diff --git a/doc/HomagGroup.Blazor3D.xml b/doc/HomagGroup.Blazor3D.xml
index 8157e65..20cc0d0 100644
--- a/doc/HomagGroup.Blazor3D.xml
+++ b/doc/HomagGroup.Blazor3D.xml
@@ -255,6 +255,11 @@
Stl format.
+
+
+ Usdz format.
+
+
These define the texture's WrapS and WrapT properties, which define horizontal and vertical texture wrapping.
@@ -1972,6 +1977,16 @@
Settings that will be applied during 3D model file importing.
Guid of the loaded item
+
+
+ Imports 3D model file to scene.
+
+ URL of the 3D model file.
+ Material that will be applied to all loaded meshes.
+ URL of the texture file.
+ UUID of the object to be loaded. Nullable. If not specified, the new Guid is genrated.
+ Guid of the loaded item
+
Imports sprite to scene.
diff --git a/src/dotnet/Blazor3D.Web/.dockerignore b/src/Blazor3D.Web/.dockerignore
similarity index 100%
rename from src/dotnet/Blazor3D.Web/.dockerignore
rename to src/Blazor3D.Web/.dockerignore
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web.sln b/src/Blazor3D.Web/Blazor3D.Web.sln
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web.sln
rename to src/Blazor3D.Web/Blazor3D.Web.sln
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Areas/Identity/Pages/_ViewStart.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Areas/Identity/Pages/_ViewStart.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Areas/Identity/Pages/_ViewStart.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Areas/Identity/Pages/_ViewStart.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Blazor3D.Web.csproj b/src/Blazor3D.Web/Blazor3D.Web/Blazor3D.Web.csproj
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Blazor3D.Web.csproj
rename to src/Blazor3D.Web/Blazor3D.Web/Blazor3D.Web.csproj
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Controllers/HomeController.cs b/src/Blazor3D.Web/Blazor3D.Web/Controllers/HomeController.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Controllers/HomeController.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Controllers/HomeController.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Controllers/ReferenceController.cs b/src/Blazor3D.Web/Blazor3D.Web/Controllers/ReferenceController.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Controllers/ReferenceController.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Controllers/ReferenceController.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Data/ApplicationDbContext.cs b/src/Blazor3D.Web/Blazor3D.Web/Data/ApplicationDbContext.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Data/ApplicationDbContext.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Data/ApplicationDbContext.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Dockerfile b/src/Blazor3D.Web/Blazor3D.Web/Dockerfile
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Dockerfile
rename to src/Blazor3D.Web/Blazor3D.Web/Dockerfile
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.Designer.cs b/src/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.Designer.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.Designer.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.Designer.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.cs b/src/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Migrations/20220708070619_Initial.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Blazor3D.Web/Blazor3D.Web/Migrations/ApplicationDbContextModelSnapshot.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Migrations/ApplicationDbContextModelSnapshot.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Migrations/ApplicationDbContextModelSnapshot.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Models/ErrorViewModel.cs b/src/Blazor3D.Web/Blazor3D.Web/Models/ErrorViewModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Models/ErrorViewModel.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Models/ErrorViewModel.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Program.cs b/src/Blazor3D.Web/Blazor3D.Web/Program.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Program.cs
rename to src/Blazor3D.Web/Blazor3D.Web/Program.cs
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Properties/launchSettings.json b/src/Blazor3D.Web/Blazor3D.Web/Properties/launchSettings.json
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Properties/launchSettings.json
rename to src/Blazor3D.Web/Blazor3D.Web/Properties/launchSettings.json
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.json b/src/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.json
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.json
rename to src/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.json
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.local.json b/src/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.local.json
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.local.json
rename to src/Blazor3D.Web/Blazor3D.Web/Properties/serviceDependencies.local.json
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Templates/Index.html b/src/Blazor3D.Web/Blazor3D.Web/Templates/Index.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Templates/Index.html
rename to src/Blazor3D.Web/Blazor3D.Web/Templates/Index.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/GettingStarted.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Home/GettingStarted.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/GettingStarted.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Home/GettingStarted.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/Index.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Home/Index.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/Index.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Home/Index.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/Privacy.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Home/Privacy.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/Privacy.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Home/Privacy.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/Tutorials.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Home/Tutorials.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Home/Tutorials.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Home/Tutorials.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/Error.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/Error.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/Error.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/Error.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml.css b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml.css
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_Layout.cshtml.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml.css b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml.css
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LayoutMain.cshtml.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LoginPartial.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LoginPartial.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LoginPartial.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_LoginPartial.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_ValidationScriptsPartial.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_ValidationScriptsPartial.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/Shared/_ValidationScriptsPartial.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/Shared/_ValidationScriptsPartial.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/_ViewImports.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/_ViewImports.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/_ViewImports.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/_ViewImports.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/_ViewStart.cshtml b/src/Blazor3D.Web/Blazor3D.Web/Views/_ViewStart.cshtml
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/Views/_ViewStart.cshtml
rename to src/Blazor3D.Web/Blazor3D.Web/Views/_ViewStart.cshtml
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/appsettings.Development.json b/src/Blazor3D.Web/Blazor3D.Web/appsettings.Development.json
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/appsettings.Development.json
rename to src/Blazor3D.Web/Blazor3D.Web/appsettings.Development.json
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/appsettings.json b/src/Blazor3D.Web/Blazor3D.Web/appsettings.json
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/appsettings.json
rename to src/Blazor3D.Web/Blazor3D.Web/appsettings.json
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db b/src/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db
rename to src/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-shm b/src/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-shm
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-shm
rename to src/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-shm
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-wal b/src/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-wal
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-wal
rename to src/Blazor3D.Web/Blazor3D.Web/blazor3dweb.db-wal
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/about.txt b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/about.txt
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/about.txt
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/about.txt
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-192x192.png b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-192x192.png
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-192x192.png
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-192x192.png
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-512x512.png b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-512x512.png
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-512x512.png
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/android-chrome-512x512.png
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/apple-touch-icon.png b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/apple-touch-icon.png
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/apple-touch-icon.png
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/apple-touch-icon.png
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/blazor3d.svg b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/blazor3d.svg
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/blazor3d.svg
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/blazor3d.svg
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/css/site.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/css/site.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/css/site.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/css/site.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-16x16.png b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-16x16.png
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-16x16.png
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-16x16.png
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-32x32.png b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-32x32.png
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-32x32.png
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon-32x32.png
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon.ico b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon.ico
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon.ico
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/favicon.ico
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/js/site.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/js/site.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/js/site.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/js/site.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/LICENSE b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/LICENSE
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/LICENSE
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/LICENSE
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/LICENSE.md b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/LICENSE.md
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/LICENSE.md
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/LICENSE.md
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/LICENSE.txt b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/LICENSE.txt
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/LICENSE.txt
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/LICENSE.txt
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.js b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.js
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.js
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.js
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.map b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.map
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.map
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/lib/jquery/dist/jquery.min.map
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.Camera.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.Camera.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.Camera.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.Camera.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.OrthographicCamera.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.OrthographicCamera.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.OrthographicCamera.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.OrthographicCamera.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.PerspectiveCamera.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.PerspectiveCamera.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.PerspectiveCamera.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Cameras.PerspectiveCamera.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Controls.OrbitControls.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Controls.OrbitControls.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Controls.OrbitControls.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Controls.OrbitControls.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.BufferGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.BufferGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.BufferGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.BufferGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.Object3D.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.Object3D.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.Object3D.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Core.Object3D.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Enums.Import3DFormats.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Enums.Import3DFormats.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Enums.Import3DFormats.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Enums.Import3DFormats.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedModuleEventHandler.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedModuleEventHandler.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedModuleEventHandler.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedModuleEventHandler.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedObjectEventHandler.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedObjectEventHandler.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedObjectEventHandler.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.LoadedObjectEventHandler.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.Object3DArgs.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.Object3DArgs.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.Object3DArgs.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.Object3DArgs.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.SelectedObjectEventHandler.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.SelectedObjectEventHandler.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.SelectedObjectEventHandler.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Events.SelectedObjectEventHandler.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.BoxGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.BoxGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.BoxGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.BoxGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CapsuleGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CapsuleGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CapsuleGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CapsuleGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CircleGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CircleGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CircleGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CircleGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.ConeGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.ConeGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.ConeGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.ConeGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CylinderGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CylinderGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CylinderGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.CylinderGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.DodecahedronGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.DodecahedronGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.DodecahedronGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.DodecahedronGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.IcosahedronGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.IcosahedronGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.IcosahedronGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.IcosahedronGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.OctahedronGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.OctahedronGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.OctahedronGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.OctahedronGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.PlaneGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.PlaneGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.PlaneGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.PlaneGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.RingGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.RingGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.RingGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.RingGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.SphereGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.SphereGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.SphereGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.SphereGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TetrahedronGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TetrahedronGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TetrahedronGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TetrahedronGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusKnotGeometry.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusKnotGeometry.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusKnotGeometry.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Geometires.TorusKnotGeometry.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.ArrowHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.ArrowHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.ArrowHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.ArrowHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.AxesHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.AxesHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.AxesHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.AxesHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.BoxHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.BoxHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.BoxHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.BoxHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.GridHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.GridHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.GridHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.GridHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PlaneHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PlaneHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PlaneHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PlaneHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PointLightHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PointLightHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PointLightHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PointLightHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PolarGridHelper.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PolarGridHelper.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PolarGridHelper.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Helpers.PolarGridHelper.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.AmbientLight.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.AmbientLight.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.AmbientLight.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.AmbientLight.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.Light.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.Light.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.Light.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.Light.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.PointLight.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.PointLight.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.PointLight.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Lights.PointLight.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.Material.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.Material.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.Material.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.Material.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.MeshStandardMaterial.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.MeshStandardMaterial.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.MeshStandardMaterial.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Materials.MeshStandardMaterial.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Euler.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Euler.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Euler.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Euler.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Plane.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Plane.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Plane.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Plane.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Vector3.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Vector3.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Vector3.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Maths.Vector3.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Group.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Group.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Group.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Group.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Mesh.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Mesh.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Mesh.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Objects.Mesh.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Scenes.Scene.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Scenes.Scene.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Scenes.Scene.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Scenes.Scene.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.AnimateRotationSettings.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.AnimateRotationSettings.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.AnimateRotationSettings.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.AnimateRotationSettings.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ImportSettings.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ImportSettings.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ImportSettings.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ImportSettings.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ViewerSettings.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ViewerSettings.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ViewerSettings.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.ViewerSettings.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.WebGLRendererSettings.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.WebGLRendererSettings.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.WebGLRendererSettings.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Settings.WebGLRendererSettings.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Viewers.Viewer.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Viewers.Viewer.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Viewers.Viewer.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Blazor3D.Viewers.Viewer.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Index.html b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Index.html
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Index.html
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/reference/Index.html
diff --git a/src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/site.webmanifest b/src/Blazor3D.Web/Blazor3D.Web/wwwroot/site.webmanifest
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Blazor3D.Web/wwwroot/site.webmanifest
rename to src/Blazor3D.Web/Blazor3D.Web/wwwroot/site.webmanifest
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Extensions/ParserExtensions.cs b/src/Blazor3D.Web/ReferenceGenerator/Extensions/ParserExtensions.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Extensions/ParserExtensions.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Extensions/ParserExtensions.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/HtmlGenerator.cs b/src/Blazor3D.Web/ReferenceGenerator/HtmlGenerator.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/HtmlGenerator.cs
rename to src/Blazor3D.Web/ReferenceGenerator/HtmlGenerator.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/BaseModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/BaseModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/BaseModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/BaseModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/ConstructorModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/ConstructorModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/ConstructorModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/ConstructorModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/ErrorViewModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/ErrorViewModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/ErrorViewModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/ErrorViewModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/EventModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/EventModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/EventModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/EventModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/FieldModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/FieldModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/FieldModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/FieldModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/MethodModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/MethodModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/MethodModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/MethodModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/Param.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/Param.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/Param.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/Param.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/PropertyModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/PropertyModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/PropertyModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/PropertyModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/ReferenceModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/ReferenceModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/ReferenceModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/ReferenceModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/TypeModel.cs b/src/Blazor3D.Web/ReferenceGenerator/Models/TypeModel.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Models/TypeModel.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Models/TypeModel.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Parser.cs b/src/Blazor3D.Web/ReferenceGenerator/Parser.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Parser.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Parser.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/ReferenceGenerator.csproj b/src/Blazor3D.Web/ReferenceGenerator/ReferenceGenerator.csproj
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/ReferenceGenerator.csproj
rename to src/Blazor3D.Web/ReferenceGenerator/ReferenceGenerator.csproj
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Settings/TemplateSettings.cs b/src/Blazor3D.Web/ReferenceGenerator/Settings/TemplateSettings.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Settings/TemplateSettings.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Settings/TemplateSettings.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Utils/BreadCrumbsFactory.cs b/src/Blazor3D.Web/ReferenceGenerator/Utils/BreadCrumbsFactory.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Utils/BreadCrumbsFactory.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Utils/BreadCrumbsFactory.cs
diff --git a/src/dotnet/Blazor3D.Web/ReferenceGenerator/Utils/PathCombiner.cs b/src/Blazor3D.Web/ReferenceGenerator/Utils/PathCombiner.cs
similarity index 100%
rename from src/dotnet/Blazor3D.Web/ReferenceGenerator/Utils/PathCombiner.cs
rename to src/Blazor3D.Web/ReferenceGenerator/Utils/PathCombiner.cs
diff --git a/src/dotnet/Blazor3D.Web/Todo.txt b/src/Blazor3D.Web/Todo.txt
similarity index 100%
rename from src/dotnet/Blazor3D.Web/Todo.txt
rename to src/Blazor3D.Web/Todo.txt
diff --git a/src/Blazor3D/Blazor3D.Tests/Blazor3D.Tests.csproj b/src/Blazor3D/Blazor3D.Tests/Blazor3D.Tests.csproj
new file mode 100644
index 0000000..1fe4fd8
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Blazor3D.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Cameras/OrthographicCameraTests.cs b/src/Blazor3D/Blazor3D.Tests/Cameras/OrthographicCameraTests.cs
new file mode 100644
index 0000000..fd1f308
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Cameras/OrthographicCameraTests.cs
@@ -0,0 +1,36 @@
+namespace Blazor3D.Tests.Cameras;
+
+[TestClass]
+public class OrthographicCameraTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var camera = new OrthographicCamera();
+ Assert.AreEqual("OrthographicCamera", camera.Type);
+ Assert.AreEqual(0.1, camera.Near);
+ Assert.AreEqual(2000, camera.Far);
+ Assert.AreEqual(-1, camera.Left);
+ Assert.AreEqual(1, camera.Right);
+ Assert.AreEqual(1, camera.Top);
+ Assert.AreEqual(-1, camera.Bottom);
+ Assert.AreEqual(1, camera.Zoom);
+ Assert.IsNotNull(camera.AnimateRotationSettings);
+ Assert.IsNotNull(camera.LookAt);
+ Assert.IsNotNull(camera.Up);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var camera = new OrthographicCamera(left: -2, right: 2, top: 2, bottom: -2, near: 0, far: 100, zoom: 0.5);
+ Assert.AreEqual("OrthographicCamera", camera.Type);
+ Assert.AreEqual(0, camera.Near);
+ Assert.AreEqual(100, camera.Far);
+ Assert.AreEqual(-2, camera.Left);
+ Assert.AreEqual(2, camera.Right);
+ Assert.AreEqual(2, camera.Top);
+ Assert.AreEqual(-2, camera.Bottom);
+ Assert.AreEqual(0.5, camera.Zoom);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Cameras/PerspectiveCameraTests.cs b/src/Blazor3D/Blazor3D.Tests/Cameras/PerspectiveCameraTests.cs
new file mode 100644
index 0000000..894b772
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Cameras/PerspectiveCameraTests.cs
@@ -0,0 +1,27 @@
+namespace Blazor3D.Tests.Cameras;
+
+[TestClass]
+public class PerspectiveCameraTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var camera = new PerspectiveCamera();
+ Assert.AreEqual("PerspectiveCamera", camera.Type);
+ Assert.AreEqual(0.1, camera.Near);
+ Assert.AreEqual(1000, camera.Far);
+ Assert.AreEqual(75, camera.Fov);
+ Assert.IsNotNull(camera.AnimateRotationSettings);
+ Assert.IsNotNull(camera.LookAt);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithPredefinedValues()
+ {
+ var camera = new PerspectiveCamera(fov: 10, near: 0.2, far: 100);
+ Assert.AreEqual("PerspectiveCamera", camera.Type);
+ Assert.AreEqual(0.2, camera.Near);
+ Assert.AreEqual(100, camera.Far);
+ Assert.AreEqual(10, camera.Fov);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/GlobalUsings.cs b/src/Blazor3D/Blazor3D.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..dddc762
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/GlobalUsings.cs
@@ -0,0 +1,5 @@
+global using Blazor3D.Cameras;
+global using Blazor3D.Helpers;
+global using Blazor3D.Maths;
+global using Blazor3D.Settings;
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/ArrowHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/ArrowHelperTests.cs
new file mode 100644
index 0000000..f6f5517
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/ArrowHelperTests.cs
@@ -0,0 +1,45 @@
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class ArrowHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var arrow = new ArrowHelper();
+ Assert.AreEqual("ArrowHelper", arrow.Type);
+ Assert.AreEqual(0, arrow.Dir.X);
+ Assert.AreEqual(0, arrow.Dir.Y);
+ Assert.AreEqual(1, arrow.Dir.Z);
+ Assert.AreEqual(0, arrow.Origin.X);
+ Assert.AreEqual(0, arrow.Origin.Y);
+ Assert.AreEqual(0, arrow.Origin.Z);
+ Assert.AreEqual(1, arrow.Length);
+ Assert.AreEqual("0xffff00", arrow.Color);
+ Assert.AreEqual(0.2, arrow.HeadLength);
+ Assert.AreEqual(0.2 * 0.2, arrow.HeadWidth);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var arrow = new ArrowHelper(
+ dir: new Vector3(3, 3, 3),
+ origin: new Vector3(3, 3, 3),
+ length: 5,
+ color: "red",
+ headLength: 2,
+ headWidth: 4);
+ Assert.AreEqual("ArrowHelper", arrow.Type);
+ Assert.AreEqual(3, arrow.Dir.X);
+ Assert.AreEqual(3, arrow.Dir.Y);
+ Assert.AreEqual(3, arrow.Dir.Z);
+ Assert.AreEqual(3, arrow.Origin.X);
+ Assert.AreEqual(3, arrow.Origin.Y);
+ Assert.AreEqual(3, arrow.Origin.Z);
+ Assert.AreEqual(5, arrow.Length);
+ Assert.AreEqual("red", arrow.Color);
+ Assert.AreEqual(2, arrow.HeadLength);
+ Assert.AreEqual(4, arrow.HeadWidth);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/AxesHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/AxesHelperTests.cs
new file mode 100644
index 0000000..9cabffa
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/AxesHelperTests.cs
@@ -0,0 +1,21 @@
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class AxesHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var helper = new AxesHelper();
+ Assert.AreEqual("AxesHelper", helper.Type);
+ Assert.AreEqual(1, helper.Size);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var helper = new AxesHelper(5);
+ Assert.AreEqual("AxesHelper", helper.Type);
+ Assert.AreEqual(5, helper.Size);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/BoxHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/BoxHelperTests.cs
new file mode 100644
index 0000000..7a9be2b
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/BoxHelperTests.cs
@@ -0,0 +1,26 @@
+using Blazor3D.Objects;
+
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class BoxHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var helper = new BoxHelper();
+ Assert.AreEqual("BoxHelper", helper.Type);
+ Assert.IsNull(helper.Object3D);
+ Assert.AreEqual("0xffff00", helper.Color);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var mesh = new Mesh();
+ var helper = new BoxHelper(mesh, "red");
+ Assert.AreEqual("BoxHelper", helper.Type);
+ Assert.IsNotNull(helper.Object3D);
+ Assert.AreEqual("red", helper.Color);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/GridHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/GridHelperTests.cs
new file mode 100644
index 0000000..4ac6c4a
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/GridHelperTests.cs
@@ -0,0 +1,27 @@
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class GridHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var grid = new GridHelper();
+ Assert.AreEqual("GridHelper", grid.Type);
+ Assert.AreEqual(10, grid.Size);
+ Assert.AreEqual(10, grid.Divisions);
+ Assert.AreEqual("0x444444", grid.ColorCenterLine);
+ Assert.AreEqual("0x888888", grid.ColorGrid);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var grid = new GridHelper(6, 6, "red", "orange");
+ Assert.AreEqual("GridHelper", grid.Type);
+ Assert.AreEqual(6, grid.Size);
+ Assert.AreEqual(6, grid.Divisions);
+ Assert.AreEqual("red", grid.ColorCenterLine);
+ Assert.AreEqual("orange", grid.ColorGrid);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/PlaneHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/PlaneHelperTests.cs
new file mode 100644
index 0000000..f1233f3
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/PlaneHelperTests.cs
@@ -0,0 +1,35 @@
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class PlaneHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var plane = new PlaneHelper();
+ Assert.AreEqual("PlaneHelper", plane.Type);
+ Assert.IsNotNull(plane.Plane);
+ Assert.IsNotNull(plane.Plane.Normal);
+ Assert.AreEqual(1, plane.Plane.Normal.X);
+ Assert.AreEqual(0, plane.Plane.Normal.Y);
+ Assert.AreEqual(0, plane.Plane.Normal.Z);
+ Assert.AreEqual(0, plane.Plane.Constant);
+ Assert.AreEqual(1, plane.Size);
+ Assert.AreEqual("0xffff00", plane.Color);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var plane = new PlaneHelper(new Plane(new Vector3(1, 1, 1), 1));
+ Assert.AreEqual("PlaneHelper", plane.Type);
+ Assert.IsNotNull(plane.Plane);
+ Assert.IsNotNull(plane.Plane.Normal);
+ Assert.AreEqual(1, plane.Plane.Normal.X);
+ Assert.AreEqual(1, plane.Plane.Normal.Y);
+ Assert.AreEqual(1, plane.Plane.Normal.Z);
+ Assert.AreEqual(1, plane.Plane.Constant);
+ Assert.AreEqual(1, plane.Size);
+ Assert.AreEqual("0xffff00", plane.Color);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/PointLightHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/PointLightHelperTests.cs
new file mode 100644
index 0000000..9a28b04
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/PointLightHelperTests.cs
@@ -0,0 +1,33 @@
+using Blazor3D.Lights;
+
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class PointLightHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var helper = new PointLightHelper();
+ Assert.AreEqual("PointLightHelper", helper.Type);
+ Assert.IsNotNull(helper.Light);
+ Assert.IsNull(helper.Color);
+ Assert.AreEqual(1, helper.SphereSize);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var light = new PointLight
+ {
+ Color = "red"
+ };
+
+ var helper = new PointLightHelper(light, 2, "blue");
+ Assert.AreEqual("PointLightHelper", helper.Type);
+ Assert.IsNotNull(helper.Light);
+ Assert.AreEqual("red", helper.Light.Color);
+ Assert.AreEqual(2, helper.SphereSize);
+ Assert.AreEqual("blue", helper.Color);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Helpers/PolarGridHelperTests.cs b/src/Blazor3D/Blazor3D.Tests/Helpers/PolarGridHelperTests.cs
new file mode 100644
index 0000000..0451a54
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Helpers/PolarGridHelperTests.cs
@@ -0,0 +1,31 @@
+namespace Blazor3D.Tests.Helpers;
+
+[TestClass]
+public class PolarGridHelperTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var grid = new PolarGridHelper();
+ Assert.AreEqual("PolarGridHelper", grid.Type);
+ Assert.AreEqual(10, grid.Radius);
+ Assert.AreEqual(16, grid.Radials);
+ Assert.AreEqual(8, grid.Circles);
+ Assert.AreEqual(64, grid.Divisions);
+ Assert.AreEqual("0x444444", grid.Color1);
+ Assert.AreEqual("0x888888", grid.Color2);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var grid = new PolarGridHelper(2, 2, 6, 32, "red", "orange");
+ Assert.AreEqual("PolarGridHelper", grid.Type);
+ Assert.AreEqual(2, grid.Radius);
+ Assert.AreEqual(2, grid.Radials);
+ Assert.AreEqual(6, grid.Circles);
+ Assert.AreEqual(32, grid.Divisions);
+ Assert.AreEqual("red", grid.Color1);
+ Assert.AreEqual("orange", grid.Color2);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D.Tests/Settings/AnimateRotationSettingsTests.cs b/src/Blazor3D/Blazor3D.Tests/Settings/AnimateRotationSettingsTests.cs
new file mode 100644
index 0000000..cc7e239
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.Tests/Settings/AnimateRotationSettingsTests.cs
@@ -0,0 +1,29 @@
+namespace Blazor3D.Tests.Settings;
+
+[TestClass]
+public class AnimateRotationSettingsTests
+{
+ [TestMethod]
+ public void DefaultConstructorShouldCreateWithPredefinedValues()
+ {
+ var settings = new AnimateRotationSettings();
+
+ Assert.AreEqual(false, settings.AnimateRotation);
+ Assert.AreEqual(0.1, settings.ThetaX);
+ Assert.AreEqual(0.1, settings.ThetaY);
+ Assert.AreEqual(0.1, settings.ThetaZ);
+ Assert.AreEqual(5, settings.Radius);
+ }
+
+ [TestMethod]
+ public void ConstructorWithParamsShouldCreateWithSpecifiedValues()
+ {
+ var settings = new AnimateRotationSettings(true, 1, 1, 1, 1);
+
+ Assert.AreEqual(true, settings.AnimateRotation);
+ Assert.AreEqual(1, settings.ThetaX);
+ Assert.AreEqual(1, settings.ThetaY);
+ Assert.AreEqual(1, settings.ThetaZ);
+ Assert.AreEqual(1, settings.Radius);
+ }
+}
\ No newline at end of file
diff --git a/src/dotnet/Blazor3D/Blazor3D.sln b/src/Blazor3D/Blazor3D.sln
similarity index 76%
rename from src/dotnet/Blazor3D/Blazor3D.sln
rename to src/Blazor3D/Blazor3D.sln
index 7d6b1fe..0075b48 100644
--- a/src/dotnet/Blazor3D/Blazor3D.sln
+++ b/src/Blazor3D/Blazor3D.sln
@@ -7,14 +7,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWebAsm", "TestWebAsm\Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestServer", "TestServer\TestServer.csproj", "{CC396385-BA20-4B3C-98AF-963160281B20}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HomagGroup.Blazor3D", "Blazor3D\HomagGroup.Blazor3D.csproj", "{F4B9477B-E078-4898-8BF2-50EBDA12D76D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor3D", "Blazor3D\Blazor3D.csproj", "{F4B9477B-E078-4898-8BF2-50EBDA12D76D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documents", "Documents", "{40998448-A3C4-455A-9447-5A89398A616F}"
ProjectSection(SolutionItems) = preProject
Todo.txt = Todo.txt
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HomagGroup.Blazor3D.Tests", "Blazor3D.Tests\HomagGroup.Blazor3D.Tests.csproj", "{121CFD4A-111F-439A-A680-7A654426A075}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor3D.Tests", "Blazor3D.Tests\Blazor3D.Tests.csproj", "{121CFD4A-111F-439A-A680-7A654426A075}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWebAsm.Client", "TestWebAsm.Client\TestWebAsm.Client.csproj", "{402D0B80-8938-4F17-89E6-76E6D3456DE1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -38,6 +40,10 @@ Global
{121CFD4A-111F-439A-A680-7A654426A075}.Debug|Any CPU.Build.0 = Debug|Any CPU
{121CFD4A-111F-439A-A680-7A654426A075}.Release|Any CPU.ActiveCfg = Release|Any CPU
{121CFD4A-111F-439A-A680-7A654426A075}.Release|Any CPU.Build.0 = Release|Any CPU
+ {402D0B80-8938-4F17-89E6-76E6D3456DE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {402D0B80-8938-4F17-89E6-76E6D3456DE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {402D0B80-8938-4F17-89E6-76E6D3456DE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {402D0B80-8938-4F17-89E6-76E6D3456DE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Blazor3D/Blazor3D.sln.DotSettings b/src/Blazor3D/Blazor3D.sln.DotSettings
new file mode 100644
index 0000000..87a100a
--- /dev/null
+++ b/src/Blazor3D/Blazor3D.sln.DotSettings
@@ -0,0 +1,3 @@
+
+ UUID
+ <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="True" Prefix="" Suffix="" Style="aaBb" /></Policy>
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Blazor3D.csproj b/src/Blazor3D/Blazor3D/Blazor3D.csproj
new file mode 100644
index 0000000..3e0809f
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Blazor3D.csproj
@@ -0,0 +1,49 @@
+
+
+
+ net6.0
+ enable
+ latest
+ enable
+ True
+ ..\..\..\..\doc\HomagGroup.Blazor3D.xml
+
+
+
+ Blazor3D
+ HOMAG-Group
+ Blazor3D, three.js, Blazor, Razor, Homag-Group, Homag, HomagGroup
+ git
+ https://github.com/HomagGroup/HomagGroup.Blazor3D-Core
+
+ This Razor class library (RCL) contains the Blazor component which allows you create 3D scenes inside your Blazor application.
+ This Blazor3D component uses three.js library to display 3D scenes on html canvas.
+ See examples of using here https://github.com/HomagGroup/HomagGroup.Blazor3D
+
+ Blazor3D
+
+
+
+ 1701;1702;1591
+
+
+
+ 1701;1702;1591
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Cameras/Camera.cs b/src/Blazor3D/Blazor3D/Cameras/Camera.cs
new file mode 100644
index 0000000..420510b
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Cameras/Camera.cs
@@ -0,0 +1,27 @@
+namespace Blazor3D.Cameras;
+
+///
+/// Abstract base class for cameras.
+/// Wrapper for three.js Camera
+///
+///
+public abstract class Camera : Object3D
+{
+ protected Camera(string type = "Camera") : base(type) { }
+
+ ///
+ /// Settings used for camera's animated rotations.
+ ///
+ public AnimateRotationSettings AnimateRotationSettings { get; set; } = new();
+
+ ///
+ /// The point camera looks at.
+ ///
+ public Vector3 LookAt { get; set; } = new();
+
+ ///
+ /// This is used by the LookAt method, for example, to determine the orientation of the result.
+ /// Default is ( 0, 1, 0 ).
+ ///
+ public Vector3 Up { get; set; } = new(0, 1, 0);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Cameras/OrthographicCamera.cs b/src/Blazor3D/Blazor3D/Cameras/OrthographicCamera.cs
new file mode 100644
index 0000000..9a8ff7f
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Cameras/OrthographicCamera.cs
@@ -0,0 +1,67 @@
+namespace Blazor3D.Cameras;
+
+///
+/// Camera that uses orthographic projection.
+/// In this projection mode, an object's size in the rendered image stays constant regardless of its distance from the camera.
+/// This can be useful for rendering 2D scenes and UI elements, amongst other things.
+///
+public sealed class OrthographicCamera : Camera
+{
+ public OrthographicCamera() : base("OrthographicCamera") { }
+
+ ///
+ /// Constructor with parameters.
+ ///
+ /// Camera frustum left plane. Default is -1.
+ /// Camera frustum right plane. Default is 1.
+ /// Camera frustum top plane. Default is 1.
+ /// Camera frustum bottom plane. Default is -1.
+ /// Camera frustum near plane distance. Default is 0.1.
+ /// Camera frustum far plane distance. Default is 1000.
+ /// Zoom factor of the camera. Default is 1.
+ public OrthographicCamera(double left = -1, double right = 1, double top = 1, double bottom = -1, double near = 0.1, double far = 2000, double zoom = 1) : this()
+ {
+ Left = left;
+ Right = right;
+ Top = top;
+ Bottom = bottom;
+ Near = near;
+ Far = far;
+ Zoom = zoom;
+ }
+
+ ///
+ /// Camera frustum left plane. Default is -1.
+ ///
+ public double Left { get; set; } = -1;
+
+ ///
+ /// Camera frustum right plane. Default is 1.
+ ///
+ public double Right { get; set; } = 1;
+
+ ///
+ /// Camera frustum top plane. Default is 1.
+ ///
+ public double Top { get; set; } = 1;
+
+ ///
+ /// Camera frustum bottom plane. Default is -1.
+ ///
+ public double Bottom { get; set; } = -1;
+
+ ///
+ /// Camera frustum near plane distance. Default is 0.1.
+ ///
+ public double Near { get; set; } = 0.1;
+
+ ///
+ /// Camera frustum far plane distance. Default is 2000.
+ ///
+ public double Far { get; set; } = 2000;
+
+ ///
+ /// Zoom factor of the camera. Default is 1.
+ ///
+ public double Zoom { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Cameras/PerspectiveCamera.cs b/src/Blazor3D/Blazor3D/Cameras/PerspectiveCamera.cs
new file mode 100644
index 0000000..2a3164c
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Cameras/PerspectiveCamera.cs
@@ -0,0 +1,41 @@
+namespace Blazor3D.Cameras;
+
+///
+/// Camera that uses perspective projection.
+/// This projection mode is designed to mimic the way the human eyes see.
+/// It is the most common projection mode used for rendering a 3D scene.
+/// Wrapper for three.js PerspectiveCamera
+///
+///
+public sealed class PerspectiveCamera : Camera
+{
+ public PerspectiveCamera() : base("PerspectiveCamera") { }
+
+ ///
+ /// Constructor with parameters.
+ ///
+ /// Camera frustum vertical field of view. Default is 75.
+ /// Camera frustum near plane distance. Default is 0.1.
+ /// Camera frustum far plane distance. Default is 1000.
+ public PerspectiveCamera(double fov, double near, double far) : this()
+ {
+ Fov = fov;
+ Near = near;
+ Far = far;
+ }
+
+ ///
+ /// Camera frustum vertical field of view. Default is 75.
+ ///
+ public double Fov { get; set; } = 75;
+
+ ///
+ /// Camera frustum near plane distance. Default is 0.1.
+ ///
+ public double Near { get; set; } = 0.1;
+
+ ///
+ /// Camera frustum far plane distance. Default is 1000.
+ ///
+ public double Far { get; set; } = 1000;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/ComponentHelpers/ChildrenHelper.cs b/src/Blazor3D/Blazor3D/ComponentHelpers/ChildrenHelper.cs
new file mode 100644
index 0000000..dc83561
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/ComponentHelpers/ChildrenHelper.cs
@@ -0,0 +1,47 @@
+namespace Blazor3D.ComponentHelpers;
+
+internal static class ChildrenHelper
+{
+ internal static void RemoveObjectByUuid(Guid uuid, List children)
+ {
+ Object3D? result = null;
+
+ foreach (var child in children)
+ {
+ if (child.Uuid == uuid)
+ {
+ result = child;
+ break;
+ }
+
+ if (child.Children.Count > 0)
+ {
+ RemoveObjectByUuid(uuid, child.Children);
+ }
+ }
+
+ if (result != null)
+ children.Remove(result);
+ }
+
+ internal static Object3D? GetObjectByUuid(Guid uuid, List children)
+ {
+ Object3D? result = null;
+
+ foreach (var child in children)
+ {
+ if (child.Uuid == uuid) return child;
+
+ if (child.Children.Count > 0)
+ {
+ result = GetObjectByUuid(uuid, child.Children);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/ComponentHelpers/SerializationHelper.cs b/src/Blazor3D/Blazor3D/ComponentHelpers/SerializationHelper.cs
new file mode 100644
index 0000000..3a56ea9
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/ComponentHelpers/SerializationHelper.cs
@@ -0,0 +1,13 @@
+namespace Blazor3D.ComponentHelpers;
+
+internal static class SerializationHelper
+{
+ internal static JsonSerializerSettings GetSerializerSettings()
+ {
+ return new JsonSerializerSettings
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Controls/OrbitControls.cs b/src/Blazor3D/Blazor3D/Controls/OrbitControls.cs
new file mode 100644
index 0000000..c5caf5d
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Controls/OrbitControls.cs
@@ -0,0 +1,42 @@
+namespace Blazor3D.Controls;
+
+///
+/// Orbit controls.
+///
+public sealed class OrbitControls
+{
+ ///
+ /// If true, then enabled. Otherwise, disabled. Default is true.
+ ///
+ public bool Enabled { get; set; } = true;
+
+ ///
+ /// Minimal distance. Default is 0.
+ ///
+ public double MinDistance { get; set; } = 0;
+
+ ///
+ /// Maximal distance to zoom. Default is 10000;
+ ///
+ public double MaxDistance { get; set; } = 10000;
+
+ ///
+ /// The point where the camera is looking at. Default is (0,0,0).
+ ///
+ public Vector3 TargetPosition { get; set; } = new();
+
+ ///
+ /// If true, then panning enabled. Otherwise, panning disabled. Default is true
+ ///
+ public bool EnablePan { get; set; } = true;
+
+ ///
+ /// If true, then damping enabled. Otherwise, damping disabled. Default is true
+ ///
+ public bool EnableDamping { get; set; } = false;
+
+ ///
+ /// Damping factor. Default is 0.05
+ ///
+ public double DampingFactor = 0.05;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Core/BufferGeometry.cs b/src/Blazor3D/Blazor3D/Core/BufferGeometry.cs
new file mode 100644
index 0000000..79fee64
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Core/BufferGeometry.cs
@@ -0,0 +1,27 @@
+namespace Blazor3D.Core;
+
+///
+/// A representation of geometry for mesh, line, or point.
+/// Includes vertex positions, face indices, normals, colors, UVs, and custom attributes within buffers,
+/// reducing the cost of passing all this data to the GPU.
+/// Wrapper for three.js BufferGeometry
+///
+public abstract class BufferGeometry
+{
+ protected BufferGeometry(string type)
+ {
+ Type = type;
+ }
+
+ ///
+ /// Optional name of the object. Default is an empty string. It has not to be unique.
+ ///
+ public string Name { get; set; } = null!;
+
+ ///
+ /// Universal unique identifier of this object instance. It's automatically assigned Guid, so it shouldn't be edited.
+ ///
+ public Guid Uuid { get; set; } = Guid.NewGuid();
+
+ public string Type { get; } = "Geometry";
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Core/Object3D.cs b/src/Blazor3D/Blazor3D/Core/Object3D.cs
new file mode 100644
index 0000000..f68e162
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Core/Object3D.cs
@@ -0,0 +1,69 @@
+namespace Blazor3D.Core;
+
+///
+/// It's a base abstract class for most objects in Blazor3D.
+/// It provides functionality for manipulating objects in 3D space.
+///Wrapper for three.js Object3D
+///
+public abstract class Object3D
+{
+ protected Object3D(string type)
+ {
+ Type = type;
+ }
+
+ ///
+ /// Represents the object's local position. Default is (0, 0, 0).
+ ///
+ public Vector3 Position { get; set; } = new();
+
+ ///
+ /// Object's local rotation, in radians.
+ ///
+ public Euler Rotation { get; set; } = new();
+
+ ///
+ /// Represents the object's local scale. Default is (1, 1, 1).
+ ///
+ public Vector3 Scale { get; set; } = new(1, 1, 1);
+
+ public string Type { get; } = "Object3D";
+
+ ///
+ /// Optional name of the object. Default is an empty string. It has not to be unique.
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// Universal unique identifier of this object instance. It's automatically assigned Guid, so it shouldn't be edited.
+ ///
+ public Guid Uuid { get; set; } = Guid.NewGuid();
+
+ ///
+ /// Collection of child objects.
+ ///
+ public List Children { get; set; } = [];
+
+ ///
+ /// Settings to create movement animations on the object
+ ///
+ public AnimateObject3DSettings AnimateObject3DSettings { get; set; }
+
+ ///
+ /// Adds a child object to the Children collection.
+ ///
+ /// Child to be added.
+ public void Add(Object3D child)
+ {
+ Children.Add(child);
+ }
+
+ ///
+ /// Adds the elements of the specified collection to the end of Children list.
+ ///
+ /// Collection of children objects.
+ public void AddRange(IEnumerable elements)
+ {
+ Children.AddRange(elements);
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Enums/ImportModels.cs b/src/Blazor3D/Blazor3D/Enums/ImportModels.cs
new file mode 100644
index 0000000..433993e
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Enums/ImportModels.cs
@@ -0,0 +1,37 @@
+namespace Blazor3D.Enums;
+
+///
+/// 3D model formats, which can be used for importing to or exporting from .
+///
+public enum Import3DFormats
+{
+ ///
+ ///Wavefront Object format.
+ ///
+ Obj,
+
+ ///
+ /// Collada format.
+ ///
+ Collada,
+
+ ///
+ /// Autodesk FBX format.
+ ///
+ Fbx,
+
+ ///
+ /// glTF format.
+ ///
+ Gltf,
+
+ ///
+ /// Stl format.
+ ///
+ Stl,
+
+ ///
+ /// Usdz format.
+ ///
+ Usdz
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Enums/Lines/LineCap.cs b/src/Blazor3D/Blazor3D/Enums/Lines/LineCap.cs
new file mode 100644
index 0000000..a6267b1
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Enums/Lines/LineCap.cs
@@ -0,0 +1,8 @@
+namespace Blazor3D.Enums.Lines;
+
+public enum LineCap
+{
+ Round,
+ Butt,
+ Square
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Enums/Lines/LineJoin.cs b/src/Blazor3D/Blazor3D/Enums/Lines/LineJoin.cs
new file mode 100644
index 0000000..79904f1
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Enums/Lines/LineJoin.cs
@@ -0,0 +1,8 @@
+namespace Blazor3D.Enums.Lines;
+
+public enum LineJoin
+{
+ Round,
+ Bevel,
+ Miter
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Enums/WrappingType.cs b/src/Blazor3D/Blazor3D/Enums/WrappingType.cs
new file mode 100644
index 0000000..fb265b1
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Enums/WrappingType.cs
@@ -0,0 +1,22 @@
+namespace Blazor3D.Enums;
+
+///
+/// These define the texture's WrapS and WrapT properties, which define horizontal and vertical texture wrapping.
+///
+public enum WrappingType
+{
+ ///
+ /// The texture will simply repeat to infinity
+ ///
+ RepeatWrapping = 1000,
+
+ ///
+ /// The last pixel of the texture stretches to the edge of the mesh.
+ ///
+ ClampToEdgeWrapping = 1001,
+
+ ///
+ /// The texture will repeats to infinity, mirroring on each repeat.
+ ///
+ MirroredRepeatWrapping = 1002
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Events/LoadedModuleEventHandler.cs b/src/Blazor3D/Blazor3D/Events/LoadedModuleEventHandler.cs
new file mode 100644
index 0000000..bb6ed80
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Events/LoadedModuleEventHandler.cs
@@ -0,0 +1,7 @@
+namespace Blazor3D.Events;
+
+///
+/// Delegate that handles JsModuleLoaded event.
+///
+/// Task
+public delegate Task LoadedModuleEventHandler();
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Events/LoadedObjectEventHandler.cs b/src/Blazor3D/Blazor3D/Events/LoadedObjectEventHandler.cs
new file mode 100644
index 0000000..7c86f03
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Events/LoadedObjectEventHandler.cs
@@ -0,0 +1,7 @@
+namespace Blazor3D.Events;
+
+///
+/// Delegate that handles ObjectLoaded event.
+///
+/// arguments for ObjectLoaded event handler.
+public delegate Task LoadedObjectEventHandler(Object3DArgs e);
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Events/Object3DArgs.cs b/src/Blazor3D/Blazor3D/Events/Object3DArgs.cs
new file mode 100644
index 0000000..d732f9d
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Events/Object3DArgs.cs
@@ -0,0 +1,19 @@
+namespace Blazor3D.Events;
+
+internal class Object3DStaticArgs
+{
+ public string ContainerId { get; set; } = null!;
+
+ public Guid UUID { get; set; }
+}
+
+///
+/// Arguments for ObjectSelected and ObjectLoaded event handlers.
+///
+public class Object3DArgs
+{
+ ///
+ /// Selected or Loaded object unique identifier.
+ ///
+ public Guid UUID { get; set; }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Events/SelectedObjectEventHandler.cs b/src/Blazor3D/Blazor3D/Events/SelectedObjectEventHandler.cs
new file mode 100644
index 0000000..4c0f90a
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Events/SelectedObjectEventHandler.cs
@@ -0,0 +1,7 @@
+namespace Blazor3D.Events;
+
+///
+/// Delegate that handles ObjectSelected event.
+///
+/// arguments for ObjectSelected event handler.
+public delegate void SelectedObjectEventHandler(Object3DArgs e);
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Extensions/ServiceCollectionExtension.cs b/src/Blazor3D/Blazor3D/Extensions/ServiceCollectionExtension.cs
new file mode 100644
index 0000000..08ab39f
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Extensions/ServiceCollectionExtension.cs
@@ -0,0 +1,25 @@
+namespace Blazor3D.Extensions;
+
+public static class ServiceCollectionExtension
+{
+ public static IServiceCollection AddBlazor3DFileTypes(this IServiceCollection services)
+ {
+ var provider = new FileExtensionContentTypeProvider();
+
+ provider.AddMapping(".fbx", "application/octet-stream");
+ provider.AddMapping(".gltf", "model/gltf+json");
+ provider.AddMapping(".glb", "model/gltf-binary");
+ provider.AddMapping(".dae", "model/vnd.collada+xml");
+ provider.AddMapping(".stl", "model/stl");
+ provider.AddMapping(".usd", "model/vnd.usd+zip");
+ provider.AddMapping(".usda", "model/vnd.usdz+zip");
+ provider.AddMapping(".usdc", "model/vnd.usdz+zip");
+ provider.AddMapping(".usdz", "model/vnd.usdz+zip");
+
+ services.Configure(s => s.ContentTypeProvider = provider);
+
+ return services;
+ }
+
+ private static void AddMapping(this FileExtensionContentTypeProvider provider, string fileExtension, string mimeType) => provider.Mappings.TryAdd(fileExtension, mimeType);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Extras/Core/Shape.cs b/src/Blazor3D/Blazor3D/Extras/Core/Shape.cs
new file mode 100644
index 0000000..c28fb2f
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Extras/Core/Shape.cs
@@ -0,0 +1,68 @@
+namespace Blazor3D.Extras.Core;
+
+///
+/// Defines an arbitrary 2d shape plane using paths with optional holes).
+/// It can be used with , , to get points, or to get triangulated faces.
+///
+public class Shape
+{
+ ///
+ /// Universal unique identifier
+ ///
+ public Guid Uuid { get; set; } = Guid.NewGuid();
+
+ ///
+ /// Array of representing the shape verticies.
+ ///
+ public List Points { get; set; } = [];
+
+ ///
+ /// Moves the current point to the specified point. Can be used for the first element of the Points collection.
+ ///
+ /// point.
+ /// MoveTo() can be used only to define first shape point
+ public void MoveTo(Vector2 point)
+ {
+ if (Points.Count > 0)
+ {
+ throw new OverflowException("MoveTo() can be used only to define first shape point");
+ }
+
+ Points.Add(point);
+ }
+
+ ///
+ /// Moves the current point to the specified point.
+ ///
+ /// X coordinate of the specified point.
+ /// Y coordinate of the specified point.
+ public void MoveTo(double x, double y)
+ {
+ MoveTo(new Vector2(x, y));
+ }
+
+ ///
+ /// Adds the vertice to the shape path.
+ ///
+ /// point.
+ /// LineTo() cannot be used to define first shape point
+ public void LineTo(Vector2 point)
+ {
+ if (Points.Count == 0)
+ {
+ throw new OverflowException("LineTo() cannot be used to define first shape point");
+ }
+
+ Points.Add(point);
+ }
+
+ ///
+ /// Adds the vertice to the shape path.
+ ///
+ /// X coordinate of the specified vertice.
+ /// Y coordinate of the specified vertice.
+ public void LineTo(double x, double y)
+ {
+ LineTo(new Vector2(x, y));
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/BoxGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/BoxGeometry.cs
new file mode 100644
index 0000000..663c184
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/BoxGeometry.cs
@@ -0,0 +1,69 @@
+namespace Blazor3D.Geometires;
+
+///
+/// Class for rectangular cuboid with a given 'width', 'height', and 'depth'.
+/// This class inherits from
+/// Wrapper for three.js BoxGeometry
+///
+///
+public sealed class BoxGeometry : BufferGeometry
+{
+ public BoxGeometry() : base("BoxGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// The length of the edges parallel to the X axis. Default is 1.
+ /// The length of the edges parallel to the Y axis. Default is 1.
+ /// The length of the edges parallel to the Z axis. Default is 1.
+ /// Number of segmented rectangular faces along the width of the sides. Default is 1.
+ /// Number of segmented rectangular faces along the height of the sides. Default is 1.
+ /// Number of segmented rectangular faces along the depth of the sides. Default is 1.
+ public BoxGeometry(
+ double width = 1,
+ double height = 1,
+ double depth = 1,
+ int widthSegments = 1,
+ int heightSegments = 1,
+ int depthSegments = 1) : this()
+ {
+ Width = width;
+ Height = height;
+ Depth = depth;
+ WidthSegments = widthSegments;
+ HeightSegments = heightSegments;
+ DepthSegments = depthSegments;
+ }
+
+ ///
+ /// The length of the edges parallel to the X axis. Default is 1.
+ ///
+ public double Width { get; set; } = 1;
+
+ ///
+ /// The length of the edges parallel to the Y axis. Default is 1.
+ ///
+ public double Height { get; set; } = 1;
+
+ ///
+ /// The length of the edges parallel to the Z axis. Default is 1.
+ ///
+ public double Depth { get; set; } = 1;
+
+ ///
+ /// Number of segmented rectangular faces along the width of the sides. Default is 1.
+ ///
+ public int WidthSegments { get; set; } = 1;
+
+ ///
+ /// Number of segmented rectangular faces along the height of the sides. Default is 1.
+ ///
+ public int HeightSegments { get; set; } = 1;
+
+ ///
+ /// Number of segmented rectangular faces along the depth of the sides. Default is 1.
+ ///
+ public int DepthSegments { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/CapsuleGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/CapsuleGeometry.cs
new file mode 100644
index 0000000..3569623
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/CapsuleGeometry.cs
@@ -0,0 +1,47 @@
+namespace Blazor3D.Geometires;
+
+///
+/// Class for a capsule with given radus and height. It is constructed using a lathe.
+/// Wrapper for three.js CapsuleGeometry
+///
+public sealed class CapsuleGeometry : BufferGeometry
+{
+ public CapsuleGeometry() : base("CapsuleGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the capsule. Default is 1.
+ /// Length of the middle section. Default is 1.
+ /// Number of curve segments used to build the caps. Default is 4.
+ /// Number of segmented faces around the circumference of the capsule. Default is 8.
+ public CapsuleGeometry(double radius = 1, double length = 1, int capSegments = 4, int radialSegments = 8) : this()
+ {
+ Radius = radius;
+ Length = length;
+ CapSegments = capSegments;
+ RadialSegments = radialSegments;
+ }
+
+ ///
+ /// Radius of the capsule. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Length of the middle section. Default is 1.
+ ///
+ public double Length { get; set; } = 1;
+
+ ///
+ /// Number of curve segments used to build the caps. Default is 4.
+ ///
+ public int CapSegments { get; set; } = 4;
+
+ ///
+ /// Number of segmented faces around the circumference of the capsule. Default is 8.
+ ///
+ public int RadialSegments { get; set; } = 8;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/CircleGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/CircleGeometry.cs
new file mode 100644
index 0000000..5defc7d
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/CircleGeometry.cs
@@ -0,0 +1,53 @@
+namespace Blazor3D.Geometires;
+
+///
+/// Class for a simple shape of Euclidean geometry.
+/// It is constructed from a number of triangular segments that are oriented around a central point and extend as far out as a given radius.
+/// It is built counter-clockwise from a start angle and a given central angle.
+/// It can also be used to create regular polygons, where the number of segments determines the number of sides.
+/// This class inherits from
+/// Wrapper for three.js CircleGeometry
+///
+///
+public sealed class CircleGeometry : BufferGeometry
+{
+ public CircleGeometry() : base("CircleGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the circle. Default is 1.
+ /// Number of segments (triangles). Minimum = 3, default = 8.
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ public CircleGeometry(double radius = 1, int segments = 8, double thetaStart = 0,
+ double thetaLength = (double)(2 * Math.PI)) : this()
+ {
+ Radius = radius;
+ Segments = segments;
+ ThetaStart = thetaStart;
+ ThetaLength = thetaLength;
+ }
+
+ ///
+ /// Radius of the circle. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Number of segments (triangles). Minimum = 3, default = 8.
+ ///
+ public int Segments { get; set; } = 8;
+
+ ///
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ ///
+ public double ThetaStart { get; set; } = 0;
+
+ ///
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ ///
+ public double ThetaLength { get; set; } = (double)(2 * Math.PI);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/ConeGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/ConeGeometry.cs
new file mode 100644
index 0000000..c81fe30
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/ConeGeometry.cs
@@ -0,0 +1,75 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating cone geometries.
+/// Wrapper for three.js ConeGeometry
+///
+public sealed class ConeGeometry : BufferGeometry
+{
+ public ConeGeometry() : base("ConeGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the cone base. Defaults to 1.
+ /// Height of the cone. Default is 1.
+ /// Number of segmented faces around the circumference of the cone. Default is 8.
+ /// umber of rows of faces along the height of the cone. Default is 1.
+ /// A Boolean indicating whether the base of the cone is open or capped. Default is false, meaning capped.
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ /// he central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ public ConeGeometry(
+ double radius = 1,
+ double height = 1,
+ int radialSegments = 8,
+ int heightSegments = 1,
+ bool openEnded = false,
+ double thetaStart = 0,
+ double thetaLength = (double)(2 * Math.PI)) : this()
+ {
+ Radius = radius;
+ Height = height;
+ RadialSegments = radialSegments;
+ HeightSegments = heightSegments;
+ OpenEnded = openEnded;
+ ThetaStart = thetaStart;
+ ThetaLength = thetaLength;
+ }
+
+ ///
+ /// Radius of the cone base. Defaults to 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Height of the cone. Default is 1.
+ ///
+ public double Height { get; set; } = 1;
+
+ ///
+ /// Number of segmented faces around the circumference of the cone. Default is 8.
+ ///
+ public int RadialSegments { get; set; } = 8;
+
+ ///
+ /// Number of rows of faces along the height of the cone. Default is 1.
+ ///
+ public int HeightSegments { get; set; } = 1;
+
+ ///
+ /// A Boolean indicating whether the base of the cone is open or capped. Default is false, meaning capped.
+ ///
+ public bool OpenEnded { get; set; } = false;
+
+ ///
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ ///
+ public double ThetaStart { get; set; } = 0;
+
+ ///
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ ///
+ public double ThetaLength { get; set; } = (double)(2 * Math.PI);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/Curves/SplineCurveGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/Curves/SplineCurveGeometry.cs
new file mode 100644
index 0000000..002178f
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/Curves/SplineCurveGeometry.cs
@@ -0,0 +1,21 @@
+namespace Blazor3D.Geometires.Curves;
+
+public class SplineCurveGeometry : BufferGeometry
+{
+ public SplineCurveGeometry() : base("SplineCurveGeometry")
+ {
+ }
+
+ public List Points { get; set; } = [];
+
+ ///
+ /// This value determines the amount of divisions when calculating the cumulative segment lengths of a curve via .getLengths.
+ /// To ensure precision when using methods like .getSpacedPoints, it is recommended to increase .arcLengthDivisions if the curve is very large. Default is 200.
+ ///
+ public int ArcLengthDivisions { get; set; } = 200;
+
+ ///
+ /// number of pieces to divide the curve into. Default is 5.
+ ///
+ public int Divisions { get; set; } = 5;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/CylinderGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/CylinderGeometry.cs
new file mode 100644
index 0000000..a811579
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/CylinderGeometry.cs
@@ -0,0 +1,83 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating cylinder geometries.
+/// Wrapper for three.js CylinderGeometry
+///
+public sealed class CylinderGeometry : BufferGeometry
+{
+ public CylinderGeometry() : base("CylinderGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the cylinder at the top. Default is 1.
+ /// Radius of the cylinder at the bottom. Default is 1.
+ /// Height of the cylinder. Default is 1.
+ /// Number of segmented faces around the circumference of the cylinder. Default is 8.
+ /// Number of rows of faces along the height of the cylinder. Default is 1.
+ /// A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped.
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ public CylinderGeometry(double radiusTop = 1,
+ double radiusBottom = 1,
+ double height = 1,
+ int radialSegments = 8,
+ int heightSegments = 1,
+ bool openEnded = false,
+ double thetaStart = 0,
+ double thetaLength = (double)(2 * Math.PI)) : this()
+ {
+ RadiusTop = radiusTop;
+ RadiusBottom = radiusBottom;
+ Height = height;
+ RadialSegments = radialSegments;
+ HeightSegments = heightSegments;
+ OpenEnded = openEnded;
+ ThetaStart = thetaStart;
+ ThetaLength = thetaLength;
+ }
+
+
+ ///
+ /// Radius of the cylinder at the top. Default is 1.
+ ///
+ public double RadiusTop { get; set; } = 1;
+
+ ///
+ /// Radius of the cylinder at the bottom. Default is 1.
+ ///
+ public double RadiusBottom { get; set; } = 1;
+
+ ///
+ /// Height of the cylinder. Default is 1.
+ ///
+ public double Height { get; set; } = 1;
+
+ ///
+ /// Number of segmented faces around the circumference of the cylinder. Default is 8.
+ ///
+ public int RadialSegments { get; set; } = 8;
+
+ ///
+ /// Number of rows of faces along the height of the cylinder. Default is 1.
+ ///
+ public int HeightSegments { get; set; } = 1;
+
+ ///
+ /// A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped.
+ ///
+ public bool OpenEnded { get; set; } = false;
+
+ ///
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ ///
+ public double ThetaStart { get; set; } = 0;
+
+ ///
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ ///
+ public double ThetaLength { get; set; } = (double)(2 * Math.PI);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/DodecahedronGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/DodecahedronGeometry.cs
new file mode 100644
index 0000000..22592ca
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/DodecahedronGeometry.cs
@@ -0,0 +1,33 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating a dodecahedron geometries.
+/// Wrapper for three.js DodecahedronGeometry
+///
+public class DodecahedronGeometry : BufferGeometry
+{
+ public DodecahedronGeometry() : base("DodecahedronGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parametes
+ ///
+ /// Radius of the dodecahedron. Default is 1.
+ /// Default is 0. Setting this to a value greater than 0 adds vertices making it no longer a dodecahedron.
+ public DodecahedronGeometry(double radius = 1, int detail = 0) : this()
+ {
+ Radius = radius;
+ Detail = detail;
+ }
+
+ ///
+ /// Radius of the dodecahedron. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Default is 0. Setting this to a value greater than 0 adds vertices making it no longer a dodecahedron.
+ ///
+ public int Detail { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/ExtrudeGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/ExtrudeGeometry.cs
new file mode 100644
index 0000000..3a5f8f8
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/ExtrudeGeometry.cs
@@ -0,0 +1,34 @@
+using Blazor3D.Extras.Core;
+
+namespace Blazor3D.Geometires;
+
+///
+/// Creates extruded geometry from a path shape.
+///
+public class ExtrudeGeometry : BufferGeometry
+{
+ public ExtrudeGeometry() : base("ExtrudeGeometry")
+ {
+ }
+
+ ///
+ /// Construcor with parameters.
+ ///
+ /// polygonal shape.
+ /// options used for extrusion.
+ public ExtrudeGeometry(Shape shape, ExtrudeGeometryOptions options) : this()
+ {
+ Shape = shape;
+ ExtrudeOptions = options;
+ }
+
+ ///
+ /// polygonal shape.
+ ///
+ public Shape Shape { get; set; } = new();
+
+ ///
+ /// options used for extrusion.
+ ///
+ public ExtrudeGeometryOptions ExtrudeOptions { get; set; } = new();
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/ExtrudeGeometryOptions.cs b/src/Blazor3D/Blazor3D/Geometires/ExtrudeGeometryOptions.cs
new file mode 100644
index 0000000..6969dec
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/ExtrudeGeometryOptions.cs
@@ -0,0 +1,17 @@
+namespace Blazor3D.Geometires;
+
+///
+/// Options used for extrusion.
+///
+public class ExtrudeGeometryOptions
+{
+ ///
+ /// Extrusion depth. Default is 1.
+ ///
+ public double Depth { get; set; } = 1;
+
+ ///
+ /// Apply beveling to the shape. Default is true.
+ ///
+ public bool BevelEnabled { get; set; } = true;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/IcosahedronGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/IcosahedronGeometry.cs
new file mode 100644
index 0000000..9ee5436
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/IcosahedronGeometry.cs
@@ -0,0 +1,33 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating an icosahedron geometry.
+/// Wrapper for three.js IcosahedronGeometry
+///
+public class IcosahedronGeometry : BufferGeometry
+{
+ public IcosahedronGeometry() : base("IcosahedronGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the icosahedron. Default is 1.
+ /// Default is 0. Setting this to a value greater than 0 adds more vertices making it no longer an icosahedron. When detail is greater than 1, it's closer to a sphere.
+ public IcosahedronGeometry(double radius = 1, int detail = 0) : this()
+ {
+ Radius = radius;
+ Detail = detail;
+ }
+
+ ///
+ /// Radius of the icosahedron. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Default is 0. Setting this to a value greater than 0 adds more vertices making it no longer an icosahedron. When detail is greater than 1, it's closer to a sphere.
+ ///
+ public int Detail { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/Lines/LineGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/Lines/LineGeometry.cs
new file mode 100644
index 0000000..76bd531
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/Lines/LineGeometry.cs
@@ -0,0 +1,10 @@
+namespace Blazor3D.Geometires.Lines;
+
+public class LineGeometry : BufferGeometry
+{
+ public LineGeometry() : base("LineGeometry")
+ {
+ }
+
+ public List Points { get; set; } = [];
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/OctahedronGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/OctahedronGeometry.cs
new file mode 100644
index 0000000..1041f03
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/OctahedronGeometry.cs
@@ -0,0 +1,33 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating an octahedron geometry.
+/// Wrapper for three.js OctahedronGeometry
+///
+public sealed class OctahedronGeometry : BufferGeometry
+{
+ public OctahedronGeometry() : base("OctahedronGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the octahedron. Default is 1.
+ /// Default is 0. Setting this to a value greater than 0 adds more vertices making it no longer an octahedron.
+ public OctahedronGeometry(double radius = 1, int detail = 0) : this()
+ {
+ Radius = radius;
+ Detail = detail;
+ }
+
+ ///
+ /// Radius of the octahedron. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Default is 0. Setting this to a value greater than 0 adds more vertices making it no longer an octahedron.
+ ///
+ public int Detail { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/PlaneGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/PlaneGeometry.cs
new file mode 100644
index 0000000..6ada8c2
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/PlaneGeometry.cs
@@ -0,0 +1,47 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating plane geometries.
+/// Wrapper for three.js PlaneGeometry
+///
+public sealed class PlaneGeometry : BufferGeometry
+{
+ public PlaneGeometry() : base("PlaneGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// The length of the edges parallel to the X axis. Default is 1.
+ /// The length of the edges parallel to the Y axis. Default is 1.
+ /// Number of segmented rectangular faces along the width of the sides. Default is 1.
+ /// Number of segmented rectangular faces along the height of the sides. Default is 1.
+ public PlaneGeometry(double width = 1, double height = 1, int widthSegments = 1, int heightSegments = 1) : this()
+ {
+ Width = width;
+ Height = height;
+ WidthSegments = widthSegments;
+ HeightSegments = heightSegments;
+ }
+
+ ///
+ /// The length of the edges parallel to the X axis. Default is 1.
+ ///
+ public double Width { get; set; } = 1;
+
+ ///
+ /// The length of the edges parallel to the Y axis. Default is 1.
+ ///
+ public double Height { get; set; } = 1;
+
+ ///
+ /// Number of segmented rectangular faces along the width of the sides. Default is 1.
+ ///
+ public int WidthSegments { get; set; } = 1;
+
+ ///
+ /// Number of segmented rectangular faces along the height of the sides. Default is 1.
+ ///
+ public int HeightSegments { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/RingGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/RingGeometry.cs
new file mode 100644
index 0000000..f8fc5a6
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/RingGeometry.cs
@@ -0,0 +1,68 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating a two-dimensional ring geometry.
+/// Wrapper for three.js RingGeometry
+///
+public sealed class RingGeometry : BufferGeometry
+{
+ public RingGeometry() : base("RingGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Inner radius of the ring. Default is 0.5.
+ /// Outer radius of the ring. Default is 1.
+ /// Number of segments. A higher number means the ring will be more round. Minimum is 3. Default is 8.
+ /// Number of rows of faces from inner to outer radii. Minimum is 1. Default is 1.
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ public RingGeometry(
+ double innerRadius = 0.5f,
+ double outerRadius = 1,
+ int thetaSegments = 8,
+ int phiSegments = 1,
+ double thetaStart = 0,
+ double thetaLength = (double)(2 * Math.PI)) : this()
+ {
+ InnerRadius = innerRadius;
+ OuterRadius = outerRadius;
+ ThetaSegments = thetaSegments;
+ PhiSegments = phiSegments;
+ ThetaStart = thetaStart;
+ ThetaLength = thetaLength;
+ }
+
+
+ ///
+ /// Inner radius of the ring. Default is 0.5.
+ ///
+ public double InnerRadius { get; set; } = 0.5f;
+
+ ///
+ /// Outer radius of the ring. Default is 1.
+ ///
+ public double OuterRadius { get; set; } = 1;
+
+ ///
+ /// Number of segments. A higher number means the ring will be more round. Minimum is 3. Default is 8.
+ ///
+ public int ThetaSegments { get; set; } = 8;
+
+ ///
+ /// Number of rows of faces from inner to outer radii. Minimum is 1. Default is 1.
+ ///
+ public int PhiSegments { get; set; } = 1;
+
+ ///
+ /// Start angle for first segment. Default is 0 (three o'clock position).
+ ///
+ public double ThetaStart { get; set; } = 0;
+
+ ///
+ /// The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+ ///
+ public double ThetaLength { get; set; } = (double)(2 * Math.PI);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/ShapeGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/ShapeGeometry.cs
new file mode 100644
index 0000000..41445bd
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/ShapeGeometry.cs
@@ -0,0 +1,27 @@
+using Blazor3D.Extras.Core;
+
+namespace Blazor3D.Geometires;
+
+///
+/// Creates an one-sided polygonal geometry from one or more path shapes.
+///
+public class ShapeGeometry : BufferGeometry
+{
+ public ShapeGeometry() : base("ShapeGeometry")
+ {
+ }
+
+ ///
+ /// onstructor with parameters
+ ///
+ /// polygonal shape.
+ public ShapeGeometry(Shape shape) : this()
+ {
+ Shape = shape;
+ }
+
+ ///
+ /// polygonal shape.
+ ///
+ public Shape Shape { get; set; } = new();
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/SphereGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/SphereGeometry.cs
new file mode 100644
index 0000000..c78534d
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/SphereGeometry.cs
@@ -0,0 +1,75 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating sphere geometries.
+/// Wrapper for three.js SphereGeometry
+///
+public sealed class SphereGeometry : BufferGeometry
+{
+ public SphereGeometry() : base("SphereGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the sphere. Default is 1.
+ /// Number of horizontal segments. Minimum value is 3, and the default is 32.
+ /// Number of vertical segments. Minimum value is 2, and the default is 16.
+ /// Specifies horizontal starting angle. Default is 0.
+ /// Specifies horizontal sweep angle size. Default is Math.PI * 2.
+ /// Specifies vertical starting angle. Default is 0.
+ /// Specifies vertical sweep angle size. Default is Math.PI * 2.
+ public SphereGeometry(
+ double radius = 1,
+ int widthSegments = 32,
+ int heightSegments = 16,
+ double phiStart = 0,
+ double phiLength = (double)(2 * Math.PI),
+ double thetaStart = 0,
+ double thetaLength = (double)(2 * Math.PI)) : this()
+ {
+ Radius = radius;
+ WidthSegments = widthSegments;
+ HeightSegments = heightSegments;
+ PhiStart = phiStart;
+ PhiLength = phiLength;
+ ThetaStart = thetaStart;
+ ThetaLength = thetaLength;
+ }
+
+ ///
+ /// Radius of the sphere. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Number of horizontal segments. Minimum value is 3, and the default is 32.
+ ///
+ public int WidthSegments { get; set; } = 32;
+
+ ///
+ /// Number of vertical segments. Minimum value is 2, and the default is 16.
+ ///
+ public int HeightSegments { get; set; } = 16;
+
+ ///
+ /// Specifies horizontal starting angle. Default is 0.
+ ///
+ public double PhiStart { get; set; } = 0;
+
+ ///
+ /// Specifies horizontal sweep angle size. Default is Math.PI * 2.
+ ///
+ public double PhiLength { get; set; } = (double)(2 * Math.PI);
+
+ ///
+ /// Specifies vertical starting angle. Default is 0.
+ ///
+ public double ThetaStart { get; set; } = 0;
+
+ ///
+ /// Specifies vertical sweep angle size. Default is Math.PI * 2.
+ ///
+ public double ThetaLength { get; set; } = (double)(2 * Math.PI);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/TetrahedronGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/TetrahedronGeometry.cs
new file mode 100644
index 0000000..e856f2e
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/TetrahedronGeometry.cs
@@ -0,0 +1,33 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating a tetrahedron geometries.
+/// Wrapper for three.js TetrahedronGeometry
+///
+public sealed class TetrahedronGeometry : BufferGeometry
+{
+ public TetrahedronGeometry() : base("TetrahedronGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the tetrahedron. Default is 1.
+ /// Default is 0. Setting this to a value greater than 0 adds more vertices making it no longer an tetrahedron.
+ public TetrahedronGeometry(double radius = 1, int detail = 0) : this()
+ {
+ Radius = radius;
+ Detail = detail;
+ }
+
+ ///
+ /// Radius of the tetrahedron. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Default is 0. Setting this to a value greater than 0 adds more vertices making it no longer an tetrahedron.
+ ///
+ public int Detail { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/Text/TextExtrudeGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/Text/TextExtrudeGeometry.cs
new file mode 100644
index 0000000..f1dee61
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/Text/TextExtrudeGeometry.cs
@@ -0,0 +1,46 @@
+namespace Blazor3D.Geometires.Text;
+
+///
+/// Represents geometry to build extruded text
+///
+public class TextExtrudeGeometry : TextShapeGeometry
+{
+ public TextExtrudeGeometry() : base("TextExtrudeGeometry")
+ {
+ }
+
+ ///
+ /// Thickness to extrude text. Default is 50.
+ ///
+ public double Height { get; set; } = 50;
+
+ ///
+ /// Number of points on the curves. Default is 12.
+ ///
+ public int CurveSegments { get; set; } = 12;
+
+ ///
+ /// Turn on bevel. Default is False.
+ ///
+ public bool BevelEnabled { get; set; } = false;
+
+ ///
+ /// How deep into text bevel goes. Default is 10.
+ ///
+ public double BevelThickness { get; set; } = 10;
+
+ ///
+ /// How far from text outline is bevel. Default is 8.
+ ///
+ public double BevelSize { get; set; } = 8;
+
+ ///
+ /// How far from text outline bevel starts. Default is 0.
+ ///
+ public double BevelOffset { get; set; } = 0;
+
+ ///
+ /// Number of bevel segments
+ ///
+ public int BevelSegments { get; set; } = 3;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/Text/TextShapeGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/Text/TextShapeGeometry.cs
new file mode 100644
index 0000000..1def5a9
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/Text/TextShapeGeometry.cs
@@ -0,0 +1,30 @@
+namespace Blazor3D.Geometires.Text;
+
+///
+/// Represents geometry to build shape text
+///
+public class TextShapeGeometry : BufferGeometry
+{
+ public TextShapeGeometry() : base("TextShapeGeometry")
+ {
+ }
+
+ protected TextShapeGeometry(string type) : base(type)
+ {
+ }
+
+ ///
+ /// The text that needs to be shown
+ ///
+ public string Text { get; set; } = "Hello, Blazor3D!";
+
+ ///
+ /// The path or URL to the file. This can also be a Data URI
+ ///
+ public string FontURL { get; set; } = string.Empty;
+
+ ///
+ /// Size of the text. Default is 100.
+ ///
+ public double Size { get; set; } = 100;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/Text/TextStrokeGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/Text/TextStrokeGeometry.cs
new file mode 100644
index 0000000..6a17d9c
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/Text/TextStrokeGeometry.cs
@@ -0,0 +1,19 @@
+namespace Blazor3D.Geometires.Text;
+
+///
+/// Represents geometry to build stroke text
+///
+public class TextStrokeGeometry : TextShapeGeometry
+{
+ ///
+ /// Constructor
+ ///
+ public TextStrokeGeometry() : base("TextStrokeGeometry")
+ {
+ }
+
+ ///
+ /// Stroke width
+ ///
+ public double StrokeWidth { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/TorusGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/TorusGeometry.cs
new file mode 100644
index 0000000..9d04961
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/TorusGeometry.cs
@@ -0,0 +1,55 @@
+namespace Blazor3D.Geometires;
+
+///
+/// A class for generating torus geometries.
+/// Wrapper for three.js TorusGeometry
+///
+public sealed class TorusGeometry : BufferGeometry
+{
+ public TorusGeometry() : base("TorusGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the torus, from the center of the torus to the center of the tube. Default is 1.
+ /// Radius of the tube. Default is 0.4.
+ /// Number of radial segments. Default is 8.
+ /// Number of tubular segments. Default is 6.
+ /// Central angle. Default is Math.PI * 2.
+ public TorusGeometry(double radius = 1, double tube = 0.4f, int radialSegments = 8, int tubularSegments = 6,
+ double arc = (double)(2 * Math.PI)) : this()
+ {
+ Radius = radius;
+ Tube = tube;
+ RadialSegments = radialSegments;
+ TubularSegments = tubularSegments;
+ Arc = arc;
+ }
+
+ ///
+ /// Radius of the torus, from the center of the torus to the center of the tube. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Radius of the tube. Default is 0.4.
+ ///
+ public double Tube { get; set; } = 0.4f;
+
+ ///
+ /// Number of radial segments. Default is 8.
+ ///
+ public int RadialSegments { get; set; } = 8;
+
+ ///
+ /// Number of tubular segments. Default is 6.
+ ///
+ public int TubularSegments { get; set; } = 6;
+
+ ///
+ /// Central angle. Default is Math.PI * 2.
+ ///
+ public double Arc { get; set; } = (double)(2 * Math.PI);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Geometires/TorusKnotGeometry.cs b/src/Blazor3D/Blazor3D/Geometires/TorusKnotGeometry.cs
new file mode 100644
index 0000000..0317448
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Geometires/TorusKnotGeometry.cs
@@ -0,0 +1,63 @@
+namespace Blazor3D.Geometires;
+
+///
+/// Class for torus knot, the particular shape of which is defined by a pair of coprime integers, p and q. If p and q are not coprime, the result will be a torus link.
+/// Wrapper for three.js TorusKnotGeometry
+///
+public sealed class TorusKnotGeometry : BufferGeometry
+{
+ public TorusKnotGeometry() : base("TorusKnotGeometry")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Radius of the torus, from the center of the torus to the center of the tube. Default is 1.
+ /// Radius of the tube. Default is 0.4.
+ /// Number of radial segments. Default is 8.
+ /// Number of tubular segments. Default is 64.
+ /// This value determines, how many times the geometry winds around its axis of rotational symmetry. Default is 2.
+ /// This value determines, how many times the geometry winds around a circle in the interior of the torus. Default is 3.
+ public TorusKnotGeometry(double radius = 1, double tube = 0.4f, int radialSegments = 8, int tubularSegments = 64,
+ int p = 2, int q = 3) : this()
+ {
+ Radius = radius;
+ Tube = tube;
+ RadialSegments = radialSegments;
+ TubularSegments = tubularSegments;
+ P = p;
+ Q = q;
+ }
+
+
+ ///
+ /// Radius of the torus, from the center of the torus to the center of the tube. Default is 1.
+ ///
+ public double Radius { get; set; } = 1;
+
+ ///
+ /// Radius of the tube. Default is 0.4.
+ ///
+ public double Tube { get; set; } = 0.4f;
+
+ ///
+ /// Number of radial segments. Default is 8.
+ ///
+ public int RadialSegments { get; set; } = 8;
+
+ ///
+ /// Number of tubular segments. Default is 64.
+ ///
+ public int TubularSegments { get; set; } = 64;
+
+ ///
+ /// This value determines, how many times the geometry winds around its axis of rotational symmetry. Default is 2.
+ ///
+ public int P { get; set; } = 2;
+
+ ///
+ /// This value determines, how many times the geometry winds around a circle in the interior of the torus. Default is 3.
+ ///
+ public int Q { get; set; } = 3;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/GlobalUsings.cs b/src/Blazor3D/Blazor3D/GlobalUsings.cs
new file mode 100644
index 0000000..90eb2c1
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/GlobalUsings.cs
@@ -0,0 +1,22 @@
+global using Blazor3D.Cameras;
+global using Blazor3D.ComponentHelpers;
+global using Blazor3D.Controls;
+global using Blazor3D.Core;
+global using Blazor3D.Enums;
+global using Blazor3D.Events;
+global using Blazor3D.Geometires;
+global using Blazor3D.Lights;
+global using Blazor3D.Materials;
+global using Blazor3D.Maths;
+global using Blazor3D.Objects;
+global using Blazor3D.Scenes;
+global using Blazor3D.Settings;
+global using Microsoft.AspNetCore.Builder;
+global using Microsoft.AspNetCore.Components;
+global using Microsoft.AspNetCore.StaticFiles;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.JSInterop;
+global using Newtonsoft.Json;
+global using Newtonsoft.Json.Converters;
+global using Newtonsoft.Json.Linq;
+global using Newtonsoft.Json.Serialization;
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/ArrowHelper.cs b/src/Blazor3D/Blazor3D/Helpers/ArrowHelper.cs
new file mode 100644
index 0000000..12ee8de
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/ArrowHelper.cs
@@ -0,0 +1,69 @@
+namespace Blazor3D.Helpers;
+
+///
+/// An 3D arrow object for visualizing directions.
+/// This object inherits from
+/// Wrapper for three.js ArrowHelper
+///
+///
+public sealed class ArrowHelper : Object3D
+{
+ public ArrowHelper() : base("ArrowHelper")
+ {
+ }
+
+ ///
+ /// Constructor with parameters.
+ ///
+ /// Direction from origin. Must be a unit vector. It's normilized before applying. Default is (0, 0, 1).
+ /// Point at which the arrow starts. Default is (0, 0, 0).
+ /// Length of the arrow. Default is 1.
+ /// Color. Default is "0xffff00".
+ /// The length of the head of the arrow. Default is 0.2 * Length.
+ /// The width of the head of the arrow. Default is 0.2 * HeadLength.
+ public ArrowHelper(
+ Vector3 dir = null!,
+ Vector3 origin = null!,
+ double length = 1,
+ string color = "0xffff00",
+ double headLength = 0.2,
+ double headWidth = 0.2 * 0.2) : this()
+ {
+ Dir = dir ?? new Vector3(0, 0, 1);
+ Origin = origin ?? new Vector3(0, 0, 0);
+ Length = length;
+ Color = color;
+ HeadLength = headLength;
+ HeadWidth = headWidth;
+ }
+
+ ///
+ /// Direction from origin. Must be a unit vector. It's normilized before applying. Default is (0, 0, 1).
+ ///
+ public Vector3 Dir { get; set; } = new(0, 0, 1);
+
+ ///
+ /// Point at which the arrow starts. Default is (0, 0, 0).
+ ///
+ public Vector3 Origin { get; set; } = new(0, 0, 0);
+
+ ///
+ /// Length of the arrow. Default is 1.
+ ///
+ public double Length { get; set; } = 1;
+
+ ///
+ /// Color. Default is "0xffff00".
+ ///
+ public string Color { get; set; } = "0xffff00";
+
+ ///
+ /// The length of the head of the arrow. Default is 0.2 * Length.
+ ///
+ public double HeadLength { get; set; } = 0.2;
+
+ ///
+ /// The width of the head of the arrow. Default is 0.2 * HeadLength.
+ ///
+ public double HeadWidth { get; set; } = 0.2 * 0.2;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/AxesHelper.cs b/src/Blazor3D/Blazor3D/Helpers/AxesHelper.cs
new file mode 100644
index 0000000..e98796d
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/AxesHelper.cs
@@ -0,0 +1,30 @@
+namespace Blazor3D.Helpers;
+
+///
+/// An axis object to visualize the 3 axes in a simple way.
+/// The X axis is red.The Y axis is green.The Z axis is blue.
+/// This object inherits from
+/// Wrapper for three.js AxesHelper
+///
+///
+public sealed class AxesHelper : Object3D
+{
+ public AxesHelper() : base("AxesHelper")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// Size of the lines representing the axes. Default is 1.
+ public AxesHelper(double size = 1) : this()
+ {
+ Size = size;
+ }
+
+
+ ///
+ /// Size of the lines representing the axes. Default is 1.
+ ///
+ public double Size { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/BoxHelper.cs b/src/Blazor3D/Blazor3D/Helpers/BoxHelper.cs
new file mode 100644
index 0000000..6ca3477
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/BoxHelper.cs
@@ -0,0 +1,27 @@
+namespace Blazor3D.Helpers;
+
+///
+/// Helper object to graphically show the world-axis-aligned bounding box around an object.
+/// This object inherits from
+/// Wrapper for three.js BoxHelper
+///
+///
+public sealed class BoxHelper : Object3D
+{
+ public BoxHelper() : base("BoxHelper")
+ {
+ }
+
+ public BoxHelper(Object3D object3d = null!, string color = "0xffff00") : this()
+ {
+ Object3D = object3d;
+ Color = color;
+ }
+
+ ///
+ /// The to show the world-axis-aligned boundingbox.
+ ///
+ public Object3D Object3D { get; set; } = null!;
+
+ public string Color { get; set; } = "0xffff00";
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/GridHelper.cs b/src/Blazor3D/Blazor3D/Helpers/GridHelper.cs
new file mode 100644
index 0000000..7c7b9de
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/GridHelper.cs
@@ -0,0 +1,43 @@
+namespace Blazor3D.Helpers;
+
+///
+/// The GridHelper is an object to define grids. Grids are two-dimensional arrays of lines.
+/// This object inherits from
+/// Wrapper for three.js GridHelper
+///
+///
+public sealed class GridHelper : Object3D
+{
+ public GridHelper() : base("GridHelper")
+ {
+ }
+
+ public GridHelper(double size = 10, int devisions = 10, string colorCenterLine = "0x444444",
+ string colorGrid = "0x888888") : this()
+ {
+ Size = size;
+ Divisions = devisions;
+ ColorCenterLine = colorCenterLine;
+ ColorGrid = colorGrid;
+ }
+
+ ///
+ /// The size of the grid. Default is 10.
+ ///
+ public double Size { get; set; } = 10;
+
+ ///
+ /// The number of divisions across the grid. Default is 10.
+ ///
+ public int Divisions { get; set; } = 10;
+
+ ///
+ /// The color of the centerline. This can be a Color, a hexadecimal value and an CSS-Color name. Default is "0x444444:.
+ ///
+ public string ColorCenterLine { get; set; } = "0x444444";
+
+ ///
+ /// The color of the lines of the grid. This can be a Color, a hexadecimal value and an CSS-Color name. Default is "0x888888".
+ ///
+ public string ColorGrid { get; set; } = "0x888888";
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/PlaneHelper.cs b/src/Blazor3D/Blazor3D/Helpers/PlaneHelper.cs
new file mode 100644
index 0000000..9ac3301
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/PlaneHelper.cs
@@ -0,0 +1,42 @@
+namespace Blazor3D.Helpers;
+
+///
+/// Helper object to visualize a .
+/// This object inherits from
+/// Wrapper for three.js PlaneHelper
+///
+///
+public sealed class PlaneHelper : Object3D
+{
+ public PlaneHelper() : base("PlaneHelper")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// The to visualize.
+ /// Side length of plane helper. Default is 1.
+ /// The color of the helper. Default is "0xffff00".
+ public PlaneHelper(Plane plane = null!, double size = 1, string color = "0xffff00") : this()
+ {
+ Plane = plane ?? new Plane();
+ Size = size;
+ Color = color;
+ }
+
+ ///
+ /// The to visualize.
+ ///
+ public Plane Plane { get; set; } = new();
+
+ ///
+ /// Side length of plane helper. Default is 1.
+ ///
+ public double Size { get; set; } = 1;
+
+ ///
+ /// The color of the helper. Default is "0xffff00".
+ ///
+ public string Color { get; set; } = "0xffff00";
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/PointLightHelper.cs b/src/Blazor3D/Blazor3D/Helpers/PointLightHelper.cs
new file mode 100644
index 0000000..25c2b19
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/PointLightHelper.cs
@@ -0,0 +1,41 @@
+namespace Blazor3D.Helpers;
+
+///
+/// This displays a helper object consisting of a spherical for visualizing a .
+/// This object inherits from
+/// Wrapper for three.js PointLightHelper
+///
+public sealed class PointLightHelper : Object3D
+{
+ public PointLightHelper() : base("PointLightHelper")
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// The light to be visualized. Must be already added to the scene.
+ /// The size of the sphere helper. Default is 1.
+ /// The size of the sphere helper. If color is not set, the helper will take the color of the light.
+ public PointLightHelper(PointLight light = null!, double sphereSize = 1, string color = null!) : this()
+ {
+ Light = light ?? new PointLight();
+ SphereSize = sphereSize;
+ Color = color;
+ }
+
+ ///
+ /// The light to be visualized. Must be already added to the scene.
+ ///
+ public PointLight Light { get; set; } = new();
+
+ ///
+ /// The size of the sphere helper. Default is 1.
+ ///
+ public double SphereSize { get; set; } = 1;
+
+ ///
+ /// The size of the sphere helper. If color is not set, the helper will take the color of the light.
+ ///
+ public string Color { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Helpers/PolarGridHelper.cs b/src/Blazor3D/Blazor3D/Helpers/PolarGridHelper.cs
new file mode 100644
index 0000000..2aa4cdb
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Helpers/PolarGridHelper.cs
@@ -0,0 +1,60 @@
+namespace Blazor3D.Helpers;
+
+///
+/// The PolarGridHelper is an object to define polar grids. Grids are two-dimensional arrays of lines.
+/// This object inherits from
+/// Wrapper for three.js PolarGridHelper
+///
+///
+public class PolarGridHelper : Object3D
+{
+ public PolarGridHelper() : base("PolarGridHelper")
+ {
+ }
+
+ public PolarGridHelper(
+ double radius = 10,
+ int radials = 16,
+ int circles = 8,
+ int divisions = 64,
+ string color1 = "0x444444",
+ string color2 = "0x888888") : this()
+ {
+ Radius = radius;
+ Radials = radials;
+ Circles = circles;
+ Divisions = divisions;
+ Color1 = color1;
+ Color2 = color2;
+ }
+
+ ///
+ /// The radius of the polar grid. This can be any positive number. Default is 10.
+ ///
+ public double Radius { get; set; } = 10;
+
+ ///
+ /// The number of radial lines. This can be any positive integer. Default is 16.
+ ///
+ public int Radials { get; set; } = 16;
+
+ ///
+ /// The number of circles. This can be any positive integer. Default is 8.
+ ///
+ public int Circles { get; set; } = 8;
+
+ ///
+ /// The number of line segments used for each circle. This can be any positive integer that is 3 or greater. Default is 64.
+ ///
+ public int Divisions { get; set; } = 64;
+
+ ///
+ /// The first color used for grid elements. This can be a Color, a hexadecimal value and an CSS-Color name. Default is "0x444444".
+ ///
+ public string Color1 { get; set; } = "0x444444";
+
+ ///
+ /// The second color used for grid elements. This can be a Color, a hexadecimal value and an CSS-Color name. Default is 0x888888
+ ///
+ public string Color2 { get; set; } = "0x888888";
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Lights/AmbientLight.cs b/src/Blazor3D/Blazor3D/Lights/AmbientLight.cs
new file mode 100644
index 0000000..f57f8ea
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Lights/AmbientLight.cs
@@ -0,0 +1,16 @@
+namespace Blazor3D.Lights;
+
+///
+/// This light globally illuminates all objects in the scene equally.
+/// This light cannot be used to cast shadows as it does not have a direction.
+/// This class inherits from
+/// Wrapper for three.js AmbientLight
+///
+///
+public sealed class AmbientLight : Light
+{
+ public AmbientLight() : base("AmbientLight")
+ {
+ Intensity = 0.6f;
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Lights/Light.cs b/src/Blazor3D/Blazor3D/Lights/Light.cs
new file mode 100644
index 0000000..4a5817a
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Lights/Light.cs
@@ -0,0 +1,25 @@
+namespace Blazor3D.Lights;
+
+///
+/// Abstract base class for lights.
+/// Wrapper for three.js Light
+///
+///
+public abstract class Light : Object3D
+{
+ protected Light(string type = "Light") : base(type)
+ {
+ }
+
+ ///
+ /// Light color.
+ /// You can use web color values to set up required color.
+ /// Default value is "white"
+ ///
+ public string Color { get; set; } = "white";
+
+ ///
+ /// Value of the light's strength/intensity. Default is 1.
+ ///
+ public double Intensity { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Lights/PointLight.cs b/src/Blazor3D/Blazor3D/Lights/PointLight.cs
new file mode 100644
index 0000000..ebe08a1
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Lights/PointLight.cs
@@ -0,0 +1,28 @@
+namespace Blazor3D.Lights;
+
+///
+/// A light that gets emitted from a single point in all directions. A common use case for this is to replicate the light emitted from a bare lightbulb.
+/// This light can cast shadows
+/// This class inherits from
+/// Wrapper for three.js PointLight
+///
+///
+public sealed class PointLight : Light
+{
+ public PointLight() : base("PointLight")
+ {
+ }
+
+ ///
+ /// When distance value is NOT 0, light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light.
+ /// When distance is zero, light does not attenuate.
+ /// Default is 0.
+ ///
+ public double Distance { get; set; } = 0;
+
+ ///
+ /// The amount the light dims along the distance of the light
+ /// Default is 1.
+ ///
+ public double Decay { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Materials/LineBasicMaterial.cs b/src/Blazor3D/Blazor3D/Materials/LineBasicMaterial.cs
new file mode 100644
index 0000000..5dc6615
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Materials/LineBasicMaterial.cs
@@ -0,0 +1,31 @@
+namespace Blazor3D.Materials;
+
+///
+/// A material for drawing wireframe-style geometries.
+///
+public class LineBasicMaterial : Material
+{
+ ///
+ /// Default constructor
+ ///
+ public LineBasicMaterial() : base("LineBasicMaterial")
+ {
+ }
+
+ ///
+ /// Define appearance of line ends. Possible values are 'butt', 'round' and 'square'. Default is 'round'.
+ ///
+ public string LineCap { get; set; } = "round"; // todo: deal with enum
+
+ ///
+ /// Define appearance of line joints. Possible values are 'round', 'bevel' and 'miter'. Default is 'round'.
+ ///
+ public string LineJoin { get; set; } = "round"; // todo: deal with enum
+
+
+ ///
+ /// Controls line thickness. Default is 1.
+ /// Due to limitations of the OpenGL Core Profile with the WebGL renderer on most platforms linewidth will always be 1 regardless of the set value.
+ ///
+ public double LineWidth { get; set; } = 1;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Materials/Material.cs b/src/Blazor3D/Blazor3D/Materials/Material.cs
new file mode 100644
index 0000000..018b55a
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Materials/Material.cs
@@ -0,0 +1,58 @@
+namespace Blazor3D.Materials;
+
+///
+/// Abstract base class for materials.
+/// Materials describe the appearance of objects. They are defined in a mostly renderer-independent way, so you don't have to rewrite materials if you decide to use a different renderer.
+/// Wrapper for three.js Material
+///
+public abstract class Material
+{
+ protected Material(string type)
+ {
+ Type = type;
+ }
+
+ public string Type { get; } = "Material";
+
+ ///
+ /// Light color.
+ /// You can use web color values to set up required color.
+ /// Default value is "orange"
+ ///
+ public string Color { get; set; } = "orange";
+
+ ///
+ /// Optional name of the object. Default is an empty string. It has not to be unique.
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// Universal unique identifier of this object instance. It's automatically assigned Guid, so it shouldn't be edited.
+ ///
+ public Guid Uuid { get; set; } = Guid.NewGuid();
+
+ ///
+ /// Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects.
+ /// When set to true, the extent to which the material is transparent is controlled by setting its opacity property.
+ /// Default is false.
+ ///
+ public bool Transparent { get; set; }
+
+ ///
+ /// Float in the range of 0.0 - 1.0 indicating how transparent the material is. A value of 0.0 indicates fully transparent, 1.0 is fully opaque.
+ /// If the material's transparent property is not set to true, the material will remain fully opaque and this value will only affect its color.
+ /// Default is 1.0.
+ ///
+ public double Opacity { get; set; } = 1;
+
+ ///
+ /// Wether to have depth test enabled when rendering this material. Default is true.
+ ///
+ public bool DepthTest { get; set; } = true;
+
+ ///
+ /// Wether rendering this material has any affect on the depth buffer. Default is true.
+ /// When drawing 2D overlays it can be useful to disable the depth writing in order to layer several things together without creating z-index artifacts.
+ ///
+ public bool DepthWrite { get; set; } = true;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Materials/MeshStandardMaterial.cs b/src/Blazor3D/Blazor3D/Materials/MeshStandardMaterial.cs
new file mode 100644
index 0000000..9fa2b83
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Materials/MeshStandardMaterial.cs
@@ -0,0 +1,41 @@
+using Blazor3D.Textures;
+
+namespace Blazor3D.Materials;
+
+///
+/// A standard physically based Material, using Metallic-Roughness workflow.
+/// This class inherits from
+/// Wrapper for three.js MeshStandardMaterial
+///
+///
+public sealed class MeshStandardMaterial : Material
+{
+ public MeshStandardMaterial() : base("MeshStandardMaterial")
+ {
+ }
+
+ ///
+ /// Define whether the material is rendered with flat shading. Default is false.
+ ///
+ public bool FlatShading { get; set; } = false;
+
+ ///
+ /// How much the material is like a metal. Non-metallic materials such as wood or stone use 0.0, metallic use 1.0, with nothing (usually) in between. Default is 0.0. A value between 0.0 and 1.0 could be used for a rusty metal look. If metalnessMap is also provided, both values are multiplied.
+ ///
+ public double Metalness { get; set; } = 0;
+
+ ///
+ /// How rough the material appears. 0.0 means a smooth mirror reflection, 1.0 means fully diffuse. Default is 1.0. If roughnessMap is also provided, both values are multiplied.
+ ///
+ public double Roughness { get; set; } = 1;
+
+ ///
+ /// Render geometry as wireframe. Default is false (i.e. render as flat polygons).
+ ///
+ public bool Wireframe { get; set; } = false;
+
+ ///
+ /// The color map. May optionally include an alpha channel, typically combined with Transparent (todo) or AlphaTest(todo). Default is null. The texture map color is modulated by the diffuse Color.
+ ///
+ public Texture Map { get; set; } = new();
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Materials/SpriteMaterial.cs b/src/Blazor3D/Blazor3D/Materials/SpriteMaterial.cs
new file mode 100644
index 0000000..dc1c558
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Materials/SpriteMaterial.cs
@@ -0,0 +1,26 @@
+using Blazor3D.Textures;
+
+namespace Blazor3D.Materials;
+
+public class SpriteMaterial : Material
+{
+ public SpriteMaterial() : base("SpriteMaterial")
+ {
+ }
+
+ ///
+ /// The color map. May optionally include an alpha channel, typically combined with Transparent (todo) or AlphaTest(todo). Default is null. The texture map color is modulated by the diffuse Color.
+ ///
+ public Texture Map { get; set; } = new();
+
+ ///
+ /// Whether the size of the sprite is attenuated by the camera depth. (Perspective camera only.)
+ /// Default is true.
+ ///
+ public bool SizeAttenuation { get; set; } = true;
+
+ ///
+ /// The rotation of the sprite in radians. Default is 0.
+ ///
+ public double Rotation { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Maths/Euler.cs b/src/Blazor3D/Blazor3D/Maths/Euler.cs
new file mode 100644
index 0000000..69d9608
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Maths/Euler.cs
@@ -0,0 +1,30 @@
+namespace Blazor3D.Maths;
+
+///
+/// Representing Euler Angles.
+/// Euler angles describe a rotational transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order.
+/// Iterating through a Euler instance will yield its components (x, y, z, order) in the corresponding order.
+/// Wrapper for three.js Euler
+///
+public sealed class Euler
+{
+ ///
+ /// The double angle of the X axis in radians. Default is 0. Optional.
+ ///
+ public double X { get; set; }
+
+ ///
+ /// The double angle of the Y axis in radians. Default is 0. Optional.
+ ///
+ public double Y { get; set; }
+
+ ///
+ /// The double angle of the Z axis in radians. Default is 0. Optional.
+ ///
+ public double Z { get; set; }
+
+ ///
+ /// String representing the order that the rotations are applied. Default is 'XYZ'. Must be upper case.
+ ///
+ public string Order { get; set; } = "XYZ";
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Maths/Plane.cs b/src/Blazor3D/Blazor3D/Maths/Plane.cs
new file mode 100644
index 0000000..65fe8d3
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Maths/Plane.cs
@@ -0,0 +1,33 @@
+namespace Blazor3D.Maths;
+
+///
+/// A two dimensional surface that extends infinitely in 3d space, represented in Hessian normal form by a unit length normal vector and a constant.
+/// Wrapper for three.js Plane
+///
+public sealed class Plane
+{
+ public Plane()
+ {
+ }
+
+ ///
+ /// Constructor with parameters.
+ ///
+ /// A unit length Vector3 defining the normal of the plane. Default is (1, 0, 0).
+ /// The signed distance from the origin to the plane. Default is 0.
+ public Plane(Vector3 normal = null!, double constant = 0)
+ {
+ Normal = normal ?? new Vector3(1, 0, 0);
+ Constant = constant;
+ }
+
+ ///
+ /// A unit length Vector3 defining the normal of the plane. Default is (1, 0, 0).
+ ///
+ public Vector3 Normal { get; set; } = new(1, 0, 0);
+
+ ///
+ /// The signed distance from the origin to the plane. Default is 0.
+ ///
+ public double Constant { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Maths/Vector2.cs b/src/Blazor3D/Blazor3D/Maths/Vector2.cs
new file mode 100644
index 0000000..68dd593
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Maths/Vector2.cs
@@ -0,0 +1,36 @@
+namespace Blazor3D.Maths;
+
+///
+/// Class representing a 2D vector. A 2D vector is an ordered pair of numbers (labeled x and y), which can be used to represent a number of things, such as point in 2D space, direction or any ordered pair of numbers.
+/// Wrapper for three.js Vector2
+///
+public sealed class Vector2
+{
+ ///
+ /// Default constructor.
+ ///
+ public Vector2()
+ {
+ }
+
+ ///
+ /// Constructor with parameters.
+ ///
+ /// double X value of this vector. Default is 0.
+ /// double Y value of this vector. Default is 0.
+ public Vector2(double x, double y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ ///
+ /// double X value of this vector. Default is 0.
+ ///
+ public double X { get; set; }
+
+ ///
+ /// double Y value of this vector. Default is 0.
+ ///
+ public double Y { get; set; }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Maths/Vector3.cs b/src/Blazor3D/Blazor3D/Maths/Vector3.cs
new file mode 100644
index 0000000..54a19f5
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Maths/Vector3.cs
@@ -0,0 +1,49 @@
+namespace Blazor3D.Maths;
+
+///
+/// Class representing a 3D vector. A 3D vector is an ordered triplet of numbers (labeled x, y, and z),
+/// which can be used to represent a number of things, such as:
+///
+/// - A point in 3D space.
+/// - A direction, length or scale in 3D space.
+/// - Any arbitrary ordered triplet of numbers.
+///
+/// Wrapper for three.js Vector3
+///
+public sealed class Vector3
+{
+ ///
+ /// Default constructor.
+ ///
+ public Vector3()
+ {
+ }
+
+ ///
+ /// Constructor with parameters.
+ ///
+ /// double X value of this vector. Default is 0.
+ /// double Y value of this vector. Default is 0.
+ /// double Z value of this vector. Default is 0.
+ public Vector3(double x, double y, double z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+
+ ///
+ /// double X value of this vector. Default is 0.
+ ///
+ public double X { get; set; }
+
+ ///
+ /// double Y value of this vector. Default is 0.
+ ///
+ public double Y { get; set; }
+
+ ///
+ /// double Z value of this vector. Default is 0.
+ ///
+ public double Z { get; set; }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Objects/Group.cs b/src/Blazor3D/Blazor3D/Objects/Group.cs
new file mode 100644
index 0000000..118933d
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Objects/Group.cs
@@ -0,0 +1,14 @@
+namespace Blazor3D.Objects;
+
+///
+/// This is almost identical to an . Its purpose is to make working with groups of objects syntactically clearer.
+/// This object inherits from
+/// Wrapper for three.js Group
+///
+///
+public sealed class Group : Object3D
+{
+ public Group() : base("Group")
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Objects/Line.cs b/src/Blazor3D/Blazor3D/Objects/Line.cs
new file mode 100644
index 0000000..209d37c
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Objects/Line.cs
@@ -0,0 +1,20 @@
+using Blazor3D.Geometires.Lines;
+
+namespace Blazor3D.Objects;
+
+public class Line : Object3D
+{
+ public Line() : base("Line")
+ {
+ }
+
+ ///
+ /// Collection of (or derived classes) materials, defining the object's appearance.
+ ///
+ public Material Material { get; set; } = new LineBasicMaterial();
+
+ ///
+ /// An instance of (or derived classes), defining the object's structure.
+ ///
+ public BufferGeometry Geometry { get; set; } = new LineGeometry();
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Objects/Mesh.cs b/src/Blazor3D/Blazor3D/Objects/Mesh.cs
new file mode 100644
index 0000000..5e0b960
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Objects/Mesh.cs
@@ -0,0 +1,34 @@
+namespace Blazor3D.Objects;
+
+///
+/// Class representing triangulated polygon mesh based objects. Also serves as a base for other classes.
+/// This object inherits from
+/// Wrapper for three.js Mesh
+///
+///
+public class Mesh : Object3D
+{
+ public Mesh() : base("Mesh")
+ {
+ }
+
+ protected Mesh(string type) : base(type)
+ {
+ }
+
+ //TODO: make Array of materials
+ ///
+ /// Collection of (or derived classes) materials, defining the object's appearance.
+ ///
+ public Material Material { get; set; } = new MeshStandardMaterial();
+
+ ///
+ /// An instance of (or derived classes), defining the object's structure.
+ ///
+ public BufferGeometry Geometry { get; set; } = new BoxGeometry();
+
+ ///
+ /// Material to draw edges with EdgesGeometry. If not specified, no edges will be drawn.
+ ///
+ public LineBasicMaterial EdgesMaterial { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Objects/Sprite.cs b/src/Blazor3D/Blazor3D/Objects/Sprite.cs
new file mode 100644
index 0000000..f239df8
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Objects/Sprite.cs
@@ -0,0 +1,30 @@
+namespace Blazor3D.Objects;
+
+///
+/// Class representing triangulated polygon mesh based objects. Also serves as a base for other classes.
+/// This object inherits from
+/// Wrapper for three.js Mesh
+///
+///
+public class Sprite : Object3D
+{
+ public Sprite() : base("Sprite")
+ {
+ }
+
+ protected Sprite(string type) : base(type)
+ {
+ }
+
+ ///
+ /// Collection of (or derived classes) materials, defining the object's appearance.
+ ///
+ public SpriteMaterial Material { get; set; } = new();
+
+ ///
+ /// The sprite's anchor point, and the point around which the sprite rotates. A value of (0.5,0.5)
+ /// coresponds to the midpoint of the sprite. A value of (0,0) corresponds to the lower left corner of the sprite.
+ /// The default is (0.5,0.5)
+ ///
+ public Vector2 Center { get; set; } = new(0.5, 0.5);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Objects/Text.cs b/src/Blazor3D/Blazor3D/Objects/Text.cs
new file mode 100644
index 0000000..27fe6d8
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Objects/Text.cs
@@ -0,0 +1,8 @@
+namespace Blazor3D.Objects;
+
+public class Text : Mesh
+{
+ public Text() : base("Text")
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Scenes/Scene.cs b/src/Blazor3D/Blazor3D/Scenes/Scene.cs
new file mode 100644
index 0000000..eefccb2
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Scenes/Scene.cs
@@ -0,0 +1,22 @@
+namespace Blazor3D.Scenes;
+
+///
+/// Scenes allow you to set up what and where is to be rendered by Blazor3D.
+/// This is the place where you put your 3D objects and lights.
+/// This object inherits from
+/// Wrapper for three.js Scene
+///
+///
+public sealed class Scene : Object3D
+{
+ public Scene() : base("Scene")
+ {
+ }
+
+ ///
+ /// Scene background color.
+ /// You can use web color values to set up required color.
+ /// Default value is "DarkSlateBlue">
+ ///
+ public string BackGroundColor { get; set; } = "DarkSlateBlue";
+}
\ No newline at end of file
diff --git a/src/dotnet/Blazor3D/Blazor3D/Settings/AnimateObject3DSettings.cs b/src/Blazor3D/Blazor3D/Settings/AnimateObject3DSettings.cs
similarity index 86%
rename from src/dotnet/Blazor3D/Blazor3D/Settings/AnimateObject3DSettings.cs
rename to src/Blazor3D/Blazor3D/Settings/AnimateObject3DSettings.cs
index f556ad7..2d0ae87 100644
--- a/src/dotnet/Blazor3D/Blazor3D/Settings/AnimateObject3DSettings.cs
+++ b/src/Blazor3D/Blazor3D/Settings/AnimateObject3DSettings.cs
@@ -1,6 +1,4 @@
-using HomagGroup.Blazor3D.Maths;
-
-namespace HomagGroup.Blazor3D.Settings;
+namespace Blazor3D.Settings;
///
/// Settings used for animations on Object3D/>.
@@ -15,7 +13,7 @@ public class AnimateObject3DSettings
///
/// a list of points representing the path for object movement.
///
- public List Points { get; set; } = new List();
+ public List Points { get; set; } = [];
///
/// The animation speed
diff --git a/src/Blazor3D/Blazor3D/Settings/AnimateRotationSettings.cs b/src/Blazor3D/Blazor3D/Settings/AnimateRotationSettings.cs
new file mode 100644
index 0000000..d0004c2
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Settings/AnimateRotationSettings.cs
@@ -0,0 +1,59 @@
+namespace Blazor3D.Settings;
+
+///
+/// Settings used for animated rotations.
+///
+public sealed class AnimateRotationSettings
+{
+ public AnimateRotationSettings()
+ {
+ }
+
+ ///
+ /// Constructor with parameters
+ ///
+ /// The option indicates whether the rotation animation should be applied. Default is false.
+ /// The angle in degreees to rotate around the X axis on each animation frame. Default is 0.1.
+ /// The angle in degreees to rotate around the Y axis on each animation frame. Default is 0.1.
+ /// The angle in degreees to rotate around the Z axis on each animation frame. Default is 0.1.
+ /// Radius of rotation. Default is 5.
+ public AnimateRotationSettings(bool animateRotation = false, double thetaX = 0.1, double thetaY = 0.1,
+ double thetaZ = 0.1, double radius = 5)
+ {
+ AnimateRotation = animateRotation;
+ ThetaX = thetaX;
+ ThetaY = thetaY;
+ ThetaZ = thetaZ;
+ Radius = radius;
+ }
+
+ ///
+ /// The option indicates whether the rotation animation should be applied. Default is false.
+ ///
+ public bool AnimateRotation { get; set; } = false;
+
+ ///
+ /// The angle in degreees to rotate around the X axis on each animation frame. Default is 0.1.
+ ///
+ public double ThetaX { get; set; } = 0.1;
+
+ ///
+ /// The angle in degreees to rotate around the Y axis on each animation frame. Default is 0.1.
+ ///
+ public double ThetaY { get; set; } = 0.1;
+
+ ///
+ /// The angle in degreees to rotate around the Z axis on each animation frame. Default is 0.1.
+ ///
+ public double ThetaZ { get; set; } = 0.1;
+
+ ///
+ /// Radius of rotation. Default is 5.
+ ///
+ public double Radius { get; set; } = 5;
+
+ ///
+ /// Stops animation when user starts using orbit controls. Default is false.
+ ///
+ public bool StopAnimationOnOrbitControlMove { get; set; } = false;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Settings/ImportSettings.cs b/src/Blazor3D/Blazor3D/Settings/ImportSettings.cs
new file mode 100644
index 0000000..12173ca
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Settings/ImportSettings.cs
@@ -0,0 +1,35 @@
+namespace Blazor3D.Settings;
+
+///
+/// Settings that will be applied during 3D model file importing.
+///
+public class ImportSettings
+{
+ ///
+ /// format of 3D model.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))] //todo: may be use serialization helper
+ public Import3DFormats Format { get; set; }
+
+ ///
+ /// URL of the 3D model file.
+ ///
+ public string FileURL { get; set; } = null!;
+
+ ///
+ /// URL of the texture file
+ ///
+ public string? TextureURL { get; set; } = null;
+
+ ///
+ /// UUID of the object to be loaded. Nullable. If not specified, the new Guid is genrated.
+ ///
+ public Guid? Uuid { get; set; } = null;
+
+ ///
+ /// Material that will be applied to all loaded meshes.
+ /// Currently, works only for STL format.
+ /// If not specified, the default is applied to the imported objects.
+ ///
+ public MeshStandardMaterial Material { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Settings/SpriteImportSettings.cs b/src/Blazor3D/Blazor3D/Settings/SpriteImportSettings.cs
new file mode 100644
index 0000000..8543c25
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Settings/SpriteImportSettings.cs
@@ -0,0 +1,40 @@
+namespace Blazor3D.Settings;
+
+public class SpriteImportSettings
+{
+ ///
+ /// URL of the sprite image.
+ ///
+ public string FileURL { get; set; } = null!;
+
+ ///
+ /// UUID of the object to be loaded. Nullable. If not specified, the new Guid is genrated.
+ ///
+ public Guid? Uuid { get; set; } = null;
+
+ ///
+ /// Material that will be applied to loaded sprites.
+ /// If not specified, the default is applied to the imported objects.
+ ///
+ public SpriteMaterial Material { get; set; } = null!;
+
+ ///
+ /// Optional name of the object. Default is an empty string. It has not to be unique.
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// A Vector3 representing the object's local position. Default is (0,0,0).
+ ///
+ public Vector3 Position { get; set; } = new(0, 0, 0);
+
+ ///
+ /// Ojbect's local rotation
+ ///
+ public Euler Rotation { get; set; } = new();
+
+ ///
+ /// The object's local scale. Default is a Vector3(1, 1, 1)
+ ///
+ public Vector3 Scale { get; set; } = new(1, 1, 1);
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Settings/ViewerSettings.cs b/src/Blazor3D/Blazor3D/Settings/ViewerSettings.cs
new file mode 100644
index 0000000..fff7395
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Settings/ViewerSettings.cs
@@ -0,0 +1,40 @@
+using Blazor3D.Viewers;
+
+namespace Blazor3D.Settings;
+
+///
+/// Class for Blazor3D Viewer settings.
+///
+public sealed class ViewerSettings
+{
+ ///
+ /// Identifier of the html container where instance will be created.
+ /// Must be unique on the html page! Default is "blazorview3d"
+ ///
+ public string ContainerId { get; set; } = "blazorview3d";
+
+ ///
+ /// If true, user can select objects by mouse. Default is false.
+ ///
+ public bool CanSelect { get; set; } = false;
+
+ ///
+ /// If true, the helpers can be selected by mouse. Default is false.
+ ///
+ public bool CanSelectHelpers { get; set; } = false;
+
+ ///
+ /// Color the selected element is highlighted. Default is "lime".
+ ///
+ public string SelectedColor { get; set; } = "lime";
+
+ ///
+ /// Show or hide ViewHelper
+ ///
+ public bool ShowViewHelper { get; set; } = true;
+
+ ///
+ /// Blazor3D Viewer WebGLRenderer settings
+ ///
+ public WebGLRendererSettings WebGLRendererSettings { get; set; } = new();
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Settings/WebGLRendererSettings.cs b/src/Blazor3D/Blazor3D/Settings/WebGLRendererSettings.cs
new file mode 100644
index 0000000..78d0c33
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Settings/WebGLRendererSettings.cs
@@ -0,0 +1,22 @@
+namespace Blazor3D.Settings;
+
+///
+/// Class for Blazor3D Viewer WebGLRenderer settings.
+///
+public class WebGLRendererSettings
+{
+ ///
+ /// Whether to perform antialiasing. Default is true.
+ ///
+ public bool Antialias { get; set; } = true;
+
+ ///
+ /// controls the default clear alpha value. When set to true, the value is 0. Otherwise it's 1. Default is false.
+ ///
+ public bool Alpha { get; set; } = false;
+
+ ///
+ /// whether the renderer will assume that colors have premultiplied alpha. Default is true.
+ ///
+ public bool PremultipliedAlpha { get; set; } = true;
+}
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Textures/Texture.cs b/src/Blazor3D/Blazor3D/Textures/Texture.cs
new file mode 100644
index 0000000..307c27b
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Textures/Texture.cs
@@ -0,0 +1,68 @@
+namespace Blazor3D.Textures;
+
+public class Texture
+{
+ public Texture()
+ {
+ }
+
+ protected Texture(string type)
+ {
+ Type = type;
+ }
+
+ public string Type { get; } = "Texture";
+
+
+ ///
+ /// Optional name of the texture (doesn't need to be unique). Default is an empty string.
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// Universal unique identifier of this object instance. It's automatically assigned Guid, so it shouldn't be edited.
+ ///
+ public Guid Uuid { get; set; } = Guid.NewGuid();
+
+ ///
+ /// URL of the texture image file.
+ ///
+ public string TextureUrl { get; set; } = string.Empty;
+
+ ///
+ /// This defines how the texture is wrapped horizontally and corresponds to U in UV mapping.
+ /// The default is , where the edge is clamped to the outer edge texels.
+ /// See the for details.
+ ///
+ public WrappingType WrapS { get; set; } = WrappingType.ClampToEdgeWrapping;
+
+ ///
+ /// This defines how the texture is wrapped vertically and corresponds to V in UV mapping.
+ /// The same choices are available as for WrapS. See the for details.
+ /// NOTE: tiling of images in textures only functions if image dimensions are powers of two (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL, not three.js.
+ ///
+ public WrappingType WrapT { get; set; } = WrappingType.ClampToEdgeWrapping;
+
+ ///
+ /// How many times the texture is repeated across the surface, in each direction U and V.
+ /// If repeat is set greater than 1 in either direction, the corresponding Wrap parameter should also be set to or to achieve the desired tiling effect.
+ /// Setting different repeat values for textures is restricted in the same way like Offset.
+ ///
+ public Vector2 Repeat { get; set; } = new(1, 1);
+
+ ///
+ /// How much a single repetition of the texture is offset from the beginning, in each direction U and V. Typical range is 0.0 to 1.0.
+ /// For more details see here
+ ///
+ public Vector2 Offset { get; set; } = new(0, 0);
+
+ ///
+ /// The point around which rotation occurs. A value of (0.5, 0.5) corresponds to the center of the texture. Default is (0, 0), the lower left.
+ ///
+ public Vector2 Center { get; set; } = new(0, 0);
+
+ ///
+ /// How much the texture is rotated around the center point, in radians. Positive values are counter-clockwise. Default is 0.
+ ///
+ public double Rotation { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/src/dotnet/Blazor3D/Blazor3D/Viewers/Viewer.razor b/src/Blazor3D/Blazor3D/Viewers/Viewer.razor
similarity index 94%
rename from src/dotnet/Blazor3D/Blazor3D/Viewers/Viewer.razor
rename to src/Blazor3D/Blazor3D/Viewers/Viewer.razor
index 1645c57..ea6b30f 100644
--- a/src/dotnet/Blazor3D/Blazor3D/Viewers/Viewer.razor
+++ b/src/Blazor3D/Blazor3D/Viewers/Viewer.razor
@@ -1,4 +1,4 @@
@inject IJSRuntime JSRuntime
@implements IDisposable
-
+
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/Viewers/Viewer.razor.cs b/src/Blazor3D/Blazor3D/Viewers/Viewer.razor.cs
new file mode 100644
index 0000000..43bca75
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/Viewers/Viewer.razor.cs
@@ -0,0 +1,411 @@
+namespace Blazor3D.Viewers;
+
+///
+/// Blazor3D viewer component.
+///
+public sealed partial class Viewer : IDisposable
+{
+ private IJSObjectReference bundleModule = null!;
+
+ private delegate void SelectedObjectStaticEventHandler(Object3DStaticArgs e);
+
+ private static event SelectedObjectStaticEventHandler ObjectSelectedStatic = null!;
+
+ private delegate void LoadedObjectStaticEventHandler(Object3DStaticArgs e);
+
+ private static event LoadedObjectStaticEventHandler ObjectLoadedStatic = null!;
+
+ private event LoadedObjectEventHandler ObjectLoadedPrivate = null!;
+
+ ///
+ /// Raises when user selects object by mouse clicking inside viewer area.
+ ///
+ public event SelectedObjectEventHandler ObjectSelected = null!;
+
+ ///
+ /// Raises after complete loading of imported file content.
+ ///
+ public event LoadedObjectEventHandler ObjectLoaded = null!;
+
+ ///
+ /// Raises after JavaScript module is completely loaded.
+ ///
+ public event LoadedModuleEventHandler JsModuleLoaded = null!;
+
+ ///
+ /// parameter of the component.
+ ///
+ [Parameter] public ViewerSettings ViewerSettings { get; set; } = new();
+
+ ///
+ /// parameter of the component. Default is empty scene.
+ ///
+ [Parameter] public Scene Scene { get; set; } = new();
+
+ ///
+ /// If true and there is no children objects in the scene, then adds the default lights and box mesh. Default value is false.
+ ///
+ [Parameter] public bool UseDefaultScene { get; set; } = false;
+
+ ///
+ /// used to display the scene.
+ ///
+ [Parameter] public Camera Camera { get; set; } = new PerspectiveCamera { Position = new Vector3(3, 3, 3) };
+
+ ///
+ /// used to rotate, pan and scale the view.
+ ///
+ [Parameter] public OrbitControls OrbitControls { get; set; } = new();
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ ObjectSelectedStatic += OnObjectSelectedStatic;
+ ObjectLoadedStatic += OnObjectLoadedStatic;
+ ObjectLoadedPrivate += OnObjectLoadedPrivate;
+
+ bundleModule = await JSRuntime.InvokeAsync("import", "./_content/Blazor3D/js/bundle.js").AsTask();
+
+ if (UseDefaultScene && !Scene.Children.Any()) AddDefaultScene();
+
+ var json = JsonConvert.SerializeObject(new { Scene, ViewerSettings, Camera, OrbitControls }, SerializationHelper.GetSerializerSettings());
+
+ await bundleModule.InvokeVoidAsync("loadViewer", json);
+
+ await OnModuleLoaded();
+ }
+ }
+
+ ///
+ /// Updates scene changes.
+ ///
+ /// Task
+ public async Task UpdateScene()
+ {
+ var json = JsonConvert.SerializeObject(Scene, SerializationHelper.GetSerializerSettings());
+
+ await bundleModule.InvokeVoidAsync("updateScene", json);
+ }
+
+ ///
+ /// Sets the camera position to specified value.
+ ///
+ /// New position.
+ /// New camera target point coordinates.
+ /// Task
+ public async Task SetCameraPositionAsync(Vector3 position, Vector3 lookAt = null!) => await bundleModule.InvokeVoidAsync("setCameraPosition", position, lookAt);
+
+ ///
+ /// Apply updated camera settings to viewer.
+ ///
+ /// Task
+ public async Task UpdateCamera(Camera camera)
+ {
+ Camera = camera;
+
+ var json = JsonConvert.SerializeObject(Camera, SerializationHelper.GetSerializerSettings());
+
+ await bundleModule.InvokeVoidAsync("updateCamera", json);
+ }
+
+ ///
+ /// Prints information about current camera and orbit controls into browser console.
+ ///
+ /// Task
+ public async Task ShowCurrentCameraInfo() => await bundleModule.InvokeVoidAsync("showCurrentCameraInfo");
+
+ ///
+ /// Apply updated orbit controls to viewer.
+ ///
+ /// new orbit controls
+ /// Task
+ public async Task UpdateOrbitControls(OrbitControls orbitControls)
+ {
+ OrbitControls = orbitControls;
+
+ var json = JsonConvert.SerializeObject(OrbitControls, SerializationHelper.GetSerializerSettings());
+
+ await bundleModule.InvokeVoidAsync("updateOrbitControls", json);
+ }
+
+ [JSInvokable]
+ public static Task ReceiveSelectedObjectUUID(string containerId, string uuid)
+ {
+ var guid = string.IsNullOrWhiteSpace(uuid) ? Guid.Empty : Guid.Parse(uuid);
+
+ var result = containerId + uuid;
+
+ ObjectSelectedStatic?.Invoke(new Object3DStaticArgs
+ {
+ ContainerId = containerId,
+ UUID = guid,
+ });
+
+ return Task.FromResult(result);
+ }
+
+ [JSInvokable]
+ public static Task ReceiveLoadedObjectUUID(string containerId, string uuid)
+ {
+ var result = containerId + uuid;
+
+ ObjectLoadedStatic?.Invoke(new Object3DStaticArgs
+ {
+ ContainerId = containerId,
+ UUID = new Guid(uuid),
+ });
+
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// Removes object from scene by it's unique identifier.
+ ///
+ /// Object's unique identifier.
+ /// Task
+ public async Task RemoveByUuidAsync(Guid uuid)
+ {
+ var result = await bundleModule.InvokeAsync("removeByUuid", uuid);
+
+ if (result) ChildrenHelper.RemoveObjectByUuid(uuid, Scene.Children);
+ }
+
+ ///
+ /// Selects object in scene by it's unique identifier
+ ///
+ /// Unique identifier of object to select
+ /// Task
+ public async Task SelectByUuidAsync(Guid uuid) => await bundleModule.InvokeVoidAsync("selectByUuid", uuid);
+
+ ///
+ /// Clears scene.
+ ///
+ /// Task
+ public async Task ClearSceneAsync()
+ {
+ await bundleModule.InvokeVoidAsync("clearScene");
+
+ Scene.Children.Clear();
+ }
+
+ ///
+ /// Imports 3D model to scene.
+ ///
+ /// Settings that will be applied during 3D model file importing.
+ /// Guid of the loaded item
+ public async Task Import3DModelAsync(ImportSettings settings)
+ {
+ settings.Uuid = settings.Uuid ?? Guid.NewGuid();
+ settings.Material = settings.Material ?? new MeshStandardMaterial();
+
+ var json = JsonConvert.SerializeObject(settings, SerializationHelper.GetSerializerSettings());
+
+ await bundleModule.InvokeVoidAsync("import3DModel", json);
+
+ return settings.Uuid.Value;
+ }
+
+ ///
+ /// Imports 3D model file to scene.
+ ///
+ /// URL of the 3D model file.
+ /// Material that will be applied to all loaded meshes.
+ /// URL of the texture file.
+ /// UUID of the object to be loaded. Nullable. If not specified, the new Guid is generated.
+ /// Guid of the loaded item
+ public async Task Import3DModelFileAsync(string fileUrl, MeshStandardMaterial? material = null, string? textureUrl = null, Guid? uuid = null)
+ {
+ var fileExtension = fileUrl.Substring(fileUrl.LastIndexOf('.') + 1);
+
+ var settings = new ImportSettings
+ {
+ FileURL = fileUrl,
+ Format = fileExtension switch
+ {
+ "stl" => Import3DFormats.Stl,
+ "gltf" or "glb" => Import3DFormats.Gltf,
+ "dae" => Import3DFormats.Collada,
+ "fbx" => Import3DFormats.Fbx,
+ "usd" or "usda" or "usdc" or "usdz" => Import3DFormats.Usdz,
+ "obj" => Import3DFormats.Obj
+ }
+ };
+
+ if (material is not null) settings.Material = material;
+
+ if (textureUrl is not null) settings.TextureURL = textureUrl;
+
+ if (uuid is not null) settings.Uuid = uuid;
+
+ return await Import3DModelAsync(settings);
+ }
+
+ ///
+ /// Imports sprite to scene.
+ ///
+ /// Settings that will be applied during 2D sprite file importing.
+ /// Guid of the loaded item
+ public async Task ImportSpriteAsync(SpriteImportSettings settings)
+ {
+ settings.Uuid = settings.Uuid ?? Guid.NewGuid();
+ settings.Material = settings.Material ?? new SpriteMaterial();
+
+ var json = JsonConvert.SerializeObject(settings, SerializationHelper.GetSerializerSettings());
+
+ await bundleModule.InvokeVoidAsync("importSprite", json);
+
+ return settings.Uuid.Value;
+ }
+
+ ///
+ /// Recursively finds object by it's uuid in collection.
+ ///
+ /// Object's uuid
+ /// Children collection. Usually it's Scene.Children
+ /// Found object or null
+ public static Object3D? GetObjectByUuid(Guid uuid, List children) => ChildrenHelper.GetObjectByUuid(uuid, children);
+
+ private async Task OnModuleLoaded()
+ {
+ var handler = JsModuleLoaded;
+
+ if (handler == null) return;
+
+ var invocationList = handler.GetInvocationList();
+ var handlerTasks = new Task[invocationList.Length];
+
+ for (var i = 0; i < invocationList.Length; i++)
+ handlerTasks[i] = ((LoadedModuleEventHandler)invocationList[i])();
+
+ await Task.WhenAll(handlerTasks);
+ }
+
+ //todo: move to helper
+ private void AddDefaultScene()
+ {
+ Scene.Add(new AmbientLight());
+
+ Scene.Add(new PointLight
+ {
+ Position = new Vector3
+ {
+ X = 1,
+ Y = 3,
+ Z = 0
+ }
+ });
+
+ Scene.Add(new Mesh());
+ }
+
+ private void OnObjectSelectedStatic(Object3DStaticArgs e)
+ {
+ if (ViewerSettings.ContainerId == e.ContainerId)
+ ObjectSelected?.Invoke(new Object3DArgs { UUID = e.UUID });
+ }
+
+ private void OnObjectLoadedStatic(Object3DStaticArgs e)
+ {
+ if (ViewerSettings.ContainerId == e.ContainerId)
+ ObjectLoadedPrivate?.Invoke(new Object3DArgs { UUID = e.UUID });
+ }
+
+ //todo: move to children helper
+ private List ParseChildren(JToken? children)
+ {
+ var result = new List();
+
+ if (children?.Type != JTokenType.Array) return result;
+
+ foreach (var child in children)
+ {
+ var c = child as JObject;
+
+ if (c == null) continue;
+
+ var type = c.Property("type")?.Value.ToString();
+ var name = c.Property("name")?.Value.ToString() ?? string.Empty;
+ var uuid = c.Property("uuid")?.Value.ToString() ?? string.Empty;
+
+ if (type == "Mesh")
+ {
+ var mesh = new Mesh
+ {
+ Name = name,
+ Uuid = Guid.Parse(uuid)
+ };
+ result.Add(mesh);
+ }
+
+ if (type == "Group")
+ {
+ var ch = c.Property("children")?.Value;
+ var childrenResult = ParseChildren(ch);
+ var group = new Group
+ {
+ Name = name,
+ Uuid = Guid.Parse(uuid),
+ };
+ group.Children.AddRange(childrenResult);
+ }
+ }
+
+ return result;
+ }
+
+ private async Task OnObjectLoadedPrivate(Object3DArgs e)
+ {
+ var json = await bundleModule.InvokeAsync("getSceneItemByGuid", e.UUID);
+
+ if (json.Contains("\"type\":\"Group\""))
+ {
+ var jobject = JObject.Parse(json);
+ var name = jobject.Property("name")?.Value.ToString() ?? string.Empty;
+ var uuidstr = jobject.Property("uuid")?.Value.ToString() ?? string.Empty;
+ var children = jobject.Property("children")?.Value;
+ var childrenResult = ParseChildren(children);
+
+ var group = new Group
+ {
+ Name = name,
+ Uuid = Guid.Parse(uuidstr),
+ };
+
+ group.Children.AddRange(childrenResult);
+
+ Scene.Children.Add(group);
+
+ ObjectLoaded?.Invoke(new Object3DArgs { UUID = e.UUID });
+ }
+
+ if (json.Contains("\"type\":\"Mesh\""))
+ {
+ var mesh = JsonConvert.DeserializeObject(json);
+
+ if (mesh != null)
+ {
+ Scene.Children.Add(mesh);
+ ObjectLoaded?.Invoke(new Object3DArgs { UUID = e.UUID });
+ }
+ }
+
+ if (json.Contains("\"type\":\"Sprite\""))
+ {
+ var sprite = JsonConvert.DeserializeObject(json);
+
+ if (sprite != null)
+ {
+ Scene.Children.Add(sprite);
+ ObjectLoaded?.Invoke(new Object3DArgs { UUID = e.UUID });
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ ObjectSelectedStatic -= OnObjectSelectedStatic;
+ ObjectLoadedStatic -= OnObjectLoadedStatic;
+ ObjectLoadedPrivate -= OnObjectLoadedPrivate;
+ }
+}
\ No newline at end of file
diff --git a/src/dotnet/Blazor3D/Blazor3D/Viewers/Viewer.razor.css b/src/Blazor3D/Blazor3D/Viewers/Viewer.razor.css
similarity index 67%
rename from src/dotnet/Blazor3D/Blazor3D/Viewers/Viewer.razor.css
rename to src/Blazor3D/Blazor3D/Viewers/Viewer.razor.css
index 99efe1f..d01a8c8 100644
--- a/src/dotnet/Blazor3D/Blazor3D/Viewers/Viewer.razor.css
+++ b/src/Blazor3D/Blazor3D/Viewers/Viewer.razor.css
@@ -1,5 +1,4 @@
.viewer3dContainer {
width: 100%;
- height:100%;
-}
-
+ height: 100%;
+}
\ No newline at end of file
diff --git a/src/dotnet/Blazor3D/Blazor3D/_Imports.razor b/src/Blazor3D/Blazor3D/_Imports.razor
similarity index 63%
rename from src/dotnet/Blazor3D/Blazor3D/_Imports.razor
rename to src/Blazor3D/Blazor3D/_Imports.razor
index b4df76f..9423b43 100644
--- a/src/dotnet/Blazor3D/Blazor3D/_Imports.razor
+++ b/src/Blazor3D/Blazor3D/_Imports.razor
@@ -1,2 +1,2 @@
@using Microsoft.AspNetCore.Components.Web
-@using Microsoft.JSInterop
+@using Microsoft.JSInterop
\ No newline at end of file
diff --git a/src/javascript/Builders/CameraBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/CameraBuilder.js
similarity index 100%
rename from src/javascript/Builders/CameraBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/CameraBuilder.js
diff --git a/src/javascript/Builders/GeometryBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/GeometryBuilder.js
similarity index 100%
rename from src/javascript/Builders/GeometryBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/GeometryBuilder.js
diff --git a/src/javascript/Builders/GroupBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/GroupBuilder.js
similarity index 100%
rename from src/javascript/Builders/GroupBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/GroupBuilder.js
diff --git a/src/javascript/Builders/HelperBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/HelperBuilder.js
similarity index 100%
rename from src/javascript/Builders/HelperBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/HelperBuilder.js
diff --git a/src/javascript/Builders/LightBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/LightBuilder.js
similarity index 100%
rename from src/javascript/Builders/LightBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/LightBuilder.js
diff --git a/src/javascript/Builders/LineBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/LineBuilder.js
similarity index 100%
rename from src/javascript/Builders/LineBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/LineBuilder.js
diff --git a/src/javascript/Builders/MaterialBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/MaterialBuilder.js
similarity index 100%
rename from src/javascript/Builders/MaterialBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/MaterialBuilder.js
diff --git a/src/javascript/Builders/MeshBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/MeshBuilder.js
similarity index 100%
rename from src/javascript/Builders/MeshBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/MeshBuilder.js
diff --git a/src/javascript/Builders/SceneBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/SceneBuilder.js
similarity index 100%
rename from src/javascript/Builders/SceneBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/SceneBuilder.js
diff --git a/src/javascript/Builders/SpriteBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/SpriteBuilder.js
similarity index 100%
rename from src/javascript/Builders/SpriteBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/SpriteBuilder.js
diff --git a/src/javascript/Builders/TextBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/TextBuilder.js
similarity index 100%
rename from src/javascript/Builders/TextBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/TextBuilder.js
diff --git a/src/javascript/Builders/TextGeometryBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/TextGeometryBuilder.js
similarity index 100%
rename from src/javascript/Builders/TextGeometryBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/TextGeometryBuilder.js
diff --git a/src/javascript/Builders/TextureBuilder.js b/src/Blazor3D/Blazor3D/npmJS/Builders/TextureBuilder.js
similarity index 100%
rename from src/javascript/Builders/TextureBuilder.js
rename to src/Blazor3D/Blazor3D/npmJS/Builders/TextureBuilder.js
diff --git a/src/javascript/Utils/Transforms.js b/src/Blazor3D/Blazor3D/npmJS/Utils/Transforms.js
similarity index 100%
rename from src/javascript/Utils/Transforms.js
rename to src/Blazor3D/Blazor3D/npmJS/Utils/Transforms.js
diff --git a/src/javascript/Viewer/Exporters.js b/src/Blazor3D/Blazor3D/npmJS/Viewer/Exporters.js
similarity index 76%
rename from src/javascript/Viewer/Exporters.js
rename to src/Blazor3D/Blazor3D/npmJS/Viewer/Exporters.js
index 1fdb3f2..07e01e0 100644
--- a/src/javascript/Viewer/Exporters.js
+++ b/src/Blazor3D/Blazor3D/npmJS/Viewer/Exporters.js
@@ -1,5 +1,5 @@
import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter";
-import { ColladaExporter } from "three/examples/jsm/exporters/ColladaExporter";
+//import { ColladaExporter } from "three/examples/jsm/exporters/ColladaExporter";
import { OBJExporter } from "three/examples/jsm/exporters/OBJExporter";
function save(blob, filename) {
@@ -38,15 +38,15 @@ class Exporters {
});
}
- static exportCollada(input) {
- const exporter = new ColladaExporter();
- const result = exporter.parse(input, undefined, {
- upAxis: "Y_UP",
- unitName: "millimeter",
- unitMeter: 0.001,
- });
- saveString(result.data, "scene.dae");
- }
+ //static exportCollada(input) {
+ // const exporter = new ColladaExporter();
+ // const result = exporter.parse(input, undefined, {
+ // upAxis: "Y_UP",
+ // unitName: "millimeter",
+ // unitMeter: 0.001,
+ // });
+ // saveString(result.data, "scene.dae");
+ //}
}
export default Exporters;
diff --git a/src/Blazor3D/Blazor3D/npmJS/Viewer/Loaders.js b/src/Blazor3D/Blazor3D/npmJS/Viewer/Loaders.js
new file mode 100644
index 0000000..ba5aee9
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/npmJS/Viewer/Loaders.js
@@ -0,0 +1,178 @@
+import * as THREE from "three";
+import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
+import { ColladaLoader } from "three/examples/jsm/loaders/ColladaLoader";
+import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
+import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
+import { STLLoader } from 'three/examples/jsm/loaders/STLLoader';
+import { USDZLoader } from "three/examples/jsm/loaders/USDZLoader";
+import Transforms from "../Utils/Transforms";
+import MaterialBuilder from "../Builders/MaterialBuilder";
+
+class Loaders
+{
+ static loadGltf(scene, url, guid, containerId)
+ {
+ const loader = new GLTFLoader();
+ loader.load(url, (object) =>
+ {
+ object.scene.uuid = guid;
+ scene.add(object.scene);
+ Loaders.callDotNet(containerId, guid);
+ });
+ }
+ static loadFbx(scene, url, guid, containerId)
+ {
+ const loader = new FBXLoader();
+ loader.load(url, (object) =>
+ {
+ scene.add(object);
+ object.uuid = guid;
+ Loaders.callDotNet(containerId, guid);
+ });
+ }
+
+ static loadCollada(scene, url, guid, containerId)
+ {
+ let object;
+ const manager = new THREE.LoadingManager(() =>
+ {
+ scene.add(object);
+ object.uuid = guid;
+ Loaders.callDotNet(containerId, guid);
+ });
+ const loader = new ColladaLoader(manager);
+ loader.load(url, (obj) =>
+ {
+ object = obj.scene;
+ });
+ }
+
+ static loadOBJ(scene, objUrl, textureUrl, guid, containerId)
+ {
+ let object;
+ const manager = new THREE.LoadingManager(() =>
+ {
+ if (textureUrl)
+ {
+ object.traverse(function (child)
+ {
+ if (child.isMesh) child.material.map = texture;
+ });
+ }
+ scene.add(object);
+ object.uuid = guid;
+ Loaders.callDotNet(containerId, guid);
+ });
+
+ const textureLoader = new THREE.TextureLoader(manager);
+ const texture = textureLoader.load(textureUrl);
+
+ const loader = new OBJLoader(manager);
+ loader.load(objUrl, (obj) =>
+ {
+ object = obj;
+ });
+ return object;
+ }
+
+ static loadStl(scene, url, guid, containerId, materialSettings)
+ {
+ let mesh;
+ const loader = new STLLoader();
+ loader.load(url, function (geometry)
+ {
+
+ // const material = new THREE.MeshPhongMaterial( { color: 0xff5533, specular: 0x111111, shininess: 200 } );
+ // const material = new THREE.MeshStandardMaterial({
+ // color: 0xff5533,
+ // });
+ const material = MaterialBuilder.buildMaterial(materialSettings);
+ mesh = new THREE.Mesh(geometry, material);
+ mesh.uuid = guid;
+
+ // mesh.position.set( 0, - 0.25, 0.6 );
+ // mesh.rotation.set( 0, - Math.PI / 2, 0 );
+ // mesh.scale.set( 0.5, 0.5, 0.5 );
+
+ // mesh.castShadow = true;
+ // mesh.receiveShadow = true;
+
+ scene.add(mesh);
+ Loaders.callDotNet(containerId, guid);
+
+ });
+ }
+
+ static loadUsdz(scene, url, guid, containerId, materialSettings)
+ {
+ let mesh;
+ const loader = new USDZLoader();
+
+ loader.load(url, function (geometry)
+ {
+ const material = MaterialBuilder.buildMaterial(materialSettings);
+ mesh = new THREE.Mesh(geometry, material);
+ mesh.uuid = guid;
+
+ scene.add(mesh);
+
+ Loaders.callDotNet(containerId, guid);
+ });
+ }
+
+ static import3DModel(scene, settings, containerId)
+ {
+ const format = settings.format;
+ let objUrl = settings.fileURL;
+ let textureUrl = settings.textureURL;
+ let guid = settings.uuid;
+ let material = settings.material;
+
+ if (format == "Obj")
+ return Loaders.loadOBJ(scene, objUrl, textureUrl, guid, containerId);
+ if (format == "Collada")
+ return Loaders.loadCollada(scene, objUrl, guid, containerId);
+ if (format == "Fbx")
+ return Loaders.loadFbx(scene, objUrl, guid, containerId);
+ if (format == "Gltf")
+ return Loaders.loadGltf(scene, objUrl, guid, containerId);
+
+ if (format == "Stl")
+ return Loaders.loadStl(scene, objUrl, guid, containerId, material);
+
+ if (format == "Usdz")
+ return Loaders.loadUsdz(scene, objUrl, guid, containerId, material);
+
+ return null;
+ }
+
+ static importSprite(scene, settings, containerId)
+ {
+ let url = settings.fileURL;
+ let guid = settings.uuid;
+ let sprite;
+ settings.material.map.textureUrl = url;
+ const material = MaterialBuilder.buildMaterial(settings.material);
+ sprite = new THREE.Sprite(material);
+ Transforms.setPosition(sprite, settings.position);
+ Transforms.setRotation(sprite, settings.rotation);
+ Transforms.setScale(sprite, settings.scale);
+ sprite.uuid = guid;
+ sprite.name = settings.name;
+ scene.add(sprite);
+ Loaders.callDotNet(containerId, guid);
+ }
+
+
+ static callDotNet(containerId, uuid)
+ {
+ DotNet.invokeMethodAsync(
+ "Blazor3D",
+ "ReceiveLoadedObjectUUID",
+ containerId,
+ uuid
+ );
+ }
+}
+
+export default Loaders;
diff --git a/src/javascript/Viewer/Viewer3D.js b/src/Blazor3D/Blazor3D/npmJS/Viewer/Viewer3D.js
similarity index 100%
rename from src/javascript/Viewer/Viewer3D.js
rename to src/Blazor3D/Blazor3D/npmJS/Viewer/Viewer3D.js
diff --git a/src/javascript/index.js b/src/Blazor3D/Blazor3D/npmJS/index.js
similarity index 100%
rename from src/javascript/index.js
rename to src/Blazor3D/Blazor3D/npmJS/index.js
diff --git a/src/javascript/package-lock.json b/src/Blazor3D/Blazor3D/npmJS/package-lock.json
similarity index 62%
rename from src/javascript/package-lock.json
rename to src/Blazor3D/Blazor3D/npmJS/package-lock.json
index 30d57e2..386c0d3 100644
--- a/src/javascript/package-lock.json
+++ b/src/Blazor3D/Blazor3D/npmJS/package-lock.json
@@ -9,11 +9,11 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "three": "^0.143.0"
+ "three": "^0.178.0"
},
"devDependencies": {
- "webpack": "^5.82.0",
- "webpack-cli": "^5.0.2"
+ "webpack": "^5.89.0",
+ "webpack-cli": "^5.1.4"
}
},
"node_modules/@discoveryjs/json-ext": {
@@ -21,257 +21,274 @@
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
"integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
- "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz",
- "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==",
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
- "dev": true
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
- "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@types/eslint": {
- "version": "8.37.0",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz",
- "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
}
},
"node_modules/@types/eslint-scope": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
- "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
}
},
"node_modules/@types/estree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
- "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
- "dev": true
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/json-schema": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
- "dev": true
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/node": {
- "version": "20.0.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.0.0.tgz",
- "integrity": "sha512-cD2uPTDnQQCVpmRefonO98/PPijuOnnEy5oytWJFPY1N9aJCz2wJ5kSGWO+zJoed2cY2JxQh6yBuUq4vIn61hw==",
- "dev": true
+ "version": "24.5.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz",
+ "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.12.0"
+ }
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.5.tgz",
- "integrity": "sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/helper-numbers": "1.11.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.5"
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
}
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz",
- "integrity": "sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==",
- "dev": true
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-api-error": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz",
- "integrity": "sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==",
- "dev": true
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz",
- "integrity": "sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==",
- "dev": true
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-numbers": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz",
- "integrity": "sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.5",
- "@webassemblyjs/helper-api-error": "1.11.5",
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz",
- "integrity": "sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==",
- "dev": true
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz",
- "integrity": "sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.11.5",
- "@webassemblyjs/helper-buffer": "1.11.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.5",
- "@webassemblyjs/wasm-gen": "1.11.5"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz",
- "integrity": "sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
},
"node_modules/@webassemblyjs/leb128": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.5.tgz",
- "integrity": "sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/utf8": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.5.tgz",
- "integrity": "sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==",
- "dev": true
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz",
- "integrity": "sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.11.5",
- "@webassemblyjs/helper-buffer": "1.11.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.5",
- "@webassemblyjs/helper-wasm-section": "1.11.5",
- "@webassemblyjs/wasm-gen": "1.11.5",
- "@webassemblyjs/wasm-opt": "1.11.5",
- "@webassemblyjs/wasm-parser": "1.11.5",
- "@webassemblyjs/wast-printer": "1.11.5"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz",
- "integrity": "sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.11.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.5",
- "@webassemblyjs/ieee754": "1.11.5",
- "@webassemblyjs/leb128": "1.11.5",
- "@webassemblyjs/utf8": "1.11.5"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz",
- "integrity": "sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.11.5",
- "@webassemblyjs/helper-buffer": "1.11.5",
- "@webassemblyjs/wasm-gen": "1.11.5",
- "@webassemblyjs/wasm-parser": "1.11.5"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz",
- "integrity": "sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.11.5",
- "@webassemblyjs/helper-api-error": "1.11.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.5",
- "@webassemblyjs/ieee754": "1.11.5",
- "@webassemblyjs/leb128": "1.11.5",
- "@webassemblyjs/utf8": "1.11.5"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz",
- "integrity": "sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.11.5",
+ "@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webpack-cli/configtest": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
- "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
+ "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.15.0"
},
@@ -281,10 +298,11 @@
}
},
"node_modules/@webpack-cli/info": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz",
- "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.15.0"
},
@@ -294,10 +312,11 @@
}
},
"node_modules/@webpack-cli/serve": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.2.tgz",
- "integrity": "sha512-S9h3GmOmzUseyeFW3tYNnWS7gNUuwxZ3mmMq0JyW78Vx1SGKPSkt5bT4pB0rUnVfHjP0EL9gW2bOzmtiTfQt0A==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.15.0"
},
@@ -315,19 +334,22 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true
+ "dev": true,
+ "license": "Apache-2.0"
},
"node_modules/acorn": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
- "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -335,44 +357,81 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-import-assertions": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
- "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "node_modules/acorn-import-phases": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
+ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ },
"peerDependencies": {
- "acorn": "^8"
+ "acorn": "^8.14.0"
}
},
"node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
"node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
"peerDependencies": {
- "ajv": "^6.9.1"
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz",
+ "integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
}
},
"node_modules/browserslist": {
- "version": "4.21.5",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
- "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+ "version": "4.26.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz",
+ "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==",
"dev": true,
"funding": [
{
@@ -382,13 +441,19 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001449",
- "electron-to-chromium": "^1.4.284",
- "node-releases": "^2.0.8",
- "update-browserslist-db": "^1.0.10"
+ "baseline-browser-mapping": "^2.8.3",
+ "caniuse-lite": "^1.0.30001741",
+ "electron-to-chromium": "^1.5.218",
+ "node-releases": "^2.0.21",
+ "update-browserslist-db": "^1.1.3"
},
"bin": {
"browserslist": "cli.js"
@@ -401,12 +466,13 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001482",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001482.tgz",
- "integrity": "sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ==",
+ "version": "1.0.30001743",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz",
+ "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==",
"dev": true,
"funding": [
{
@@ -421,13 +487,15 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chrome-trace-event": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
- "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0"
}
@@ -437,6 +505,7 @@
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-plain-object": "^2.0.4",
"kind-of": "^6.0.2",
@@ -450,19 +519,22 @@
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -473,16 +545,18 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.384",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.384.tgz",
- "integrity": "sha512-I97q0MmRAAqj53+a8vZsDkEXBZki+ehYAOPzwtQzALip52aEp2+BJqHFtTlsfjoqVZYwPpHC8wM6MbsSZQ/Eqw==",
- "dev": true
+ "version": "1.5.222",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.222.tgz",
+ "integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/enhanced-resolve": {
- "version": "5.13.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz",
- "integrity": "sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==",
+ "version": "5.18.3",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
+ "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -492,10 +566,11 @@
}
},
"node_modules/envinfo": {
- "version": "7.8.1",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
- "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
+ "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
"dev": true,
+ "license": "MIT",
"bin": {
"envinfo": "dist/cli.js"
},
@@ -504,16 +579,18 @@
}
},
"node_modules/es-module-lexer": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz",
- "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==",
- "dev": true
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -523,6 +600,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -536,6 +614,7 @@
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -548,6 +627,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -557,6 +637,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -566,6 +647,7 @@
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.8.x"
}
@@ -574,19 +656,32 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
},
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
"integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4.9.1"
}
@@ -596,6 +691,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -604,50 +700,69 @@
"node": ">=8"
}
},
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
"node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "dev": true
+ "dev": true,
+ "license": "BSD-2-Clause"
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "dev": true
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
+ "license": "ISC"
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/import-local": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
- "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"pkg-dir": "^4.2.0",
"resolve-cwd": "^3.0.0"
@@ -667,17 +782,22 @@
"resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
"integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/is-core-module": {
- "version": "2.12.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
- "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has": "^1.0.3"
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -688,6 +808,7 @@
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"isobject": "^3.0.1"
},
@@ -699,13 +820,15 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -715,6 +838,7 @@
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -728,19 +852,22 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -750,6 +877,7 @@
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.11.5"
}
@@ -759,6 +887,7 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
@@ -770,13 +899,15 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -786,6 +917,7 @@
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
@@ -797,19 +929,22 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
- "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
- "dev": true
+ "version": "2.0.21",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz",
+ "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
@@ -825,6 +960,7 @@
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
@@ -837,6 +973,7 @@
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -846,6 +983,7 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -855,6 +993,7 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -863,19 +1002,22 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"find-up": "^4.0.0"
},
@@ -883,20 +1025,12 @@
"node": ">=8"
}
},
- "node_modules/punycode": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
- "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -906,6 +1040,7 @@
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
"integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"resolve": "^1.20.0"
},
@@ -913,19 +1048,33 @@
"node": ">= 10.13.0"
}
},
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/resolve": {
- "version": "1.22.2",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
- "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-core-module": "^2.11.0",
+ "is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -935,6 +1084,7 @@
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
"integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"resolve-from": "^5.0.0"
},
@@ -947,6 +1097,7 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -969,17 +1120,20 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/schema-utils": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz",
- "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
+ "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/json-schema": "^7.0.8",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
},
"engines": {
"node": ">= 10.13.0"
@@ -990,10 +1144,11 @@
}
},
"node_modules/serialize-javascript": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
- "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"randombytes": "^2.1.0"
}
@@ -1003,6 +1158,7 @@
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
"integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"kind-of": "^6.0.2"
},
@@ -1015,6 +1171,7 @@
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
@@ -1027,6 +1184,7 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -1036,6 +1194,7 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -1045,6 +1204,7 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -1055,6 +1215,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -1070,6 +1231,7 @@
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -1078,22 +1240,28 @@
}
},
"node_modules/tapable": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
- "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
+ "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
"node_modules/terser": {
- "version": "5.17.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
- "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==",
+ "version": "5.44.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz",
+ "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "@jridgewell/source-map": "^0.3.2",
- "acorn": "^8.5.0",
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
@@ -1105,16 +1273,17 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.7",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
- "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
+ "version": "5.3.14",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
+ "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.1",
- "terser": "^5.16.5"
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -1139,14 +1308,22 @@
}
},
"node_modules/three": {
- "version": "0.143.0",
- "resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz",
- "integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg=="
+ "version": "0.178.0",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.178.0.tgz",
+ "integrity": "sha512-ybFIB0+x8mz0wnZgSGy2MO/WCO6xZhQSZnmfytSPyNpM0sBafGRVhdaj+erYh5U+RhQOAg/eXqw5uVDiM2BjhQ==",
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz",
+ "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/update-browserslist-db": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
- "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"dev": true,
"funding": [
{
@@ -1162,9 +1339,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -1173,20 +1351,12 @@
"browserslist": ">= 4.21.0"
}
},
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
"node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
+ "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -1196,35 +1366,37 @@
}
},
"node_modules/webpack": {
- "version": "5.82.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.0.tgz",
- "integrity": "sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg==",
+ "version": "5.101.3",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz",
+ "integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/eslint-scope": "^3.7.3",
- "@types/estree": "^1.0.0",
- "@webassemblyjs/ast": "^1.11.5",
- "@webassemblyjs/wasm-edit": "^1.11.5",
- "@webassemblyjs/wasm-parser": "^1.11.5",
- "acorn": "^8.7.1",
- "acorn-import-assertions": "^1.7.6",
- "browserslist": "^4.14.5",
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.8",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.15.0",
+ "acorn-import-phases": "^1.0.3",
+ "browserslist": "^4.24.0",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.13.0",
+ "enhanced-resolve": "^5.17.3",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.1.2",
+ "schema-utils": "^4.3.2",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.3.7",
- "watchpack": "^2.4.0",
- "webpack-sources": "^3.2.3"
+ "terser-webpack-plugin": "^5.3.11",
+ "watchpack": "^2.4.1",
+ "webpack-sources": "^3.3.3"
},
"bin": {
"webpack": "bin/webpack.js"
@@ -1243,15 +1415,16 @@
}
},
"node_modules/webpack-cli": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.2.tgz",
- "integrity": "sha512-4y3W5Dawri5+8dXm3+diW6Mn1Ya+Dei6eEVAdIduAmYNLzv1koKVAqsfgrrc9P2mhrYHQphx5htnGkcNwtubyQ==",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.0.1",
- "@webpack-cli/info": "^2.0.1",
- "@webpack-cli/serve": "^2.0.2",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
"colorette": "^2.0.14",
"commander": "^10.0.1",
"cross-spawn": "^7.0.3",
@@ -1292,17 +1465,20 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/webpack-merge": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
- "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+ "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"clone-deep": "^4.0.1",
+ "flat": "^5.0.2",
"wildcard": "^2.0.0"
},
"engines": {
@@ -1310,10 +1486,11 @@
}
},
"node_modules/webpack-sources": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
- "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10.13.0"
}
@@ -1323,6 +1500,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
@@ -1337,7 +1515,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
"integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
}
}
}
diff --git a/src/javascript/package.json b/src/Blazor3D/Blazor3D/npmJS/package.json
similarity index 73%
rename from src/javascript/package.json
rename to src/Blazor3D/Blazor3D/npmJS/package.json
index eaa2ed9..7193209 100644
--- a/src/javascript/package.json
+++ b/src/Blazor3D/Blazor3D/npmJS/package.json
@@ -4,7 +4,6 @@
"description": "",
"private": true,
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress --profile",
"watch": "webpack --progress --profile --watch",
"production": "webpack --progress --profile --mode production"
@@ -13,10 +12,11 @@
"author": "",
"license": "ISC",
"dependencies": {
- "three": "^0.143.0"
+ "three": "^0.180.0",
+ "three-usdz-loader": "^1.0.9"
},
"devDependencies": {
- "webpack": "^5.82.0",
- "webpack-cli": "^5.0.2"
+ "webpack": "^5.89.0",
+ "webpack-cli": "^5.1.4"
}
}
diff --git a/src/javascript/webpack.config.js b/src/Blazor3D/Blazor3D/npmJS/webpack.config.js
similarity index 57%
rename from src/javascript/webpack.config.js
rename to src/Blazor3D/Blazor3D/npmJS/webpack.config.js
index 6a8662f..0ad78ed 100644
--- a/src/javascript/webpack.config.js
+++ b/src/Blazor3D/Blazor3D/npmJS/webpack.config.js
@@ -2,16 +2,17 @@ const path = require('path');
const webpack = require('webpack');
const bundleFileName = 'bundle';
-const dirName = '../dotnet/Blazor3D/Blazor3D/wwwroot/js';
+const dirName = '../wwwroot/js';
-module.exports = (env, argv) => {
- //todo: bundle.min.js for production mode
+module.exports = (env, argv) =>
+{
+ //todo: bundle.min.js for production mode
return {
mode: argv.mode === "production" ? "production" : "development",
entry: ['./index.js'],
output: {
- library:{
- type: 'module'
+ library: {
+ type: 'module'
},
umdNamedDefine: true,
filename: bundleFileName + ".js",
@@ -19,11 +20,11 @@ module.exports = (env, argv) => {
},
plugins: [
new webpack.BannerPlugin({
- banner: `Copyright © 2022 Roman Simuta aka siroman \nCopyright © 2010-2021 three.js authors https://threejs.org/`
+ banner: `Copyright © 2022 Roman Simuta aka siroman \nCopyright © 2010-2021 three.js authors https://threejs.org/`
})
- ],
- experiments: {
+ ],
+ experiments: {
outputModule: true,
- },
+ },
};
};
\ No newline at end of file
diff --git a/src/Blazor3D/Blazor3D/wwwroot/js/bundle.js b/src/Blazor3D/Blazor3D/wwwroot/js/bundle.js
new file mode 100644
index 0000000..5c4bdc4
--- /dev/null
+++ b/src/Blazor3D/Blazor3D/wwwroot/js/bundle.js
@@ -0,0 +1,2 @@
+/*! For license information please see bundle.js.LICENSE.txt */
+const t="178",e=0,n=1,i=2,r=100,s=101,a=102,o=200,l=201,c=202,h=203,u=204,d=205,p=206,f=207,m=208,g=209,v=210,_=211,y=212,x=213,M=214,b=0,S=1,T=2,w=3,E=4,A=5,R=6,C=7,P="attached",I=301,L=302,N=303,D=306,U=1e3,O=1001,F=1002,k=1003,B=1004,z=1005,H=1006,V=1007,G=1008,W=1009,j=1012,X=1013,q=1014,Y=1015,K=1016,J=1017,Z=1018,$=1020,Q=1023,tt=1026,et=1027,nt=1028,it=1029,rt=1031,st=1033,at=33776,ot=33777,lt=33778,ct=33779,ht=35840,ut=35841,dt=35842,pt=35843,ft=36196,mt=37492,gt=37496,vt=37808,_t=37809,yt=37810,xt=37811,Mt=37812,bt=37813,St=37814,Tt=37815,wt=37816,Et=37817,At=37818,Rt=37819,Ct=37820,Pt=37821,It=36492,Lt=36494,Nt=36495,Dt=36284,Ut=36285,Ot=36286,Ft=2300,kt=2301,Bt=2302,zt="",Ht="srgb",Vt="srgb-linear",Gt="linear",Wt="srgb",jt=7680,Xt=512,qt=513,Yt=514,Kt=515,Jt=516,Zt=517,$t=518,Qt=519,te=35044,ee="300 es",ne=2e3,ie=2001;class re{addEventListener(t,e){void 0===this._listeners&&(this._listeners={});const n=this._listeners;void 0===n[t]&&(n[t]=[]),-1===n[t].indexOf(e)&&n[t].push(e)}hasEventListener(t,e){const n=this._listeners;return void 0!==n&&void 0!==n[t]&&-1!==n[t].indexOf(e)}removeEventListener(t,e){const n=this._listeners;if(void 0===n)return;const i=n[t];if(void 0!==i){const t=i.indexOf(e);-1!==t&&i.splice(t,1)}}dispatchEvent(t){const e=this._listeners;if(void 0===e)return;const n=e[t.type];if(void 0!==n){t.target=this;const e=n.slice(0);for(let n=0,i=e.length;n>8&255]+se[t>>16&255]+se[t>>24&255]+"-"+se[255&e]+se[e>>8&255]+"-"+se[e>>16&15|64]+se[e>>24&255]+"-"+se[63&n|128]+se[n>>8&255]+"-"+se[n>>16&255]+se[n>>24&255]+se[255&i]+se[i>>8&255]+se[i>>16&255]+se[i>>24&255]).toLowerCase()}function he(t,e,n){return Math.max(e,Math.min(n,t))}function ue(t,e){return(t%e+e)%e}function de(t,e,n){return(1-n)*t+n*e}function pe(t,e){switch(e.constructor){case Float32Array:return t;case Uint32Array:return t/4294967295;case Uint16Array:return t/65535;case Uint8Array:return t/255;case Int32Array:return Math.max(t/2147483647,-1);case Int16Array:return Math.max(t/32767,-1);case Int8Array:return Math.max(t/127,-1);default:throw new Error("Invalid component type.")}}function fe(t,e){switch(e.constructor){case Float32Array:return t;case Uint32Array:return Math.round(4294967295*t);case Uint16Array:return Math.round(65535*t);case Uint8Array:return Math.round(255*t);case Int32Array:return Math.round(2147483647*t);case Int16Array:return Math.round(32767*t);case Int8Array:return Math.round(127*t);default:throw new Error("Invalid component type.")}}const me={DEG2RAD:oe,RAD2DEG:le,generateUUID:ce,clamp:he,euclideanModulo:ue,mapLinear:function(t,e,n,i,r){return i+(t-e)*(r-i)/(n-e)},inverseLerp:function(t,e,n){return t!==e?(n-t)/(e-t):0},lerp:de,damp:function(t,e,n,i){return de(t,e,1-Math.exp(-n*i))},pingpong:function(t,e=1){return e-Math.abs(ue(t,2*e)-e)},smoothstep:function(t,e,n){return t<=e?0:t>=n?1:(t=(t-e)/(n-e))*t*(3-2*t)},smootherstep:function(t,e,n){return t<=e?0:t>=n?1:(t=(t-e)/(n-e))*t*t*(t*(6*t-15)+10)},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},seededRandom:function(t){void 0!==t&&(ae=t);let e=ae+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296},degToRad:function(t){return t*oe},radToDeg:function(t){return t*le},isPowerOfTwo:function(t){return!(t&t-1)&&0!==t},ceilPowerOfTwo:function(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))},floorPowerOfTwo:function(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))},setQuaternionFromProperEuler:function(t,e,n,i,r){const s=Math.cos,a=Math.sin,o=s(n/2),l=a(n/2),c=s((e+i)/2),h=a((e+i)/2),u=s((e-i)/2),d=a((e-i)/2),p=s((i-e)/2),f=a((i-e)/2);switch(r){case"XYX":t.set(o*h,l*u,l*d,o*c);break;case"YZY":t.set(l*d,o*h,l*u,o*c);break;case"ZXZ":t.set(l*u,l*d,o*h,o*c);break;case"XZX":t.set(o*h,l*f,l*p,o*c);break;case"YXY":t.set(l*p,o*h,l*f,o*c);break;case"ZYZ":t.set(l*f,l*p,o*h,o*c);break;default:console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: "+r)}},normalize:fe,denormalize:pe};class ge{constructor(t=0,e=0){ge.prototype.isVector2=!0,this.x=t,this.y=e}get width(){return this.x}set width(t){this.x=t}get height(){return this.y}set height(t){this.y=t}set(t,e){return this.x=t,this.y=e,this}setScalar(t){return this.x=t,this.y=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}addScalar(t){return this.x+=t,this.y+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this}subScalar(t){return this.x-=t,this.y-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this}multiply(t){return this.x*=t.x,this.y*=t.y,this}multiplyScalar(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t.x,this.y/=t.y,this}divideScalar(t){return this.multiplyScalar(1/t)}applyMatrix3(t){const e=this.x,n=this.y,i=t.elements;return this.x=i[0]*e+i[3]*n+i[6],this.y=i[1]*e+i[4]*n+i[7],this}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this}clamp(t,e){return this.x=he(this.x,t.x,e.x),this.y=he(this.y,t.y,e.y),this}clampScalar(t,e){return this.x=he(this.x,t,e),this.y=he(this.y,t,e),this}clampLength(t,e){const n=this.length();return this.divideScalar(n||1).multiplyScalar(he(n,t,e))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const n=this.dot(t)/e;return Math.acos(he(n,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,n=this.y-t.y;return e*e+n*n}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this}lerpVectors(t,e,n){return this.x=t.x+(e.x-t.x)*n,this.y=t.y+(e.y-t.y)*n,this}equals(t){return t.x===this.x&&t.y===this.y}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this}rotateAround(t,e){const n=Math.cos(e),i=Math.sin(e),r=this.x-t.x,s=this.y-t.y;return this.x=r*n-s*i+t.x,this.y=r*i+s*n+t.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class ve{constructor(t=0,e=0,n=0,i=1){this.isQuaternion=!0,this._x=t,this._y=e,this._z=n,this._w=i}static slerpFlat(t,e,n,i,r,s,a){let o=n[i+0],l=n[i+1],c=n[i+2],h=n[i+3];const u=r[s+0],d=r[s+1],p=r[s+2],f=r[s+3];if(0===a)return t[e+0]=o,t[e+1]=l,t[e+2]=c,void(t[e+3]=h);if(1===a)return t[e+0]=u,t[e+1]=d,t[e+2]=p,void(t[e+3]=f);if(h!==f||o!==u||l!==d||c!==p){let t=1-a;const e=o*u+l*d+c*p+h*f,n=e>=0?1:-1,i=1-e*e;if(i>Number.EPSILON){const r=Math.sqrt(i),s=Math.atan2(r,e*n);t=Math.sin(t*s)/r,a=Math.sin(a*s)/r}const r=a*n;if(o=o*t+u*r,l=l*t+d*r,c=c*t+p*r,h=h*t+f*r,t===1-a){const t=1/Math.sqrt(o*o+l*l+c*c+h*h);o*=t,l*=t,c*=t,h*=t}}t[e]=o,t[e+1]=l,t[e+2]=c,t[e+3]=h}static multiplyQuaternionsFlat(t,e,n,i,r,s){const a=n[i],o=n[i+1],l=n[i+2],c=n[i+3],h=r[s],u=r[s+1],d=r[s+2],p=r[s+3];return t[e]=a*p+c*h+o*d-l*u,t[e+1]=o*p+c*u+l*h-a*d,t[e+2]=l*p+c*d+a*u-o*h,t[e+3]=c*p-a*h-o*u-l*d,t}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get w(){return this._w}set w(t){this._w=t,this._onChangeCallback()}set(t,e,n,i){return this._x=t,this._y=e,this._z=n,this._w=i,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this._onChangeCallback(),this}setFromEuler(t,e=!0){const n=t._x,i=t._y,r=t._z,s=t._order,a=Math.cos,o=Math.sin,l=a(n/2),c=a(i/2),h=a(r/2),u=o(n/2),d=o(i/2),p=o(r/2);switch(s){case"XYZ":this._x=u*c*h+l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h-u*d*p;break;case"YXZ":this._x=u*c*h+l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h+u*d*p;break;case"ZXY":this._x=u*c*h-l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h-u*d*p;break;case"ZYX":this._x=u*c*h-l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h+u*d*p;break;case"YZX":this._x=u*c*h+l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h-u*d*p;break;case"XZY":this._x=u*c*h-l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h+u*d*p;break;default:console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: "+s)}return!0===e&&this._onChangeCallback(),this}setFromAxisAngle(t,e){const n=e/2,i=Math.sin(n);return this._x=t.x*i,this._y=t.y*i,this._z=t.z*i,this._w=Math.cos(n),this._onChangeCallback(),this}setFromRotationMatrix(t){const e=t.elements,n=e[0],i=e[4],r=e[8],s=e[1],a=e[5],o=e[9],l=e[2],c=e[6],h=e[10],u=n+a+h;if(u>0){const t=.5/Math.sqrt(u+1);this._w=.25/t,this._x=(c-o)*t,this._y=(r-l)*t,this._z=(s-i)*t}else if(n>a&&n>h){const t=2*Math.sqrt(1+n-a-h);this._w=(c-o)/t,this._x=.25*t,this._y=(i+s)/t,this._z=(r+l)/t}else if(a>h){const t=2*Math.sqrt(1+a-n-h);this._w=(r-l)/t,this._x=(i+s)/t,this._y=.25*t,this._z=(o+c)/t}else{const t=2*Math.sqrt(1+h-n-a);this._w=(s-i)/t,this._x=(r+l)/t,this._y=(o+c)/t,this._z=.25*t}return this._onChangeCallback(),this}setFromUnitVectors(t,e){let n=t.dot(e)+1;return n<1e-8?(n=0,Math.abs(t.x)>Math.abs(t.z)?(this._x=-t.y,this._y=t.x,this._z=0,this._w=n):(this._x=0,this._y=-t.z,this._z=t.y,this._w=n)):(this._x=t.y*e.z-t.z*e.y,this._y=t.z*e.x-t.x*e.z,this._z=t.x*e.y-t.y*e.x,this._w=n),this.normalize()}angleTo(t){return 2*Math.acos(Math.abs(he(this.dot(t),-1,1)))}rotateTowards(t,e){const n=this.angleTo(t);if(0===n)return this;const i=Math.min(1,e/n);return this.slerp(t,i),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this._onChangeCallback(),this}multiply(t){return this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const n=t._x,i=t._y,r=t._z,s=t._w,a=e._x,o=e._y,l=e._z,c=e._w;return this._x=n*c+s*a+i*l-r*o,this._y=i*c+s*o+r*a-n*l,this._z=r*c+s*l+n*o-i*a,this._w=s*c-n*a-i*o-r*l,this._onChangeCallback(),this}slerp(t,e){if(0===e)return this;if(1===e)return this.copy(t);const n=this._x,i=this._y,r=this._z,s=this._w;let a=s*t._w+n*t._x+i*t._y+r*t._z;if(a<0?(this._w=-t._w,this._x=-t._x,this._y=-t._y,this._z=-t._z,a=-a):this.copy(t),a>=1)return this._w=s,this._x=n,this._y=i,this._z=r,this;const o=1-a*a;if(o<=Number.EPSILON){const t=1-e;return this._w=t*s+e*this._w,this._x=t*n+e*this._x,this._y=t*i+e*this._y,this._z=t*r+e*this._z,this.normalize(),this}const l=Math.sqrt(o),c=Math.atan2(l,a),h=Math.sin((1-e)*c)/l,u=Math.sin(e*c)/l;return this._w=s*h+this._w*u,this._x=n*h+this._x*u,this._y=i*h+this._y*u,this._z=r*h+this._z*u,this._onChangeCallback(),this}slerpQuaternions(t,e,n){return this.copy(t).slerp(e,n)}random(){const t=2*Math.PI*Math.random(),e=2*Math.PI*Math.random(),n=Math.random(),i=Math.sqrt(1-n),r=Math.sqrt(n);return this.set(i*Math.sin(t),i*Math.cos(t),r*Math.sin(e),r*Math.cos(e))}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w}fromArray(t,e=0){return this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t}fromBufferAttribute(t,e){return this._x=t.getX(e),this._y=t.getY(e),this._z=t.getZ(e),this._w=t.getW(e),this._onChangeCallback(),this}toJSON(){return this.toArray()}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class _e{constructor(t=0,e=0,n=0){_e.prototype.isVector3=!0,this.x=t,this.y=e,this.z=n}set(t,e,n){return void 0===n&&(n=this.z),this.x=t,this.y=e,this.z=n,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return this.applyQuaternion(xe.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(xe.setFromAxisAngle(t,e))}applyMatrix3(t){const e=this.x,n=this.y,i=this.z,r=t.elements;return this.x=r[0]*e+r[3]*n+r[6]*i,this.y=r[1]*e+r[4]*n+r[7]*i,this.z=r[2]*e+r[5]*n+r[8]*i,this}applyNormalMatrix(t){return this.applyMatrix3(t).normalize()}applyMatrix4(t){const e=this.x,n=this.y,i=this.z,r=t.elements,s=1/(r[3]*e+r[7]*n+r[11]*i+r[15]);return this.x=(r[0]*e+r[4]*n+r[8]*i+r[12])*s,this.y=(r[1]*e+r[5]*n+r[9]*i+r[13])*s,this.z=(r[2]*e+r[6]*n+r[10]*i+r[14])*s,this}applyQuaternion(t){const e=this.x,n=this.y,i=this.z,r=t.x,s=t.y,a=t.z,o=t.w,l=2*(s*i-a*n),c=2*(a*e-r*i),h=2*(r*n-s*e);return this.x=e+o*l+s*h-a*c,this.y=n+o*c+a*l-r*h,this.z=i+o*h+r*c-s*l,this}project(t){return this.applyMatrix4(t.matrixWorldInverse).applyMatrix4(t.projectionMatrix)}unproject(t){return this.applyMatrix4(t.projectionMatrixInverse).applyMatrix4(t.matrixWorld)}transformDirection(t){const e=this.x,n=this.y,i=this.z,r=t.elements;return this.x=r[0]*e+r[4]*n+r[8]*i,this.y=r[1]*e+r[5]*n+r[9]*i,this.z=r[2]*e+r[6]*n+r[10]*i,this.normalize()}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this}divideScalar(t){return this.multiplyScalar(1/t)}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this}clamp(t,e){return this.x=he(this.x,t.x,e.x),this.y=he(this.y,t.y,e.y),this.z=he(this.z,t.z,e.z),this}clampScalar(t,e){return this.x=he(this.x,t,e),this.y=he(this.y,t,e),this.z=he(this.z,t,e),this}clampLength(t,e){const n=this.length();return this.divideScalar(n||1).multiplyScalar(he(n,t,e))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this}lerpVectors(t,e,n){return this.x=t.x+(e.x-t.x)*n,this.y=t.y+(e.y-t.y)*n,this.z=t.z+(e.z-t.z)*n,this}cross(t){return this.crossVectors(this,t)}crossVectors(t,e){const n=t.x,i=t.y,r=t.z,s=e.x,a=e.y,o=e.z;return this.x=i*o-r*a,this.y=r*s-n*o,this.z=n*a-i*s,this}projectOnVector(t){const e=t.lengthSq();if(0===e)return this.set(0,0,0);const n=t.dot(this)/e;return this.copy(t).multiplyScalar(n)}projectOnPlane(t){return ye.copy(this).projectOnVector(t),this.sub(ye)}reflect(t){return this.sub(ye.copy(t).multiplyScalar(2*this.dot(t)))}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const n=this.dot(t)/e;return Math.acos(he(n,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return e*e+n*n+i*i}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)}setFromSpherical(t){return this.setFromSphericalCoords(t.radius,t.phi,t.theta)}setFromSphericalCoords(t,e,n){const i=Math.sin(e)*t;return this.x=i*Math.sin(n),this.y=Math.cos(e)*t,this.z=i*Math.cos(n),this}setFromCylindrical(t){return this.setFromCylindricalCoords(t.radius,t.theta,t.y)}setFromCylindricalCoords(t,e,n){return this.x=t*Math.sin(e),this.y=n,this.z=t*Math.cos(e),this}setFromMatrixPosition(t){const e=t.elements;return this.x=e[12],this.y=e[13],this.z=e[14],this}setFromMatrixScale(t){const e=this.setFromMatrixColumn(t,0).length(),n=this.setFromMatrixColumn(t,1).length(),i=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=n,this.z=i,this}setFromMatrixColumn(t,e){return this.fromArray(t.elements,4*e)}setFromMatrix3Column(t,e){return this.fromArray(t.elements,3*e)}setFromEuler(t){return this.x=t._x,this.y=t._y,this.z=t._z,this}setFromColor(t){return this.x=t.r,this.y=t.g,this.z=t.b,this}equals(t){return t.x===this.x&&t.y===this.y&&t.z===this.z}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this.z=t[e+2],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=Math.random()*Math.PI*2,e=2*Math.random()-1,n=Math.sqrt(1-e*e);return this.x=n*Math.cos(t),this.y=e,this.z=n*Math.sin(t),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const ye=new _e,xe=new ve;class Me{constructor(t,e,n,i,r,s,a,o,l){Me.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1],void 0!==t&&this.set(t,e,n,i,r,s,a,o,l)}set(t,e,n,i,r,s,a,o,l){const c=this.elements;return c[0]=t,c[1]=i,c[2]=a,c[3]=e,c[4]=r,c[5]=o,c[6]=n,c[7]=s,c[8]=l,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(t){const e=this.elements,n=t.elements;return e[0]=n[0],e[1]=n[1],e[2]=n[2],e[3]=n[3],e[4]=n[4],e[5]=n[5],e[6]=n[6],e[7]=n[7],e[8]=n[8],this}extractBasis(t,e,n){return t.setFromMatrix3Column(this,0),e.setFromMatrix3Column(this,1),n.setFromMatrix3Column(this,2),this}setFromMatrix4(t){const e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const n=t.elements,i=e.elements,r=this.elements,s=n[0],a=n[3],o=n[6],l=n[1],c=n[4],h=n[7],u=n[2],d=n[5],p=n[8],f=i[0],m=i[3],g=i[6],v=i[1],_=i[4],y=i[7],x=i[2],M=i[5],b=i[8];return r[0]=s*f+a*v+o*x,r[3]=s*m+a*_+o*M,r[6]=s*g+a*y+o*b,r[1]=l*f+c*v+h*x,r[4]=l*m+c*_+h*M,r[7]=l*g+c*y+h*b,r[2]=u*f+d*v+p*x,r[5]=u*m+d*_+p*M,r[8]=u*g+d*y+p*b,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this}determinant(){const t=this.elements,e=t[0],n=t[1],i=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8];return e*s*c-e*a*l-n*r*c+n*a*o+i*r*l-i*s*o}invert(){const t=this.elements,e=t[0],n=t[1],i=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8],h=c*s-a*l,u=a*o-c*r,d=l*r-s*o,p=e*h+n*u+i*d;if(0===p)return this.set(0,0,0,0,0,0,0,0,0);const f=1/p;return t[0]=h*f,t[1]=(i*l-c*n)*f,t[2]=(a*n-i*s)*f,t[3]=u*f,t[4]=(c*e-i*o)*f,t[5]=(i*r-a*e)*f,t[6]=d*f,t[7]=(n*o-l*e)*f,t[8]=(s*e-n*r)*f,this}transpose(){let t;const e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this}getNormalMatrix(t){return this.setFromMatrix4(t).invert().transpose()}transposeIntoArray(t){const e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this}setUvTransform(t,e,n,i,r,s,a){const o=Math.cos(r),l=Math.sin(r);return this.set(n*o,n*l,-n*(o*s+l*a)+s+t,-i*l,i*o,-i*(-l*s+o*a)+a+e,0,0,1),this}scale(t,e){return this.premultiply(be.makeScale(t,e)),this}rotate(t){return this.premultiply(be.makeRotation(-t)),this}translate(t,e){return this.premultiply(be.makeTranslation(t,e)),this}makeTranslation(t,e){return t.isVector2?this.set(1,0,t.x,0,1,t.y,0,0,1):this.set(1,0,t,0,1,e,0,0,1),this}makeRotation(t){const e=Math.cos(t),n=Math.sin(t);return this.set(e,-n,0,n,e,0,0,0,1),this}makeScale(t,e){return this.set(t,0,0,0,e,0,0,0,1),this}equals(t){const e=this.elements,n=t.elements;for(let t=0;t<9;t++)if(e[t]!==n[t])return!1;return!0}fromArray(t,e=0){for(let n=0;n<9;n++)this.elements[n]=t[n+e];return this}toArray(t=[],e=0){const n=this.elements;return t[e]=n[0],t[e+1]=n[1],t[e+2]=n[2],t[e+3]=n[3],t[e+4]=n[4],t[e+5]=n[5],t[e+6]=n[6],t[e+7]=n[7],t[e+8]=n[8],t}clone(){return(new this.constructor).fromArray(this.elements)}}const be=new Me;function Se(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;return!1}function Te(t){return document.createElementNS("http://www.w3.org/1999/xhtml",t)}function we(){const t=Te("canvas");return t.style.display="block",t}Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array;const Ee={};function Ae(t){t in Ee||(Ee[t]=!0,console.warn(t))}const Re=(new Me).set(.4123908,.3575843,.1804808,.212639,.7151687,.0721923,.0193308,.1191948,.9505322),Ce=(new Me).set(3.2409699,-1.5373832,-.4986108,-.9692436,1.8759675,.0415551,.0556301,-.203977,1.0569715);function Pe(){const t={enabled:!0,workingColorSpace:Vt,spaces:{},convert:function(t,e,n){return!1!==this.enabled&&e!==n&&e&&n?(this.spaces[e].transfer===Wt&&(t.r=Le(t.r),t.g=Le(t.g),t.b=Le(t.b)),this.spaces[e].primaries!==this.spaces[n].primaries&&(t.applyMatrix3(this.spaces[e].toXYZ),t.applyMatrix3(this.spaces[n].fromXYZ)),this.spaces[n].transfer===Wt&&(t.r=Ne(t.r),t.g=Ne(t.g),t.b=Ne(t.b)),t):t},workingToColorSpace:function(t,e){return this.convert(t,this.workingColorSpace,e)},colorSpaceToWorking:function(t,e){return this.convert(t,e,this.workingColorSpace)},getPrimaries:function(t){return this.spaces[t].primaries},getTransfer:function(t){return t===zt?Gt:this.spaces[t].transfer},getLuminanceCoefficients:function(t,e=this.workingColorSpace){return t.fromArray(this.spaces[e].luminanceCoefficients)},define:function(t){Object.assign(this.spaces,t)},_getMatrix:function(t,e,n){return t.copy(this.spaces[e].toXYZ).multiply(this.spaces[n].fromXYZ)},_getDrawingBufferColorSpace:function(t){return this.spaces[t].outputColorSpaceConfig.drawingBufferColorSpace},_getUnpackColorSpace:function(t=this.workingColorSpace){return this.spaces[t].workingColorSpaceConfig.unpackColorSpace},fromWorkingColorSpace:function(e,n){return Ae("THREE.ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."),t.workingToColorSpace(e,n)},toWorkingColorSpace:function(e,n){return Ae("THREE.ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."),t.colorSpaceToWorking(e,n)}},e=[.64,.33,.3,.6,.15,.06],n=[.2126,.7152,.0722],i=[.3127,.329];return t.define({[Vt]:{primaries:e,whitePoint:i,transfer:Gt,toXYZ:Re,fromXYZ:Ce,luminanceCoefficients:n,workingColorSpaceConfig:{unpackColorSpace:Ht},outputColorSpaceConfig:{drawingBufferColorSpace:Ht}},[Ht]:{primaries:e,whitePoint:i,transfer:Wt,toXYZ:Re,fromXYZ:Ce,luminanceCoefficients:n,outputColorSpaceConfig:{drawingBufferColorSpace:Ht}}}),t}const Ie=Pe();function Le(t){return t<.04045?.0773993808*t:Math.pow(.9478672986*t+.0521327014,2.4)}function Ne(t){return t<.0031308?12.92*t:1.055*Math.pow(t,.41666)-.055}let De;class Ue{static getDataURL(t,e="image/png"){if(/^data:/i.test(t.src))return t.src;if("undefined"==typeof HTMLCanvasElement)return t.src;let n;if(t instanceof HTMLCanvasElement)n=t;else{void 0===De&&(De=Te("canvas")),De.width=t.width,De.height=t.height;const e=De.getContext("2d");t instanceof ImageData?e.putImageData(t,0,0):e.drawImage(t,0,0,t.width,t.height),n=De}return n.toDataURL(e)}static sRGBToLinear(t){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const e=Te("canvas");e.width=t.width,e.height=t.height;const n=e.getContext("2d");n.drawImage(t,0,0,t.width,t.height);const i=n.getImageData(0,0,t.width,t.height),r=i.data;for(let t=0;t1),this.pmremVersion=0}get width(){return this.source.getSize(ze).x}get height(){return this.source.getSize(ze).y}get depth(){return this.source.getSize(ze).z}get image(){return this.source.data}set image(t=null){this.source.data=t}updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,this.repeat.x,this.repeat.y,this.rotation,this.center.x,this.center.y)}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}clone(){return(new this.constructor).copy(this)}copy(t){return this.name=t.name,this.source=t.source,this.mipmaps=t.mipmaps.slice(0),this.mapping=t.mapping,this.channel=t.channel,this.wrapS=t.wrapS,this.wrapT=t.wrapT,this.magFilter=t.magFilter,this.minFilter=t.minFilter,this.anisotropy=t.anisotropy,this.format=t.format,this.internalFormat=t.internalFormat,this.type=t.type,this.offset.copy(t.offset),this.repeat.copy(t.repeat),this.center.copy(t.center),this.rotation=t.rotation,this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrix.copy(t.matrix),this.generateMipmaps=t.generateMipmaps,this.premultiplyAlpha=t.premultiplyAlpha,this.flipY=t.flipY,this.unpackAlignment=t.unpackAlignment,this.colorSpace=t.colorSpace,this.renderTarget=t.renderTarget,this.isRenderTargetTexture=t.isRenderTargetTexture,this.isArrayTexture=t.isArrayTexture,this.userData=JSON.parse(JSON.stringify(t.userData)),this.needsUpdate=!0,this}setValues(t){for(const e in t){const n=t[e];if(void 0===n){console.warn(`THREE.Texture.setValues(): parameter '${e}' has value of undefined.`);continue}const i=this[e];void 0!==i?i&&n&&i.isVector2&&n.isVector2||i&&n&&i.isVector3&&n.isVector3||i&&n&&i.isMatrix3&&n.isMatrix3?i.copy(n):this[e]=n:console.warn(`THREE.Texture.setValues(): property '${e}' does not exist.`)}}toJSON(t){const e=void 0===t||"string"==typeof t;if(!e&&void 0!==t.textures[this.uuid])return t.textures[this.uuid];const n={metadata:{version:4.7,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,image:this.source.toJSON(t).uuid,mapping:this.mapping,channel:this.channel,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],center:[this.center.x,this.center.y],rotation:this.rotation,wrap:[this.wrapS,this.wrapT],format:this.format,internalFormat:this.internalFormat,type:this.type,colorSpace:this.colorSpace,minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY,generateMipmaps:this.generateMipmaps,premultiplyAlpha:this.premultiplyAlpha,unpackAlignment:this.unpackAlignment};return Object.keys(this.userData).length>0&&(n.userData=this.userData),e||(t.textures[this.uuid]=n),n}dispose(){this.dispatchEvent({type:"dispose"})}transformUv(t){if(300!==this.mapping)return t;if(t.applyMatrix3(this.matrix),t.x<0||t.x>1)switch(this.wrapS){case U:t.x=t.x-Math.floor(t.x);break;case O:t.x=t.x<0?0:1;break;case F:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case U:t.y=t.y-Math.floor(t.y);break;case O:t.y=t.y<0?0:1;break;case F:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}return this.flipY&&(t.y=1-t.y),t}set needsUpdate(t){!0===t&&(this.version++,this.source.needsUpdate=!0)}set needsPMREMUpdate(t){!0===t&&this.pmremVersion++}}He.DEFAULT_IMAGE=null,He.DEFAULT_MAPPING=300,He.DEFAULT_ANISOTROPY=1;class Ve{constructor(t=0,e=0,n=0,i=1){Ve.prototype.isVector4=!0,this.x=t,this.y=e,this.z=n,this.w=i}get width(){return this.z}set width(t){this.z=t}get height(){return this.w}set height(t){this.w=t}set(t,e,n,i){return this.x=t,this.y=e,this.z=n,this.w=i,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this.w=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setW(t){return this.w=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;case 3:this.w=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=void 0!==t.w?t.w:1,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this.w+=t.w,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this.w+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this.w=t.w+e.w,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this.w+=t.w*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this.w-=t.w,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this.w-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this.w=t.w-e.w,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this.w*=t.w,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this}applyMatrix4(t){const e=this.x,n=this.y,i=this.z,r=this.w,s=t.elements;return this.x=s[0]*e+s[4]*n+s[8]*i+s[12]*r,this.y=s[1]*e+s[5]*n+s[9]*i+s[13]*r,this.z=s[2]*e+s[6]*n+s[10]*i+s[14]*r,this.w=s[3]*e+s[7]*n+s[11]*i+s[15]*r,this}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this.w/=t.w,this}divideScalar(t){return this.multiplyScalar(1/t)}setAxisAngleFromQuaternion(t){this.w=2*Math.acos(t.w);const e=Math.sqrt(1-t.w*t.w);return e<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=t.x/e,this.y=t.y/e,this.z=t.z/e),this}setAxisAngleFromRotationMatrix(t){let e,n,i,r;const s=.01,a=.1,o=t.elements,l=o[0],c=o[4],h=o[8],u=o[1],d=o[5],p=o[9],f=o[2],m=o[6],g=o[10];if(Math.abs(c-u)o&&t>v?tv?o1;this.dispose()}this.viewport.set(0,0,t,e),this.scissor.set(0,0,t,e)}clone(){return(new this.constructor).copy(this)}copy(t){this.width=t.width,this.height=t.height,this.depth=t.depth,this.scissor.copy(t.scissor),this.scissorTest=t.scissorTest,this.viewport.copy(t.viewport),this.textures.length=0;for(let e=0,n=t.textures.length;e=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y),(t.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y&&t.max.z>=this.min.z&&t.min.z<=this.max.z}intersectsSphere(t){return this.clampPoint(t.center,Ke),Ke.distanceToSquared(t.center)<=t.radius*t.radius}intersectsPlane(t){let e,n;return t.normal.x>0?(e=t.normal.x*this.min.x,n=t.normal.x*this.max.x):(e=t.normal.x*this.max.x,n=t.normal.x*this.min.x),t.normal.y>0?(e+=t.normal.y*this.min.y,n+=t.normal.y*this.max.y):(e+=t.normal.y*this.max.y,n+=t.normal.y*this.min.y),t.normal.z>0?(e+=t.normal.z*this.min.z,n+=t.normal.z*this.max.z):(e+=t.normal.z*this.max.z,n+=t.normal.z*this.min.z),e<=-t.constant&&n>=-t.constant}intersectsTriangle(t){if(this.isEmpty())return!1;this.getCenter(rn),sn.subVectors(this.max,rn),Ze.subVectors(t.a,rn),$e.subVectors(t.b,rn),Qe.subVectors(t.c,rn),tn.subVectors($e,Ze),en.subVectors(Qe,$e),nn.subVectors(Ze,Qe);let e=[0,-tn.z,tn.y,0,-en.z,en.y,0,-nn.z,nn.y,tn.z,0,-tn.x,en.z,0,-en.x,nn.z,0,-nn.x,-tn.y,tn.x,0,-en.y,en.x,0,-nn.y,nn.x,0];return!!ln(e,Ze,$e,Qe,sn)&&(e=[1,0,0,0,1,0,0,0,1],!!ln(e,Ze,$e,Qe,sn)&&(an.crossVectors(tn,en),e=[an.x,an.y,an.z],ln(e,Ze,$e,Qe,sn)))}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return this.clampPoint(t,Ke).distanceTo(t)}getBoundingSphere(t){return this.isEmpty()?t.makeEmpty():(this.getCenter(t.center),t.radius=.5*this.getSize(Ke).length()),t}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}applyMatrix4(t){return this.isEmpty()||(Ye[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(t),Ye[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(t),Ye[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(t),Ye[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(t),Ye[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(t),Ye[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(t),Ye[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(t),Ye[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(t),this.setFromPoints(Ye)),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}}fromJSON(t){return this.min.fromArray(t.min),this.max.fromArray(t.max),this}}const Ye=[new _e,new _e,new _e,new _e,new _e,new _e,new _e,new _e],Ke=new _e,Je=new qe,Ze=new _e,$e=new _e,Qe=new _e,tn=new _e,en=new _e,nn=new _e,rn=new _e,sn=new _e,an=new _e,on=new _e;function ln(t,e,n,i,r){for(let s=0,a=t.length-3;s<=a;s+=3){on.fromArray(t,s);const a=r.x*Math.abs(on.x)+r.y*Math.abs(on.y)+r.z*Math.abs(on.z),o=e.dot(on),l=n.dot(on),c=i.dot(on);if(Math.max(-Math.max(o,l,c),Math.min(o,l,c))>a)return!1}return!0}const cn=new qe,hn=new _e,un=new _e;class dn{constructor(t=new _e,e=-1){this.isSphere=!0,this.center=t,this.radius=e}set(t,e){return this.center.copy(t),this.radius=e,this}setFromPoints(t,e){const n=this.center;void 0!==e?n.copy(e):cn.setFromPoints(t).getCenter(n);let i=0;for(let e=0,r=t.length;ethis.radius*this.radius&&(e.sub(this.center).normalize(),e.multiplyScalar(this.radius).add(this.center)),e}getBoundingBox(t){return this.isEmpty()?(t.makeEmpty(),t):(t.set(this.center,this.center),t.expandByScalar(this.radius),t)}applyMatrix4(t){return this.center.applyMatrix4(t),this.radius=this.radius*t.getMaxScaleOnAxis(),this}translate(t){return this.center.add(t),this}expandByPoint(t){if(this.isEmpty())return this.center.copy(t),this.radius=0,this;hn.subVectors(t,this.center);const e=hn.lengthSq();if(e>this.radius*this.radius){const t=Math.sqrt(e),n=.5*(t-this.radius);this.center.addScaledVector(hn,n/t),this.radius+=n}return this}union(t){return t.isEmpty()?this:this.isEmpty()?(this.copy(t),this):(!0===this.center.equals(t.center)?this.radius=Math.max(this.radius,t.radius):(un.subVectors(t.center,this.center).setLength(t.radius),this.expandByPoint(hn.copy(t.center).add(un)),this.expandByPoint(hn.copy(t.center).sub(un))),this)}equals(t){return t.center.equals(this.center)&&t.radius===this.radius}clone(){return(new this.constructor).copy(this)}toJSON(){return{radius:this.radius,center:this.center.toArray()}}fromJSON(t){return this.radius=t.radius,this.center.fromArray(t.center),this}}const pn=new _e,fn=new _e,mn=new _e,gn=new _e,vn=new _e,_n=new _e,yn=new _e;class xn{constructor(t=new _e,e=new _e(0,0,-1)){this.origin=t,this.direction=e}set(t,e){return this.origin.copy(t),this.direction.copy(e),this}copy(t){return this.origin.copy(t.origin),this.direction.copy(t.direction),this}at(t,e){return e.copy(this.origin).addScaledVector(this.direction,t)}lookAt(t){return this.direction.copy(t).sub(this.origin).normalize(),this}recast(t){return this.origin.copy(this.at(t,pn)),this}closestPointToPoint(t,e){e.subVectors(t,this.origin);const n=e.dot(this.direction);return n<0?e.copy(this.origin):e.copy(this.origin).addScaledVector(this.direction,n)}distanceToPoint(t){return Math.sqrt(this.distanceSqToPoint(t))}distanceSqToPoint(t){const e=pn.subVectors(t,this.origin).dot(this.direction);return e<0?this.origin.distanceToSquared(t):(pn.copy(this.origin).addScaledVector(this.direction,e),pn.distanceToSquared(t))}distanceSqToSegment(t,e,n,i){fn.copy(t).add(e).multiplyScalar(.5),mn.copy(e).sub(t).normalize(),gn.copy(this.origin).sub(fn);const r=.5*t.distanceTo(e),s=-this.direction.dot(mn),a=gn.dot(this.direction),o=-gn.dot(mn),l=gn.lengthSq(),c=Math.abs(1-s*s);let h,u,d,p;if(c>0)if(h=s*o-a,u=s*a-o,p=r*c,h>=0)if(u>=-p)if(u<=p){const t=1/c;h*=t,u*=t,d=h*(h+s*u+2*a)+u*(s*h+u+2*o)+l}else u=r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;else u=-r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;else u<=-p?(h=Math.max(0,-(-s*r+a)),u=h>0?-r:Math.min(Math.max(-r,-o),r),d=-h*h+u*(u+2*o)+l):u<=p?(h=0,u=Math.min(Math.max(-r,-o),r),d=u*(u+2*o)+l):(h=Math.max(0,-(s*r+a)),u=h>0?r:Math.min(Math.max(-r,-o),r),d=-h*h+u*(u+2*o)+l);else u=s>0?-r:r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;return n&&n.copy(this.origin).addScaledVector(this.direction,h),i&&i.copy(fn).addScaledVector(mn,u),d}intersectSphere(t,e){pn.subVectors(t.center,this.origin);const n=pn.dot(this.direction),i=pn.dot(pn)-n*n,r=t.radius*t.radius;if(i>r)return null;const s=Math.sqrt(r-i),a=n-s,o=n+s;return o<0?null:a<0?this.at(o,e):this.at(a,e)}intersectsSphere(t){return!(t.radius<0)&&this.distanceSqToPoint(t.center)<=t.radius*t.radius}distanceToPlane(t){const e=t.normal.dot(this.direction);if(0===e)return 0===t.distanceToPoint(this.origin)?0:null;const n=-(this.origin.dot(t.normal)+t.constant)/e;return n>=0?n:null}intersectPlane(t,e){const n=this.distanceToPlane(t);return null===n?null:this.at(n,e)}intersectsPlane(t){const e=t.distanceToPoint(this.origin);return 0===e||t.normal.dot(this.direction)*e<0}intersectBox(t,e){let n,i,r,s,a,o;const l=1/this.direction.x,c=1/this.direction.y,h=1/this.direction.z,u=this.origin;return l>=0?(n=(t.min.x-u.x)*l,i=(t.max.x-u.x)*l):(n=(t.max.x-u.x)*l,i=(t.min.x-u.x)*l),c>=0?(r=(t.min.y-u.y)*c,s=(t.max.y-u.y)*c):(r=(t.max.y-u.y)*c,s=(t.min.y-u.y)*c),n>s||r>i?null:((r>n||isNaN(n))&&(n=r),(s=0?(a=(t.min.z-u.z)*h,o=(t.max.z-u.z)*h):(a=(t.max.z-u.z)*h,o=(t.min.z-u.z)*h),n>o||a>i?null:((a>n||n!=n)&&(n=a),(o=0?n:i,e)))}intersectsBox(t){return null!==this.intersectBox(t,pn)}intersectTriangle(t,e,n,i,r){vn.subVectors(e,t),_n.subVectors(n,t),yn.crossVectors(vn,_n);let s,a=this.direction.dot(yn);if(a>0){if(i)return null;s=1}else{if(!(a<0))return null;s=-1,a=-a}gn.subVectors(this.origin,t);const o=s*this.direction.dot(_n.crossVectors(gn,_n));if(o<0)return null;const l=s*this.direction.dot(vn.cross(gn));if(l<0)return null;if(o+l>a)return null;const c=-s*gn.dot(yn);return c<0?null:this.at(c/a,r)}applyMatrix4(t){return this.origin.applyMatrix4(t),this.direction.transformDirection(t),this}equals(t){return t.origin.equals(this.origin)&&t.direction.equals(this.direction)}clone(){return(new this.constructor).copy(this)}}class Mn{constructor(t,e,n,i,r,s,a,o,l,c,h,u,d,p,f,m){Mn.prototype.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],void 0!==t&&this.set(t,e,n,i,r,s,a,o,l,c,h,u,d,p,f,m)}set(t,e,n,i,r,s,a,o,l,c,h,u,d,p,f,m){const g=this.elements;return g[0]=t,g[4]=e,g[8]=n,g[12]=i,g[1]=r,g[5]=s,g[9]=a,g[13]=o,g[2]=l,g[6]=c,g[10]=h,g[14]=u,g[3]=d,g[7]=p,g[11]=f,g[15]=m,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return(new Mn).fromArray(this.elements)}copy(t){const e=this.elements,n=t.elements;return e[0]=n[0],e[1]=n[1],e[2]=n[2],e[3]=n[3],e[4]=n[4],e[5]=n[5],e[6]=n[6],e[7]=n[7],e[8]=n[8],e[9]=n[9],e[10]=n[10],e[11]=n[11],e[12]=n[12],e[13]=n[13],e[14]=n[14],e[15]=n[15],this}copyPosition(t){const e=this.elements,n=t.elements;return e[12]=n[12],e[13]=n[13],e[14]=n[14],this}setFromMatrix3(t){const e=t.elements;return this.set(e[0],e[3],e[6],0,e[1],e[4],e[7],0,e[2],e[5],e[8],0,0,0,0,1),this}extractBasis(t,e,n){return t.setFromMatrixColumn(this,0),e.setFromMatrixColumn(this,1),n.setFromMatrixColumn(this,2),this}makeBasis(t,e,n){return this.set(t.x,e.x,n.x,0,t.y,e.y,n.y,0,t.z,e.z,n.z,0,0,0,0,1),this}extractRotation(t){const e=this.elements,n=t.elements,i=1/bn.setFromMatrixColumn(t,0).length(),r=1/bn.setFromMatrixColumn(t,1).length(),s=1/bn.setFromMatrixColumn(t,2).length();return e[0]=n[0]*i,e[1]=n[1]*i,e[2]=n[2]*i,e[3]=0,e[4]=n[4]*r,e[5]=n[5]*r,e[6]=n[6]*r,e[7]=0,e[8]=n[8]*s,e[9]=n[9]*s,e[10]=n[10]*s,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromEuler(t){const e=this.elements,n=t.x,i=t.y,r=t.z,s=Math.cos(n),a=Math.sin(n),o=Math.cos(i),l=Math.sin(i),c=Math.cos(r),h=Math.sin(r);if("XYZ"===t.order){const t=s*c,n=s*h,i=a*c,r=a*h;e[0]=o*c,e[4]=-o*h,e[8]=l,e[1]=n+i*l,e[5]=t-r*l,e[9]=-a*o,e[2]=r-t*l,e[6]=i+n*l,e[10]=s*o}else if("YXZ"===t.order){const t=o*c,n=o*h,i=l*c,r=l*h;e[0]=t+r*a,e[4]=i*a-n,e[8]=s*l,e[1]=s*h,e[5]=s*c,e[9]=-a,e[2]=n*a-i,e[6]=r+t*a,e[10]=s*o}else if("ZXY"===t.order){const t=o*c,n=o*h,i=l*c,r=l*h;e[0]=t-r*a,e[4]=-s*h,e[8]=i+n*a,e[1]=n+i*a,e[5]=s*c,e[9]=r-t*a,e[2]=-s*l,e[6]=a,e[10]=s*o}else if("ZYX"===t.order){const t=s*c,n=s*h,i=a*c,r=a*h;e[0]=o*c,e[4]=i*l-n,e[8]=t*l+r,e[1]=o*h,e[5]=r*l+t,e[9]=n*l-i,e[2]=-l,e[6]=a*o,e[10]=s*o}else if("YZX"===t.order){const t=s*o,n=s*l,i=a*o,r=a*l;e[0]=o*c,e[4]=r-t*h,e[8]=i*h+n,e[1]=h,e[5]=s*c,e[9]=-a*c,e[2]=-l*c,e[6]=n*h+i,e[10]=t-r*h}else if("XZY"===t.order){const t=s*o,n=s*l,i=a*o,r=a*l;e[0]=o*c,e[4]=-h,e[8]=l*c,e[1]=t*h+r,e[5]=s*c,e[9]=n*h-i,e[2]=i*h-n,e[6]=a*c,e[10]=r*h+t}return e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromQuaternion(t){return this.compose(Tn,t,wn)}lookAt(t,e,n){const i=this.elements;return Rn.subVectors(t,e),0===Rn.lengthSq()&&(Rn.z=1),Rn.normalize(),En.crossVectors(n,Rn),0===En.lengthSq()&&(1===Math.abs(n.z)?Rn.x+=1e-4:Rn.z+=1e-4,Rn.normalize(),En.crossVectors(n,Rn)),En.normalize(),An.crossVectors(Rn,En),i[0]=En.x,i[4]=An.x,i[8]=Rn.x,i[1]=En.y,i[5]=An.y,i[9]=Rn.y,i[2]=En.z,i[6]=An.z,i[10]=Rn.z,this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const n=t.elements,i=e.elements,r=this.elements,s=n[0],a=n[4],o=n[8],l=n[12],c=n[1],h=n[5],u=n[9],d=n[13],p=n[2],f=n[6],m=n[10],g=n[14],v=n[3],_=n[7],y=n[11],x=n[15],M=i[0],b=i[4],S=i[8],T=i[12],w=i[1],E=i[5],A=i[9],R=i[13],C=i[2],P=i[6],I=i[10],L=i[14],N=i[3],D=i[7],U=i[11],O=i[15];return r[0]=s*M+a*w+o*C+l*N,r[4]=s*b+a*E+o*P+l*D,r[8]=s*S+a*A+o*I+l*U,r[12]=s*T+a*R+o*L+l*O,r[1]=c*M+h*w+u*C+d*N,r[5]=c*b+h*E+u*P+d*D,r[9]=c*S+h*A+u*I+d*U,r[13]=c*T+h*R+u*L+d*O,r[2]=p*M+f*w+m*C+g*N,r[6]=p*b+f*E+m*P+g*D,r[10]=p*S+f*A+m*I+g*U,r[14]=p*T+f*R+m*L+g*O,r[3]=v*M+_*w+y*C+x*N,r[7]=v*b+_*E+y*P+x*D,r[11]=v*S+_*A+y*I+x*U,r[15]=v*T+_*R+y*L+x*O,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[4]*=t,e[8]*=t,e[12]*=t,e[1]*=t,e[5]*=t,e[9]*=t,e[13]*=t,e[2]*=t,e[6]*=t,e[10]*=t,e[14]*=t,e[3]*=t,e[7]*=t,e[11]*=t,e[15]*=t,this}determinant(){const t=this.elements,e=t[0],n=t[4],i=t[8],r=t[12],s=t[1],a=t[5],o=t[9],l=t[13],c=t[2],h=t[6],u=t[10],d=t[14];return t[3]*(+r*o*h-i*l*h-r*a*u+n*l*u+i*a*d-n*o*d)+t[7]*(+e*o*d-e*l*u+r*s*u-i*s*d+i*l*c-r*o*c)+t[11]*(+e*l*h-e*a*d-r*s*h+n*s*d+r*a*c-n*l*c)+t[15]*(-i*a*c-e*o*h+e*a*u+i*s*h-n*s*u+n*o*c)}transpose(){const t=this.elements;let e;return e=t[1],t[1]=t[4],t[4]=e,e=t[2],t[2]=t[8],t[8]=e,e=t[6],t[6]=t[9],t[9]=e,e=t[3],t[3]=t[12],t[12]=e,e=t[7],t[7]=t[13],t[13]=e,e=t[11],t[11]=t[14],t[14]=e,this}setPosition(t,e,n){const i=this.elements;return t.isVector3?(i[12]=t.x,i[13]=t.y,i[14]=t.z):(i[12]=t,i[13]=e,i[14]=n),this}invert(){const t=this.elements,e=t[0],n=t[1],i=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8],h=t[9],u=t[10],d=t[11],p=t[12],f=t[13],m=t[14],g=t[15],v=h*m*l-f*u*l+f*o*d-a*m*d-h*o*g+a*u*g,_=p*u*l-c*m*l-p*o*d+s*m*d+c*o*g-s*u*g,y=c*f*l-p*h*l+p*a*d-s*f*d-c*a*g+s*h*g,x=p*h*o-c*f*o-p*a*u+s*f*u+c*a*m-s*h*m,M=e*v+n*_+i*y+r*x;if(0===M)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const b=1/M;return t[0]=v*b,t[1]=(f*u*r-h*m*r-f*i*d+n*m*d+h*i*g-n*u*g)*b,t[2]=(a*m*r-f*o*r+f*i*l-n*m*l-a*i*g+n*o*g)*b,t[3]=(h*o*r-a*u*r-h*i*l+n*u*l+a*i*d-n*o*d)*b,t[4]=_*b,t[5]=(c*m*r-p*u*r+p*i*d-e*m*d-c*i*g+e*u*g)*b,t[6]=(p*o*r-s*m*r-p*i*l+e*m*l+s*i*g-e*o*g)*b,t[7]=(s*u*r-c*o*r+c*i*l-e*u*l-s*i*d+e*o*d)*b,t[8]=y*b,t[9]=(p*h*r-c*f*r-p*n*d+e*f*d+c*n*g-e*h*g)*b,t[10]=(s*f*r-p*a*r+p*n*l-e*f*l-s*n*g+e*a*g)*b,t[11]=(c*a*r-s*h*r-c*n*l+e*h*l+s*n*d-e*a*d)*b,t[12]=x*b,t[13]=(c*f*i-p*h*i+p*n*u-e*f*u-c*n*m+e*h*m)*b,t[14]=(p*a*i-s*f*i-p*n*o+e*f*o+s*n*m-e*a*m)*b,t[15]=(s*h*i-c*a*i+c*n*o-e*h*o-s*n*u+e*a*u)*b,this}scale(t){const e=this.elements,n=t.x,i=t.y,r=t.z;return e[0]*=n,e[4]*=i,e[8]*=r,e[1]*=n,e[5]*=i,e[9]*=r,e[2]*=n,e[6]*=i,e[10]*=r,e[3]*=n,e[7]*=i,e[11]*=r,this}getMaxScaleOnAxis(){const t=this.elements,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],n=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],i=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,n,i))}makeTranslation(t,e,n){return t.isVector3?this.set(1,0,0,t.x,0,1,0,t.y,0,0,1,t.z,0,0,0,1):this.set(1,0,0,t,0,1,0,e,0,0,1,n,0,0,0,1),this}makeRotationX(t){const e=Math.cos(t),n=Math.sin(t);return this.set(1,0,0,0,0,e,-n,0,0,n,e,0,0,0,0,1),this}makeRotationY(t){const e=Math.cos(t),n=Math.sin(t);return this.set(e,0,n,0,0,1,0,0,-n,0,e,0,0,0,0,1),this}makeRotationZ(t){const e=Math.cos(t),n=Math.sin(t);return this.set(e,-n,0,0,n,e,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(t,e){const n=Math.cos(e),i=Math.sin(e),r=1-n,s=t.x,a=t.y,o=t.z,l=r*s,c=r*a;return this.set(l*s+n,l*a-i*o,l*o+i*a,0,l*a+i*o,c*a+n,c*o-i*s,0,l*o-i*a,c*o+i*s,r*o*o+n,0,0,0,0,1),this}makeScale(t,e,n){return this.set(t,0,0,0,0,e,0,0,0,0,n,0,0,0,0,1),this}makeShear(t,e,n,i,r,s){return this.set(1,n,r,0,t,1,s,0,e,i,1,0,0,0,0,1),this}compose(t,e,n){const i=this.elements,r=e._x,s=e._y,a=e._z,o=e._w,l=r+r,c=s+s,h=a+a,u=r*l,d=r*c,p=r*h,f=s*c,m=s*h,g=a*h,v=o*l,_=o*c,y=o*h,x=n.x,M=n.y,b=n.z;return i[0]=(1-(f+g))*x,i[1]=(d+y)*x,i[2]=(p-_)*x,i[3]=0,i[4]=(d-y)*M,i[5]=(1-(u+g))*M,i[6]=(m+v)*M,i[7]=0,i[8]=(p+_)*b,i[9]=(m-v)*b,i[10]=(1-(u+f))*b,i[11]=0,i[12]=t.x,i[13]=t.y,i[14]=t.z,i[15]=1,this}decompose(t,e,n){const i=this.elements;let r=bn.set(i[0],i[1],i[2]).length();const s=bn.set(i[4],i[5],i[6]).length(),a=bn.set(i[8],i[9],i[10]).length();this.determinant()<0&&(r=-r),t.x=i[12],t.y=i[13],t.z=i[14],Sn.copy(this);const o=1/r,l=1/s,c=1/a;return Sn.elements[0]*=o,Sn.elements[1]*=o,Sn.elements[2]*=o,Sn.elements[4]*=l,Sn.elements[5]*=l,Sn.elements[6]*=l,Sn.elements[8]*=c,Sn.elements[9]*=c,Sn.elements[10]*=c,e.setFromRotationMatrix(Sn),n.x=r,n.y=s,n.z=a,this}makePerspective(t,e,n,i,r,s,a=2e3){const o=this.elements,l=2*r/(e-t),c=2*r/(n-i),h=(e+t)/(e-t),u=(n+i)/(n-i);let d,p;if(a===ne)d=-(s+r)/(s-r),p=-2*s*r/(s-r);else{if(a!==ie)throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: "+a);d=-s/(s-r),p=-s*r/(s-r)}return o[0]=l,o[4]=0,o[8]=h,o[12]=0,o[1]=0,o[5]=c,o[9]=u,o[13]=0,o[2]=0,o[6]=0,o[10]=d,o[14]=p,o[3]=0,o[7]=0,o[11]=-1,o[15]=0,this}makeOrthographic(t,e,n,i,r,s,a=2e3){const o=this.elements,l=1/(e-t),c=1/(n-i),h=1/(s-r),u=(e+t)*l,d=(n+i)*c;let p,f;if(a===ne)p=(s+r)*h,f=-2*h;else{if(a!==ie)throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: "+a);p=r*h,f=-1*h}return o[0]=2*l,o[4]=0,o[8]=0,o[12]=-u,o[1]=0,o[5]=2*c,o[9]=0,o[13]=-d,o[2]=0,o[6]=0,o[10]=f,o[14]=-p,o[3]=0,o[7]=0,o[11]=0,o[15]=1,this}equals(t){const e=this.elements,n=t.elements;for(let t=0;t<16;t++)if(e[t]!==n[t])return!1;return!0}fromArray(t,e=0){for(let n=0;n<16;n++)this.elements[n]=t[n+e];return this}toArray(t=[],e=0){const n=this.elements;return t[e]=n[0],t[e+1]=n[1],t[e+2]=n[2],t[e+3]=n[3],t[e+4]=n[4],t[e+5]=n[5],t[e+6]=n[6],t[e+7]=n[7],t[e+8]=n[8],t[e+9]=n[9],t[e+10]=n[10],t[e+11]=n[11],t[e+12]=n[12],t[e+13]=n[13],t[e+14]=n[14],t[e+15]=n[15],t}}const bn=new _e,Sn=new Mn,Tn=new _e(0,0,0),wn=new _e(1,1,1),En=new _e,An=new _e,Rn=new _e,Cn=new Mn,Pn=new ve;class In{constructor(t=0,e=0,n=0,i=In.DEFAULT_ORDER){this.isEuler=!0,this._x=t,this._y=e,this._z=n,this._order=i}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get order(){return this._order}set order(t){this._order=t,this._onChangeCallback()}set(t,e,n,i=this._order){return this._x=t,this._y=e,this._z=n,this._order=i,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(t){return this._x=t._x,this._y=t._y,this._z=t._z,this._order=t._order,this._onChangeCallback(),this}setFromRotationMatrix(t,e=this._order,n=!0){const i=t.elements,r=i[0],s=i[4],a=i[8],o=i[1],l=i[5],c=i[9],h=i[2],u=i[6],d=i[10];switch(e){case"XYZ":this._y=Math.asin(he(a,-1,1)),Math.abs(a)<.9999999?(this._x=Math.atan2(-c,d),this._z=Math.atan2(-s,r)):(this._x=Math.atan2(u,l),this._z=0);break;case"YXZ":this._x=Math.asin(-he(c,-1,1)),Math.abs(c)<.9999999?(this._y=Math.atan2(a,d),this._z=Math.atan2(o,l)):(this._y=Math.atan2(-h,r),this._z=0);break;case"ZXY":this._x=Math.asin(he(u,-1,1)),Math.abs(u)<.9999999?(this._y=Math.atan2(-h,d),this._z=Math.atan2(-s,l)):(this._y=0,this._z=Math.atan2(o,r));break;case"ZYX":this._y=Math.asin(-he(h,-1,1)),Math.abs(h)<.9999999?(this._x=Math.atan2(u,d),this._z=Math.atan2(o,r)):(this._x=0,this._z=Math.atan2(-s,l));break;case"YZX":this._z=Math.asin(he(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-c,l),this._y=Math.atan2(-h,r)):(this._x=0,this._y=Math.atan2(a,d));break;case"XZY":this._z=Math.asin(-he(s,-1,1)),Math.abs(s)<.9999999?(this._x=Math.atan2(u,l),this._y=Math.atan2(a,r)):(this._x=Math.atan2(-c,d),this._y=0);break;default:console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+e)}return this._order=e,!0===n&&this._onChangeCallback(),this}setFromQuaternion(t,e,n){return Cn.makeRotationFromQuaternion(t),this.setFromRotationMatrix(Cn,e,n)}setFromVector3(t,e=this._order){return this.set(t.x,t.y,t.z,e)}reorder(t){return Pn.setFromEuler(this),this.setFromQuaternion(Pn,t)}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._order===this._order}fromArray(t){return this._x=t[0],this._y=t[1],this._z=t[2],void 0!==t[3]&&(this._order=t[3]),this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._order,t}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}}In.DEFAULT_ORDER="XYZ";class Ln{constructor(){this.mask=1}set(t){this.mask=1<>>0}enable(t){this.mask|=1<1){for(let t=0;t1){for(let t=0;t0&&(i.userData=this.userData),i.layers=this.layers.mask,i.matrix=this.matrix.toArray(),i.up=this.up.toArray(),!1===this.matrixAutoUpdate&&(i.matrixAutoUpdate=!1),this.isInstancedMesh&&(i.type="InstancedMesh",i.count=this.count,i.instanceMatrix=this.instanceMatrix.toJSON(),null!==this.instanceColor&&(i.instanceColor=this.instanceColor.toJSON())),this.isBatchedMesh&&(i.type="BatchedMesh",i.perObjectFrustumCulled=this.perObjectFrustumCulled,i.sortObjects=this.sortObjects,i.drawRanges=this._drawRanges,i.reservedRanges=this._reservedRanges,i.geometryInfo=this._geometryInfo.map(t=>({...t,boundingBox:t.boundingBox?t.boundingBox.toJSON():void 0,boundingSphere:t.boundingSphere?t.boundingSphere.toJSON():void 0})),i.instanceInfo=this._instanceInfo.map(t=>({...t})),i.availableInstanceIds=this._availableInstanceIds.slice(),i.availableGeometryIds=this._availableGeometryIds.slice(),i.nextIndexStart=this._nextIndexStart,i.nextVertexStart=this._nextVertexStart,i.geometryCount=this._geometryCount,i.maxInstanceCount=this._maxInstanceCount,i.maxVertexCount=this._maxVertexCount,i.maxIndexCount=this._maxIndexCount,i.geometryInitialized=this._geometryInitialized,i.matricesTexture=this._matricesTexture.toJSON(t),i.indirectTexture=this._indirectTexture.toJSON(t),null!==this._colorsTexture&&(i.colorsTexture=this._colorsTexture.toJSON(t)),null!==this.boundingSphere&&(i.boundingSphere=this.boundingSphere.toJSON()),null!==this.boundingBox&&(i.boundingBox=this.boundingBox.toJSON())),this.isScene)this.background&&(this.background.isColor?i.background=this.background.toJSON():this.background.isTexture&&(i.background=this.background.toJSON(t).uuid)),this.environment&&this.environment.isTexture&&!0!==this.environment.isRenderTargetTexture&&(i.environment=this.environment.toJSON(t).uuid);else if(this.isMesh||this.isLine||this.isPoints){i.geometry=r(t.geometries,this.geometry);const e=this.geometry.parameters;if(void 0!==e&&void 0!==e.shapes){const n=e.shapes;if(Array.isArray(n))for(let e=0,i=n.length;e0){i.children=[];for(let e=0;e0){i.animations=[];for(let e=0;e0&&(n.geometries=e),i.length>0&&(n.materials=i),r.length>0&&(n.textures=r),a.length>0&&(n.images=a),o.length>0&&(n.shapes=o),l.length>0&&(n.skeletons=l),c.length>0&&(n.animations=c),h.length>0&&(n.nodes=h)}return n.object=i,n;function s(t){const e=[];for(const n in t){const i=t[n];delete i.metadata,e.push(i)}return e}}clone(t){return(new this.constructor).copy(this,t)}copy(t,e=!0){if(this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.rotation.order=t.rotation.order,this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldAutoUpdate=t.matrixWorldAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.animations=t.animations.slice(),this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(let e=0;e0?i.multiplyScalar(1/Math.sqrt(r)):i.set(0,0,0)}static getBarycoord(t,e,n,i,r){Kn.subVectors(i,e),Jn.subVectors(n,e),Zn.subVectors(t,e);const s=Kn.dot(Kn),a=Kn.dot(Jn),o=Kn.dot(Zn),l=Jn.dot(Jn),c=Jn.dot(Zn),h=s*l-a*a;if(0===h)return r.set(0,0,0),null;const u=1/h,d=(l*o-a*c)*u,p=(s*c-a*o)*u;return r.set(1-d-p,p,d)}static containsPoint(t,e,n,i){return null!==this.getBarycoord(t,e,n,i,$n)&&$n.x>=0&&$n.y>=0&&$n.x+$n.y<=1}static getInterpolation(t,e,n,i,r,s,a,o){return null===this.getBarycoord(t,e,n,i,$n)?(o.x=0,o.y=0,"z"in o&&(o.z=0),"w"in o&&(o.w=0),null):(o.setScalar(0),o.addScaledVector(r,$n.x),o.addScaledVector(s,$n.y),o.addScaledVector(a,$n.z),o)}static getInterpolatedAttribute(t,e,n,i,r,s){return si.setScalar(0),ai.setScalar(0),oi.setScalar(0),si.fromBufferAttribute(t,e),ai.fromBufferAttribute(t,n),oi.fromBufferAttribute(t,i),s.setScalar(0),s.addScaledVector(si,r.x),s.addScaledVector(ai,r.y),s.addScaledVector(oi,r.z),s}static isFrontFacing(t,e,n,i){return Kn.subVectors(n,e),Jn.subVectors(t,e),Kn.cross(Jn).dot(i)<0}set(t,e,n){return this.a.copy(t),this.b.copy(e),this.c.copy(n),this}setFromPointsAndIndices(t,e,n,i){return this.a.copy(t[e]),this.b.copy(t[n]),this.c.copy(t[i]),this}setFromAttributeAndIndices(t,e,n,i){return this.a.fromBufferAttribute(t,e),this.b.fromBufferAttribute(t,n),this.c.fromBufferAttribute(t,i),this}clone(){return(new this.constructor).copy(this)}copy(t){return this.a.copy(t.a),this.b.copy(t.b),this.c.copy(t.c),this}getArea(){return Kn.subVectors(this.c,this.b),Jn.subVectors(this.a,this.b),.5*Kn.cross(Jn).length()}getMidpoint(t){return t.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return li.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return li.getBarycoord(t,this.a,this.b,this.c,e)}getInterpolation(t,e,n,i,r){return li.getInterpolation(t,this.a,this.b,this.c,e,n,i,r)}containsPoint(t){return li.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return li.isFrontFacing(this.a,this.b,this.c,t)}intersectsBox(t){return t.intersectsTriangle(this)}closestPointToPoint(t,e){const n=this.a,i=this.b,r=this.c;let s,a;Qn.subVectors(i,n),ti.subVectors(r,n),ni.subVectors(t,n);const o=Qn.dot(ni),l=ti.dot(ni);if(o<=0&&l<=0)return e.copy(n);ii.subVectors(t,i);const c=Qn.dot(ii),h=ti.dot(ii);if(c>=0&&h<=c)return e.copy(i);const u=o*h-c*l;if(u<=0&&o>=0&&c<=0)return s=o/(o-c),e.copy(n).addScaledVector(Qn,s);ri.subVectors(t,r);const d=Qn.dot(ri),p=ti.dot(ri);if(p>=0&&d<=p)return e.copy(r);const f=d*l-o*p;if(f<=0&&l>=0&&p<=0)return a=l/(l-p),e.copy(n).addScaledVector(ti,a);const m=c*p-d*h;if(m<=0&&h-c>=0&&d-p>=0)return ei.subVectors(r,i),a=(h-c)/(h-c+(d-p)),e.copy(i).addScaledVector(ei,a);const g=1/(m+f+u);return s=f*g,a=u*g,e.copy(n).addScaledVector(Qn,s).addScaledVector(ti,a)}equals(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}const ci={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},hi={h:0,s:0,l:0},ui={h:0,s:0,l:0};function di(t,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+6*(e-t)*(2/3-n):t}class pi{constructor(t,e,n){return this.isColor=!0,this.r=1,this.g=1,this.b=1,this.set(t,e,n)}set(t,e,n){if(void 0===e&&void 0===n){const e=t;e&&e.isColor?this.copy(e):"number"==typeof e?this.setHex(e):"string"==typeof e&&this.setStyle(e)}else this.setRGB(t,e,n);return this}setScalar(t){return this.r=t,this.g=t,this.b=t,this}setHex(t,e=Ht){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,Ie.colorSpaceToWorking(this,e),this}setRGB(t,e,n,i=Ie.workingColorSpace){return this.r=t,this.g=e,this.b=n,Ie.colorSpaceToWorking(this,i),this}setHSL(t,e,n,i=Ie.workingColorSpace){if(t=ue(t,1),e=he(e,0,1),n=he(n,0,1),0===e)this.r=this.g=this.b=n;else{const i=n<=.5?n*(1+e):n+e-n*e,r=2*n-i;this.r=di(r,i,t+1/3),this.g=di(r,i,t),this.b=di(r,i,t-1/3)}return Ie.colorSpaceToWorking(this,i),this}setStyle(t,e=Ht){function n(e){void 0!==e&&parseFloat(e)<1&&console.warn("THREE.Color: Alpha component of "+t+" will be ignored.")}let i;if(i=/^(\w+)\(([^\)]*)\)/.exec(t)){let r;const s=i[1],a=i[2];switch(s){case"rgb":case"rgba":if(r=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return n(r[4]),this.setRGB(Math.min(255,parseInt(r[1],10))/255,Math.min(255,parseInt(r[2],10))/255,Math.min(255,parseInt(r[3],10))/255,e);if(r=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return n(r[4]),this.setRGB(Math.min(100,parseInt(r[1],10))/100,Math.min(100,parseInt(r[2],10))/100,Math.min(100,parseInt(r[3],10))/100,e);break;case"hsl":case"hsla":if(r=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return n(r[4]),this.setHSL(parseFloat(r[1])/360,parseFloat(r[2])/100,parseFloat(r[3])/100,e);break;default:console.warn("THREE.Color: Unknown color model "+t)}}else if(i=/^\#([A-Fa-f\d]+)$/.exec(t)){const n=i[1],r=n.length;if(3===r)return this.setRGB(parseInt(n.charAt(0),16)/15,parseInt(n.charAt(1),16)/15,parseInt(n.charAt(2),16)/15,e);if(6===r)return this.setHex(parseInt(n,16),e);console.warn("THREE.Color: Invalid hex color "+t)}else if(t&&t.length>0)return this.setColorName(t,e);return this}setColorName(t,e=Ht){const n=ci[t.toLowerCase()];return void 0!==n?this.setHex(n,e):console.warn("THREE.Color: Unknown color "+t),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(t){return this.r=t.r,this.g=t.g,this.b=t.b,this}copySRGBToLinear(t){return this.r=Le(t.r),this.g=Le(t.g),this.b=Le(t.b),this}copyLinearToSRGB(t){return this.r=Ne(t.r),this.g=Ne(t.g),this.b=Ne(t.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(t=Ht){return Ie.workingToColorSpace(fi.copy(this),t),65536*Math.round(he(255*fi.r,0,255))+256*Math.round(he(255*fi.g,0,255))+Math.round(he(255*fi.b,0,255))}getHexString(t=Ht){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e=Ie.workingColorSpace){Ie.workingToColorSpace(fi.copy(this),e);const n=fi.r,i=fi.g,r=fi.b,s=Math.max(n,i,r),a=Math.min(n,i,r);let o,l;const c=(a+s)/2;if(a===s)o=0,l=0;else{const t=s-a;switch(l=c<=.5?t/(s+a):t/(2-s-a),s){case n:o=(i-r)/t+(i0!=t>0&&this.version++,this._alphaTest=t}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(t){if(void 0!==t)for(const e in t){const n=t[e];if(void 0===n){console.warn(`THREE.Material: parameter '${e}' has value of undefined.`);continue}const i=this[e];void 0!==i?i&&i.isColor?i.set(n):i&&i.isVector3&&n&&n.isVector3?i.copy(n):this[e]=n:console.warn(`THREE.Material: '${e}' is not a property of THREE.${this.type}.`)}}toJSON(t){const e=void 0===t||"string"==typeof t;e&&(t={textures:{},images:{}});const n={metadata:{version:4.7,type:"Material",generator:"Material.toJSON"}};function i(t){const e=[];for(const n in t){const i=t[n];delete i.metadata,e.push(i)}return e}if(n.uuid=this.uuid,n.type=this.type,""!==this.name&&(n.name=this.name),this.color&&this.color.isColor&&(n.color=this.color.getHex()),void 0!==this.roughness&&(n.roughness=this.roughness),void 0!==this.metalness&&(n.metalness=this.metalness),void 0!==this.sheen&&(n.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(n.sheenColor=this.sheenColor.getHex()),void 0!==this.sheenRoughness&&(n.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(n.emissive=this.emissive.getHex()),void 0!==this.emissiveIntensity&&1!==this.emissiveIntensity&&(n.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(n.specular=this.specular.getHex()),void 0!==this.specularIntensity&&(n.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(n.specularColor=this.specularColor.getHex()),void 0!==this.shininess&&(n.shininess=this.shininess),void 0!==this.clearcoat&&(n.clearcoat=this.clearcoat),void 0!==this.clearcoatRoughness&&(n.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(n.clearcoatMap=this.clearcoatMap.toJSON(t).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(n.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(t).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(n.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(t).uuid,n.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),void 0!==this.dispersion&&(n.dispersion=this.dispersion),void 0!==this.iridescence&&(n.iridescence=this.iridescence),void 0!==this.iridescenceIOR&&(n.iridescenceIOR=this.iridescenceIOR),void 0!==this.iridescenceThicknessRange&&(n.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(n.iridescenceMap=this.iridescenceMap.toJSON(t).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(n.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(t).uuid),void 0!==this.anisotropy&&(n.anisotropy=this.anisotropy),void 0!==this.anisotropyRotation&&(n.anisotropyRotation=this.anisotropyRotation),this.anisotropyMap&&this.anisotropyMap.isTexture&&(n.anisotropyMap=this.anisotropyMap.toJSON(t).uuid),this.map&&this.map.isTexture&&(n.map=this.map.toJSON(t).uuid),this.matcap&&this.matcap.isTexture&&(n.matcap=this.matcap.toJSON(t).uuid),this.alphaMap&&this.alphaMap.isTexture&&(n.alphaMap=this.alphaMap.toJSON(t).uuid),this.lightMap&&this.lightMap.isTexture&&(n.lightMap=this.lightMap.toJSON(t).uuid,n.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(n.aoMap=this.aoMap.toJSON(t).uuid,n.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(n.bumpMap=this.bumpMap.toJSON(t).uuid,n.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(n.normalMap=this.normalMap.toJSON(t).uuid,n.normalMapType=this.normalMapType,n.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(n.displacementMap=this.displacementMap.toJSON(t).uuid,n.displacementScale=this.displacementScale,n.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(n.roughnessMap=this.roughnessMap.toJSON(t).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(n.metalnessMap=this.metalnessMap.toJSON(t).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(n.emissiveMap=this.emissiveMap.toJSON(t).uuid),this.specularMap&&this.specularMap.isTexture&&(n.specularMap=this.specularMap.toJSON(t).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(n.specularIntensityMap=this.specularIntensityMap.toJSON(t).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(n.specularColorMap=this.specularColorMap.toJSON(t).uuid),this.envMap&&this.envMap.isTexture&&(n.envMap=this.envMap.toJSON(t).uuid,void 0!==this.combine&&(n.combine=this.combine)),void 0!==this.envMapRotation&&(n.envMapRotation=this.envMapRotation.toArray()),void 0!==this.envMapIntensity&&(n.envMapIntensity=this.envMapIntensity),void 0!==this.reflectivity&&(n.reflectivity=this.reflectivity),void 0!==this.refractionRatio&&(n.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(n.gradientMap=this.gradientMap.toJSON(t).uuid),void 0!==this.transmission&&(n.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(n.transmissionMap=this.transmissionMap.toJSON(t).uuid),void 0!==this.thickness&&(n.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(n.thicknessMap=this.thicknessMap.toJSON(t).uuid),void 0!==this.attenuationDistance&&this.attenuationDistance!==1/0&&(n.attenuationDistance=this.attenuationDistance),void 0!==this.attenuationColor&&(n.attenuationColor=this.attenuationColor.getHex()),void 0!==this.size&&(n.size=this.size),null!==this.shadowSide&&(n.shadowSide=this.shadowSide),void 0!==this.sizeAttenuation&&(n.sizeAttenuation=this.sizeAttenuation),1!==this.blending&&(n.blending=this.blending),0!==this.side&&(n.side=this.side),!0===this.vertexColors&&(n.vertexColors=!0),this.opacity<1&&(n.opacity=this.opacity),!0===this.transparent&&(n.transparent=!0),204!==this.blendSrc&&(n.blendSrc=this.blendSrc),205!==this.blendDst&&(n.blendDst=this.blendDst),this.blendEquation!==r&&(n.blendEquation=this.blendEquation),null!==this.blendSrcAlpha&&(n.blendSrcAlpha=this.blendSrcAlpha),null!==this.blendDstAlpha&&(n.blendDstAlpha=this.blendDstAlpha),null!==this.blendEquationAlpha&&(n.blendEquationAlpha=this.blendEquationAlpha),this.blendColor&&this.blendColor.isColor&&(n.blendColor=this.blendColor.getHex()),0!==this.blendAlpha&&(n.blendAlpha=this.blendAlpha),3!==this.depthFunc&&(n.depthFunc=this.depthFunc),!1===this.depthTest&&(n.depthTest=this.depthTest),!1===this.depthWrite&&(n.depthWrite=this.depthWrite),!1===this.colorWrite&&(n.colorWrite=this.colorWrite),255!==this.stencilWriteMask&&(n.stencilWriteMask=this.stencilWriteMask),519!==this.stencilFunc&&(n.stencilFunc=this.stencilFunc),0!==this.stencilRef&&(n.stencilRef=this.stencilRef),255!==this.stencilFuncMask&&(n.stencilFuncMask=this.stencilFuncMask),this.stencilFail!==jt&&(n.stencilFail=this.stencilFail),this.stencilZFail!==jt&&(n.stencilZFail=this.stencilZFail),this.stencilZPass!==jt&&(n.stencilZPass=this.stencilZPass),!0===this.stencilWrite&&(n.stencilWrite=this.stencilWrite),void 0!==this.rotation&&0!==this.rotation&&(n.rotation=this.rotation),!0===this.polygonOffset&&(n.polygonOffset=!0),0!==this.polygonOffsetFactor&&(n.polygonOffsetFactor=this.polygonOffsetFactor),0!==this.polygonOffsetUnits&&(n.polygonOffsetUnits=this.polygonOffsetUnits),void 0!==this.linewidth&&1!==this.linewidth&&(n.linewidth=this.linewidth),void 0!==this.dashSize&&(n.dashSize=this.dashSize),void 0!==this.gapSize&&(n.gapSize=this.gapSize),void 0!==this.scale&&(n.scale=this.scale),!0===this.dithering&&(n.dithering=!0),this.alphaTest>0&&(n.alphaTest=this.alphaTest),!0===this.alphaHash&&(n.alphaHash=!0),!0===this.alphaToCoverage&&(n.alphaToCoverage=!0),!0===this.premultipliedAlpha&&(n.premultipliedAlpha=!0),!0===this.forceSinglePass&&(n.forceSinglePass=!0),!0===this.wireframe&&(n.wireframe=!0),this.wireframeLinewidth>1&&(n.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(n.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(n.wireframeLinejoin=this.wireframeLinejoin),!0===this.flatShading&&(n.flatShading=!0),!1===this.visible&&(n.visible=!1),!1===this.toneMapped&&(n.toneMapped=!1),!1===this.fog&&(n.fog=!1),Object.keys(this.userData).length>0&&(n.userData=this.userData),e){const e=i(t.textures),r=i(t.images);e.length>0&&(n.textures=e),r.length>0&&(n.images=r)}return n}clone(){return(new this.constructor).copy(this)}copy(t){this.name=t.name,this.blending=t.blending,this.side=t.side,this.vertexColors=t.vertexColors,this.opacity=t.opacity,this.transparent=t.transparent,this.blendSrc=t.blendSrc,this.blendDst=t.blendDst,this.blendEquation=t.blendEquation,this.blendSrcAlpha=t.blendSrcAlpha,this.blendDstAlpha=t.blendDstAlpha,this.blendEquationAlpha=t.blendEquationAlpha,this.blendColor.copy(t.blendColor),this.blendAlpha=t.blendAlpha,this.depthFunc=t.depthFunc,this.depthTest=t.depthTest,this.depthWrite=t.depthWrite,this.stencilWriteMask=t.stencilWriteMask,this.stencilFunc=t.stencilFunc,this.stencilRef=t.stencilRef,this.stencilFuncMask=t.stencilFuncMask,this.stencilFail=t.stencilFail,this.stencilZFail=t.stencilZFail,this.stencilZPass=t.stencilZPass,this.stencilWrite=t.stencilWrite;const e=t.clippingPlanes;let n=null;if(null!==e){const t=e.length;n=new Array(t);for(let i=0;i!==t;++i)n[i]=e[i].clone()}return this.clippingPlanes=n,this.clipIntersection=t.clipIntersection,this.clipShadows=t.clipShadows,this.shadowSide=t.shadowSide,this.colorWrite=t.colorWrite,this.precision=t.precision,this.polygonOffset=t.polygonOffset,this.polygonOffsetFactor=t.polygonOffsetFactor,this.polygonOffsetUnits=t.polygonOffsetUnits,this.dithering=t.dithering,this.alphaTest=t.alphaTest,this.alphaHash=t.alphaHash,this.alphaToCoverage=t.alphaToCoverage,this.premultipliedAlpha=t.premultipliedAlpha,this.forceSinglePass=t.forceSinglePass,this.visible=t.visible,this.toneMapped=t.toneMapped,this.userData=JSON.parse(JSON.stringify(t.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(t){!0===t&&this.version++}}class vi extends gi{constructor(t){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new pi(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new In,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}const _i=new _e,yi=new ge;let xi=0;class Mi{constructor(t,e,n=!1){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,Object.defineProperty(this,"id",{value:xi++}),this.name="",this.array=t,this.itemSize=e,this.count=void 0!==t?t.length/e:0,this.normalized=n,this.usage=te,this.updateRanges=[],this.gpuType=Y,this.version=0}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}copy(t){return this.name=t.name,this.array=new t.array.constructor(t.array),this.itemSize=t.itemSize,this.count=t.count,this.normalized=t.normalized,this.usage=t.usage,this.gpuType=t.gpuType,this}copyAt(t,e,n){t*=this.itemSize,n*=e.itemSize;for(let i=0,r=this.itemSize;ie.count&&console.warn("THREE.BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."),e.needsUpdate=!0}return this}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new qe);const t=this.attributes.position,e=this.morphAttributes.position;if(t&&t.isGLBufferAttribute)return console.error("THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.",this),void this.boundingBox.set(new _e(-1/0,-1/0,-1/0),new _e(1/0,1/0,1/0));if(void 0!==t){if(this.boundingBox.setFromBufferAttribute(t),e)for(let t=0,n=e.length;t0&&(t.userData=this.userData),void 0!==this.parameters){const e=this.parameters;for(const n in e)void 0!==e[n]&&(t[n]=e[n]);return t}t.data={attributes:{}};const e=this.index;null!==e&&(t.data.index={type:e.array.constructor.name,array:Array.prototype.slice.call(e.array)});const n=this.attributes;for(const e in n){const i=n[e];t.data.attributes[e]=i.toJSON(t.data)}const i={};let r=!1;for(const e in this.morphAttributes){const n=this.morphAttributes[e],s=[];for(let e=0,i=n.length;e0&&(i[e]=s,r=!0)}r&&(t.data.morphAttributes=i,t.data.morphTargetsRelative=this.morphTargetsRelative);const s=this.groups;s.length>0&&(t.data.groups=JSON.parse(JSON.stringify(s)));const a=this.boundingSphere;return null!==a&&(t.data.boundingSphere=a.toJSON()),t}clone(){return(new this.constructor).copy(this)}copy(t){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const e={};this.name=t.name;const n=t.index;null!==n&&this.setIndex(n.clone());const i=t.attributes;for(const t in i){const n=i[t];this.setAttribute(t,n.clone(e))}const r=t.morphAttributes;for(const t in r){const n=[],i=r[t];for(let t=0,r=i.length;t0){const n=t[e[0]];if(void 0!==n){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=n.length;t(t.far-t.near)**2)return}Ni.copy(r).invert(),Di.copy(t.ray).applyMatrix4(Ni),null!==n.boundingBox&&!1===Di.intersectsBox(n.boundingBox)||this._computeIntersections(t,e,Di)}}_computeIntersections(t,e,n){let i;const r=this.geometry,s=this.material,a=r.index,o=r.attributes.position,l=r.attributes.uv,c=r.attributes.uv1,h=r.attributes.normal,u=r.groups,d=r.drawRange;if(null!==a)if(Array.isArray(s))for(let r=0,o=u.length;rn.far?null:{distance:c,point:Gi.clone(),object:t}}(t,e,n,i,Fi,ki,Bi,Vi);if(h){const t=new _e;li.getBarycoord(Vi,Fi,ki,Bi,t),r&&(h.uv=li.getInterpolatedAttribute(r,o,l,c,t,new ge)),s&&(h.uv1=li.getInterpolatedAttribute(s,o,l,c,t,new ge)),a&&(h.normal=li.getInterpolatedAttribute(a,o,l,c,t,new _e),h.normal.dot(i.direction)>0&&h.normal.multiplyScalar(-1));const e={a:o,b:l,c,normal:new _e,materialIndex:0};li.getNormal(Fi,ki,Bi,e.normal),h.face=e,h.barycoord=t}return h}class Xi extends Li{constructor(t=1,e=1,n=1,i=1,r=1,s=1){super(),this.type="BoxGeometry",this.parameters={width:t,height:e,depth:n,widthSegments:i,heightSegments:r,depthSegments:s};const a=this;i=Math.floor(i),r=Math.floor(r),s=Math.floor(s);const o=[],l=[],c=[],h=[];let u=0,d=0;function p(t,e,n,i,r,s,p,f,m,g,v){const _=s/m,y=p/g,x=s/2,M=p/2,b=f/2,S=m+1,T=g+1;let w=0,E=0;const A=new _e;for(let s=0;s0?1:-1,c.push(A.x,A.y,A.z),h.push(o/m),h.push(1-s/g),w+=1}}for(let t=0;t0&&(e.defines=this.defines),e.vertexShader=this.vertexShader,e.fragmentShader=this.fragmentShader,e.lights=this.lights,e.clipping=this.clipping;const n={};for(const t in this.extensions)!0===this.extensions[t]&&(n[t]=!0);return Object.keys(n).length>0&&(e.extensions=n),e}}class $i extends Yn{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new Mn,this.projectionMatrix=new Mn,this.projectionMatrixInverse=new Mn,this.coordinateSystem=ne}copy(t,e){return super.copy(t,e),this.matrixWorldInverse.copy(t.matrixWorldInverse),this.projectionMatrix.copy(t.projectionMatrix),this.projectionMatrixInverse.copy(t.projectionMatrixInverse),this.coordinateSystem=t.coordinateSystem,this}getWorldDirection(t){return super.getWorldDirection(t).negate()}updateMatrixWorld(t){super.updateMatrixWorld(t),this.matrixWorldInverse.copy(this.matrixWorld).invert()}updateWorldMatrix(t,e){super.updateWorldMatrix(t,e),this.matrixWorldInverse.copy(this.matrixWorld).invert()}clone(){return(new this.constructor).copy(this)}}const Qi=new _e,tr=new ge,er=new ge;class nr extends $i{constructor(t=50,e=1,n=.1,i=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=t,this.zoom=1,this.near=n,this.far=i,this.focus=10,this.aspect=e,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(t,e){return super.copy(t,e),this.fov=t.fov,this.zoom=t.zoom,this.near=t.near,this.far=t.far,this.focus=t.focus,this.aspect=t.aspect,this.view=null===t.view?null:Object.assign({},t.view),this.filmGauge=t.filmGauge,this.filmOffset=t.filmOffset,this}setFocalLength(t){const e=.5*this.getFilmHeight()/t;this.fov=2*le*Math.atan(e),this.updateProjectionMatrix()}getFocalLength(){const t=Math.tan(.5*oe*this.fov);return.5*this.getFilmHeight()/t}getEffectiveFOV(){return 2*le*Math.atan(Math.tan(.5*oe*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}getViewBounds(t,e,n){Qi.set(-1,-1,.5).applyMatrix4(this.projectionMatrixInverse),e.set(Qi.x,Qi.y).multiplyScalar(-t/Qi.z),Qi.set(1,1,.5).applyMatrix4(this.projectionMatrixInverse),n.set(Qi.x,Qi.y).multiplyScalar(-t/Qi.z)}getViewSize(t,e){return this.getViewBounds(t,tr,er),e.subVectors(er,tr)}setViewOffset(t,e,n,i,r,s){this.aspect=t/e,null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=t,this.view.fullHeight=e,this.view.offsetX=n,this.view.offsetY=i,this.view.width=r,this.view.height=s,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const t=this.near;let e=t*Math.tan(.5*oe*this.fov)/this.zoom,n=2*e,i=this.aspect*n,r=-.5*i;const s=this.view;if(null!==this.view&&this.view.enabled){const t=s.fullWidth,a=s.fullHeight;r+=s.offsetX*i/t,e-=s.offsetY*n/a,i*=s.width/t,n*=s.height/a}const a=this.filmOffset;0!==a&&(r+=t*a/this.getFilmWidth()),this.projectionMatrix.makePerspective(r,r+i,e,e-n,t,this.far,this.coordinateSystem),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(t){const e=super.toJSON(t);return e.object.fov=this.fov,e.object.zoom=this.zoom,e.object.near=this.near,e.object.far=this.far,e.object.focus=this.focus,e.object.aspect=this.aspect,null!==this.view&&(e.object.view=Object.assign({},this.view)),e.object.filmGauge=this.filmGauge,e.object.filmOffset=this.filmOffset,e}}const ir=-90;class rr extends Yn{constructor(t,e,n){super(),this.type="CubeCamera",this.renderTarget=n,this.coordinateSystem=null,this.activeMipmapLevel=0;const i=new nr(ir,1,t,e);i.layers=this.layers,this.add(i);const r=new nr(ir,1,t,e);r.layers=this.layers,this.add(r);const s=new nr(ir,1,t,e);s.layers=this.layers,this.add(s);const a=new nr(ir,1,t,e);a.layers=this.layers,this.add(a);const o=new nr(ir,1,t,e);o.layers=this.layers,this.add(o);const l=new nr(ir,1,t,e);l.layers=this.layers,this.add(l)}updateCoordinateSystem(){const t=this.coordinateSystem,e=this.children.concat(),[n,i,r,s,a,o]=e;for(const t of e)this.remove(t);if(t===ne)n.up.set(0,1,0),n.lookAt(1,0,0),i.up.set(0,1,0),i.lookAt(-1,0,0),r.up.set(0,0,-1),r.lookAt(0,1,0),s.up.set(0,0,1),s.lookAt(0,-1,0),a.up.set(0,1,0),a.lookAt(0,0,1),o.up.set(0,1,0),o.lookAt(0,0,-1);else{if(t!==ie)throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: "+t);n.up.set(0,-1,0),n.lookAt(-1,0,0),i.up.set(0,-1,0),i.lookAt(1,0,0),r.up.set(0,0,1),r.lookAt(0,1,0),s.up.set(0,0,-1),s.lookAt(0,-1,0),a.up.set(0,-1,0),a.lookAt(0,0,1),o.up.set(0,-1,0),o.lookAt(0,0,-1)}for(const t of e)this.add(t),t.updateMatrixWorld()}update(t,e){null===this.parent&&this.updateMatrixWorld();const{renderTarget:n,activeMipmapLevel:i}=this;this.coordinateSystem!==t.coordinateSystem&&(this.coordinateSystem=t.coordinateSystem,this.updateCoordinateSystem());const[r,s,a,o,l,c]=this.children,h=t.getRenderTarget(),u=t.getActiveCubeFace(),d=t.getActiveMipmapLevel(),p=t.xr.enabled;t.xr.enabled=!1;const f=n.texture.generateMipmaps;n.texture.generateMipmaps=!1,t.setRenderTarget(n,0,i),t.render(e,r),t.setRenderTarget(n,1,i),t.render(e,s),t.setRenderTarget(n,2,i),t.render(e,a),t.setRenderTarget(n,3,i),t.render(e,o),t.setRenderTarget(n,4,i),t.render(e,l),n.texture.generateMipmaps=f,t.setRenderTarget(n,5,i),t.render(e,c),t.setRenderTarget(h,u,d),t.xr.enabled=p,n.texture.needsPMREMUpdate=!0}}class sr extends He{constructor(t=[],e=301,n,i,r,s,a,o,l,c){super(t,e,n,i,r,s,a,o,l,c),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(t){this.image=t}}class ar extends We{constructor(t=1,e={}){super(t,t,e),this.isWebGLCubeRenderTarget=!0;const n={width:t,height:t,depth:1},i=[n,n,n,n,n,n];this.texture=new sr(i),this._setTextureOptions(e),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(t,e){this.texture.type=e.type,this.texture.colorSpace=e.colorSpace,this.texture.generateMipmaps=e.generateMipmaps,this.texture.minFilter=e.minFilter,this.texture.magFilter=e.magFilter;const n={tEquirect:{value:null}},i="\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t",r="\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t",s=new Xi(5,5,5),a=new Zi({name:"CubemapFromEquirect",uniforms:qi(n),vertexShader:i,fragmentShader:r,side:1,blending:0});a.uniforms.tEquirect.value=e;const o=new Wi(s,a),l=e.minFilter;return e.minFilter===G&&(e.minFilter=H),new rr(1,10,this).update(t,o),e.minFilter=l,o.geometry.dispose(),o.material.dispose(),this}clear(t,e=!0,n=!0,i=!0){const r=t.getRenderTarget();for(let r=0;r<6;r++)t.setRenderTarget(this,r),t.clear(e,n,i);t.setRenderTarget(r)}}class or extends Yn{constructor(){super(),this.isGroup=!0,this.type="Group"}}const lr={type:"move"};class cr{constructor(){this._targetRay=null,this._grip=null,this._hand=null}getHandSpace(){return null===this._hand&&(this._hand=new or,this._hand.matrixAutoUpdate=!1,this._hand.visible=!1,this._hand.joints={},this._hand.inputState={pinching:!1}),this._hand}getTargetRaySpace(){return null===this._targetRay&&(this._targetRay=new or,this._targetRay.matrixAutoUpdate=!1,this._targetRay.visible=!1,this._targetRay.hasLinearVelocity=!1,this._targetRay.linearVelocity=new _e,this._targetRay.hasAngularVelocity=!1,this._targetRay.angularVelocity=new _e),this._targetRay}getGripSpace(){return null===this._grip&&(this._grip=new or,this._grip.matrixAutoUpdate=!1,this._grip.visible=!1,this._grip.hasLinearVelocity=!1,this._grip.linearVelocity=new _e,this._grip.hasAngularVelocity=!1,this._grip.angularVelocity=new _e),this._grip}dispatchEvent(t){return null!==this._targetRay&&this._targetRay.dispatchEvent(t),null!==this._grip&&this._grip.dispatchEvent(t),null!==this._hand&&this._hand.dispatchEvent(t),this}connect(t){if(t&&t.hand){const e=this._hand;if(e)for(const n of t.hand.values())this._getHandJoint(e,n)}return this.dispatchEvent({type:"connected",data:t}),this}disconnect(t){return this.dispatchEvent({type:"disconnected",data:t}),null!==this._targetRay&&(this._targetRay.visible=!1),null!==this._grip&&(this._grip.visible=!1),null!==this._hand&&(this._hand.visible=!1),this}update(t,e,n){let i=null,r=null,s=null;const a=this._targetRay,o=this._grip,l=this._hand;if(t&&"visible-blurred"!==e.session.visibilityState){if(l&&t.hand){s=!0;for(const i of t.hand.values()){const t=e.getJointPose(i,n),r=this._getHandJoint(l,i);null!==t&&(r.matrix.fromArray(t.transform.matrix),r.matrix.decompose(r.position,r.rotation,r.scale),r.matrixWorldNeedsUpdate=!0,r.jointRadius=t.radius),r.visible=null!==t}const i=l.joints["index-finger-tip"],r=l.joints["thumb-tip"],a=i.position.distanceTo(r.position),o=.02,c=.005;l.inputState.pinching&&a>o+c?(l.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:t.handedness,target:this})):!l.inputState.pinching&&a<=o-c&&(l.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:t.handedness,target:this}))}else null!==o&&t.gripSpace&&(r=e.getPose(t.gripSpace,n),null!==r&&(o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),o.matrixWorldNeedsUpdate=!0,r.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(r.linearVelocity)):o.hasLinearVelocity=!1,r.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(r.angularVelocity)):o.hasAngularVelocity=!1));null!==a&&(i=e.getPose(t.targetRaySpace,n),null===i&&null!==r&&(i=r),null!==i&&(a.matrix.fromArray(i.transform.matrix),a.matrix.decompose(a.position,a.rotation,a.scale),a.matrixWorldNeedsUpdate=!0,i.linearVelocity?(a.hasLinearVelocity=!0,a.linearVelocity.copy(i.linearVelocity)):a.hasLinearVelocity=!1,i.angularVelocity?(a.hasAngularVelocity=!0,a.angularVelocity.copy(i.angularVelocity)):a.hasAngularVelocity=!1,this.dispatchEvent(lr)))}return null!==a&&(a.visible=null!==i),null!==o&&(o.visible=null!==r),null!==l&&(l.visible=null!==s),this}_getHandJoint(t,e){if(void 0===t.joints[e.jointName]){const n=new or;n.matrixAutoUpdate=!1,n.visible=!1,t.joints[e.jointName]=n,t.add(n)}return t.joints[e.jointName]}}class hr extends Yn{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.backgroundBlurriness=0,this.backgroundIntensity=1,this.backgroundRotation=new In,this.environmentIntensity=1,this.environmentRotation=new In,this.overrideMaterial=null,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}copy(t,e){return super.copy(t,e),null!==t.background&&(this.background=t.background.clone()),null!==t.environment&&(this.environment=t.environment.clone()),null!==t.fog&&(this.fog=t.fog.clone()),this.backgroundBlurriness=t.backgroundBlurriness,this.backgroundIntensity=t.backgroundIntensity,this.backgroundRotation.copy(t.backgroundRotation),this.environmentIntensity=t.environmentIntensity,this.environmentRotation.copy(t.environmentRotation),null!==t.overrideMaterial&&(this.overrideMaterial=t.overrideMaterial.clone()),this.matrixAutoUpdate=t.matrixAutoUpdate,this}toJSON(t){const e=super.toJSON(t);return null!==this.fog&&(e.object.fog=this.fog.toJSON()),this.backgroundBlurriness>0&&(e.object.backgroundBlurriness=this.backgroundBlurriness),1!==this.backgroundIntensity&&(e.object.backgroundIntensity=this.backgroundIntensity),e.object.backgroundRotation=this.backgroundRotation.toArray(),1!==this.environmentIntensity&&(e.object.environmentIntensity=this.environmentIntensity),e.object.environmentRotation=this.environmentRotation.toArray(),e}}class ur{constructor(t,e){this.isInterleavedBuffer=!0,this.array=t,this.stride=e,this.count=void 0!==t?t.length/e:0,this.usage=te,this.updateRanges=[],this.version=0,this.uuid=ce()}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}copy(t){return this.array=new t.array.constructor(t.array),this.count=t.count,this.stride=t.stride,this.usage=t.usage,this}copyAt(t,e,n){t*=this.stride,n*=e.stride;for(let i=0,r=this.stride;it.far||e.push({distance:o,point:gr.clone(),uv:li.getInterpolation(gr,br,Sr,Tr,wr,Er,Ar,new ge),face:null,object:this})}copy(t,e){return super.copy(t,e),void 0!==t.center&&this.center.copy(t.center),this.material=t.material,this}}function Cr(t,e,n,i,r,s){yr.subVectors(t,n).addScalar(.5).multiply(i),void 0!==r?(xr.x=s*yr.x-r*yr.y,xr.y=r*yr.x+s*yr.y):xr.copy(yr),t.copy(e),t.x+=xr.x,t.y+=xr.y,t.applyMatrix4(Mr)}const Pr=new _e,Ir=new Ve,Lr=new Ve,Nr=new _e,Dr=new Mn,Ur=new _e,Or=new dn,Fr=new Mn,kr=new xn;class Br extends Wi{constructor(t,e){super(t,e),this.isSkinnedMesh=!0,this.type="SkinnedMesh",this.bindMode=P,this.bindMatrix=new Mn,this.bindMatrixInverse=new Mn,this.boundingBox=null,this.boundingSphere=null}computeBoundingBox(){const t=this.geometry;null===this.boundingBox&&(this.boundingBox=new qe),this.boundingBox.makeEmpty();const e=t.getAttribute("position");for(let t=0;t1?null:e.copy(t.start).addScaledVector(n,r)}intersectsLine(t){const e=this.distanceToPoint(t.start),n=this.distanceToPoint(t.end);return e<0&&n>0||n<0&&e>0}intersectsBox(t){return t.intersectsPlane(this)}intersectsSphere(t){return t.intersectsPlane(this)}coplanarPoint(t){return t.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(t,e){const n=e||ns.getNormalMatrix(t),i=this.coplanarPoint(ts).applyMatrix4(t),r=this.normal.applyMatrix3(n).normalize();return this.constant=-i.dot(r),this}translate(t){return this.constant-=t.dot(this.normal),this}equals(t){return t.normal.equals(this.normal)&&t.constant===this.constant}clone(){return(new this.constructor).copy(this)}}const rs=new dn,ss=new ge(.5,.5),as=new _e;class os{constructor(t=new is,e=new is,n=new is,i=new is,r=new is,s=new is){this.planes=[t,e,n,i,r,s]}set(t,e,n,i,r,s){const a=this.planes;return a[0].copy(t),a[1].copy(e),a[2].copy(n),a[3].copy(i),a[4].copy(r),a[5].copy(s),this}copy(t){const e=this.planes;for(let n=0;n<6;n++)e[n].copy(t.planes[n]);return this}setFromProjectionMatrix(t,e=2e3){const n=this.planes,i=t.elements,r=i[0],s=i[1],a=i[2],o=i[3],l=i[4],c=i[5],h=i[6],u=i[7],d=i[8],p=i[9],f=i[10],m=i[11],g=i[12],v=i[13],_=i[14],y=i[15];if(n[0].setComponents(o-r,u-l,m-d,y-g).normalize(),n[1].setComponents(o+r,u+l,m+d,y+g).normalize(),n[2].setComponents(o+s,u+c,m+p,y+v).normalize(),n[3].setComponents(o-s,u-c,m-p,y-v).normalize(),n[4].setComponents(o-a,u-h,m-f,y-_).normalize(),e===ne)n[5].setComponents(o+a,u+h,m+f,y+_).normalize();else{if(e!==ie)throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: "+e);n[5].setComponents(a,h,f,_).normalize()}return this}intersectsObject(t){if(void 0!==t.boundingSphere)null===t.boundingSphere&&t.computeBoundingSphere(),rs.copy(t.boundingSphere).applyMatrix4(t.matrixWorld);else{const e=t.geometry;null===e.boundingSphere&&e.computeBoundingSphere(),rs.copy(e.boundingSphere).applyMatrix4(t.matrixWorld)}return this.intersectsSphere(rs)}intersectsSprite(t){rs.center.set(0,0,0);const e=ss.distanceTo(t.center);return rs.radius=.7071067811865476+e,rs.applyMatrix4(t.matrixWorld),this.intersectsSphere(rs)}intersectsSphere(t){const e=this.planes,n=t.center,i=-t.radius;for(let t=0;t<6;t++)if(e[t].distanceToPoint(n)0?t.max.x:t.min.x,as.y=i.normal.y>0?t.max.y:t.min.y,as.z=i.normal.z>0?t.max.z:t.min.z,i.distanceToPoint(as)<0)return!1}return!0}containsPoint(t){const e=this.planes;for(let n=0;n<6;n++)if(e[n].distanceToPoint(t)<0)return!1;return!0}clone(){return(new this.constructor).copy(this)}}class ls extends gi{constructor(t){super(),this.isLineBasicMaterial=!0,this.type="LineBasicMaterial",this.color=new pi(16777215),this.map=null,this.linewidth=1,this.linecap="round",this.linejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.linewidth=t.linewidth,this.linecap=t.linecap,this.linejoin=t.linejoin,this.fog=t.fog,this}}const cs=new _e,hs=new _e,us=new Mn,ds=new xn,ps=new dn,fs=new _e,ms=new _e;class gs extends Yn{constructor(t=new Li,e=new ls){super(),this.isLine=!0,this.type="Line",this.geometry=t,this.material=e,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.updateMorphTargets()}copy(t,e){return super.copy(t,e),this.material=Array.isArray(t.material)?t.material.slice():t.material,this.geometry=t.geometry,this}computeLineDistances(){const t=this.geometry;if(null===t.index){const e=t.attributes.position,n=[0];for(let t=1,i=e.count;t0){const n=t[e[0]];if(void 0!==n){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=n.length;ti)return;fs.applyMatrix4(t.matrixWorld);const l=e.ray.origin.distanceTo(fs);return le.far?void 0:{distance:l,point:ms.clone().applyMatrix4(t.matrixWorld),index:a,face:null,faceIndex:null,barycoord:null,object:t}}const _s=new _e,ys=new _e;class xs extends gs{constructor(t,e){super(t,e),this.isLineSegments=!0,this.type="LineSegments"}computeLineDistances(){const t=this.geometry;if(null===t.index){const e=t.attributes.position,n=[];for(let t=0,i=e.count;t0){const n=t[e[0]];if(void 0!==n){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=n.length;tr.far)return;s.push({distance:l,distanceToRay:Math.sqrt(o),point:n,index:e,face:null,faceIndex:null,barycoord:null,object:a})}}class Cs extends He{constructor(t,e,n,i,r,s,a,o,l){super(t,e,n,i,r,s,a,o,l),this.isCanvasTexture=!0,this.needsUpdate=!0}}class Ps extends He{constructor(t,e,n=1014,i,r,s,a=1003,o=1003,l,c=1026,h=1){if(c!==tt&&c!==et)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");super({width:t,height:e,depth:h},i,r,s,a,o,c,n,l),this.isDepthTexture=!0,this.flipY=!1,this.generateMipmaps=!1,this.compareFunction=null}copy(t){return super.copy(t),this.source=new Fe(Object.assign({},t.image)),this.compareFunction=t.compareFunction,this}toJSON(t){const e=super.toJSON(t);return null!==this.compareFunction&&(e.compareFunction=this.compareFunction),e}}class Is extends Li{constructor(t=1,e=1,n=4,i=8,r=1){super(),this.type="CapsuleGeometry",this.parameters={radius:t,height:e,capSegments:n,radialSegments:i,heightSegments:r},e=Math.max(0,e),n=Math.max(1,Math.floor(n)),i=Math.max(3,Math.floor(i)),r=Math.max(1,Math.floor(r));const s=[],a=[],o=[],l=[],c=e/2,h=Math.PI/2*t,u=e,d=2*h+u,p=2*n+r,f=i+1,m=new _e,g=new _e;for(let v=0;v<=p;v++){let _=0,y=0,x=0,M=0;if(v<=n){const e=v/n,i=e*Math.PI/2;y=-c-t*Math.cos(i),x=t*Math.sin(i),M=-t*Math.cos(i),_=e*h}else if(v<=n+r){const i=(v-n)/r;y=i*e-c,x=t,M=0,_=h+i*u}else{const e=(v-n-r)/n,i=e*Math.PI/2;y=c+t*Math.sin(i),x=t*Math.cos(i),M=t*Math.sin(i),_=h+u+e*h}const b=Math.max(0,Math.min(1,_/d));let S=0;0===v?S=.5/i:v===p&&(S=-.5/i);for(let t=0;t<=i;t++){const e=t/i,n=e*Math.PI*2,r=Math.sin(n),s=Math.cos(n);g.x=-x*s,g.y=y,g.z=x*r,a.push(g.x,g.y,g.z),m.set(-x*s,M,x*r),m.normalize(),o.push(m.x,m.y,m.z),l.push(e+S,b)}if(v>0){const t=(v-1)*f;for(let e=0;e0||0!==i)&&(c.push(s,a,l),_+=3),(e>0||i!==r-1)&&(c.push(a,o,l),_+=3)}l.addGroup(g,_,0),g+=_}(),!1===s&&(t>0&&v(!0),e>0&&v(!1)),this.setIndex(c),this.setAttribute("position",new Ti(h,3)),this.setAttribute("normal",new Ti(u,3)),this.setAttribute("uv",new Ti(d,2))}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}static fromJSON(t){return new Ns(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Ds extends Ns{constructor(t=1,e=1,n=32,i=1,r=!1,s=0,a=2*Math.PI){super(0,t,e,n,i,r,s,a),this.type="ConeGeometry",this.parameters={radius:t,height:e,radialSegments:n,heightSegments:i,openEnded:r,thetaStart:s,thetaLength:a}}static fromJSON(t){return new Ds(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Us extends Li{constructor(t=[],e=[],n=1,i=0){super(),this.type="PolyhedronGeometry",this.parameters={vertices:t,indices:e,radius:n,detail:i};const r=[],s=[];function a(t,e,n,i){const r=i+1,s=[];for(let i=0;i<=r;i++){s[i]=[];const a=t.clone().lerp(n,i/r),o=e.clone().lerp(n,i/r),l=r-i;for(let t=0;t<=l;t++)s[i][t]=0===t&&i===r?a:a.clone().lerp(o,t/l)}for(let t=0;t.9&&a<.1&&(e<.2&&(s[t+0]+=1),n<.2&&(s[t+2]+=1),i<.2&&(s[t+4]+=1))}}()}(),this.setAttribute("position",new Ti(r,3)),this.setAttribute("normal",new Ti(r.slice(),3)),this.setAttribute("uv",new Ti(s,2)),0===i?this.computeVertexNormals():this.normalizeNormals()}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}static fromJSON(t){return new Us(t.vertices,t.indices,t.radius,t.details)}}class Os extends Us{constructor(t=1,e=0){const n=(1+Math.sqrt(5))/2,i=1/n;super([-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-i,-n,0,-i,n,0,i,-n,0,i,n,-i,-n,0,-i,n,0,i,-n,0,i,n,0,-n,0,-i,n,0,-i,-n,0,i,n,0,i],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],t,e),this.type="DodecahedronGeometry",this.parameters={radius:t,detail:e}}static fromJSON(t){return new Os(t.radius,t.detail)}}const Fs=new _e,ks=new _e,Bs=new _e,zs=new li;class Hs extends Li{constructor(t=null,e=1){if(super(),this.type="EdgesGeometry",this.parameters={geometry:t,thresholdAngle:e},null!==t){const n=4,i=Math.pow(10,n),r=Math.cos(oe*e),s=t.getIndex(),a=t.getAttribute("position"),o=s?s.count:a.count,l=[0,0,0],c=["a","b","c"],h=new Array(3),u={},d=[];for(let t=0;t0)){l=i;break}l=i-1}if(i=l,n[i]===s)return i/(r-1);const c=n[i];return(i+(s-c)/(n[i+1]-c))/(r-1)}getTangent(t,e){const n=1e-4;let i=t-n,r=t+n;i<0&&(i=0),r>1&&(r=1);const s=this.getPoint(i),a=this.getPoint(r),o=e||(s.isVector2?new ge:new _e);return o.copy(a).sub(s).normalize(),o}getTangentAt(t,e){const n=this.getUtoTmapping(t);return this.getTangent(n,e)}computeFrenetFrames(t,e=!1){const n=new _e,i=[],r=[],s=[],a=new _e,o=new Mn;for(let e=0;e<=t;e++){const n=e/t;i[e]=this.getTangentAt(n,new _e)}r[0]=new _e,s[0]=new _e;let l=Number.MAX_VALUE;const c=Math.abs(i[0].x),h=Math.abs(i[0].y),u=Math.abs(i[0].z);c<=l&&(l=c,n.set(1,0,0)),h<=l&&(l=h,n.set(0,1,0)),u<=l&&n.set(0,0,1),a.crossVectors(i[0],n).normalize(),r[0].crossVectors(i[0],a),s[0].crossVectors(i[0],r[0]);for(let e=1;e<=t;e++){if(r[e]=r[e-1].clone(),s[e]=s[e-1].clone(),a.crossVectors(i[e-1],i[e]),a.length()>Number.EPSILON){a.normalize();const t=Math.acos(he(i[e-1].dot(i[e]),-1,1));r[e].applyMatrix4(o.makeRotationAxis(a,t))}s[e].crossVectors(i[e],r[e])}if(!0===e){let e=Math.acos(he(r[0].dot(r[t]),-1,1));e/=t,i[0].dot(a.crossVectors(r[0],r[t]))>0&&(e=-e);for(let n=1;n<=t;n++)r[n].applyMatrix4(o.makeRotationAxis(i[n],e*n)),s[n].crossVectors(i[n],r[n])}return{tangents:i,normals:r,binormals:s}}clone(){return(new this.constructor).copy(this)}copy(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}toJSON(){const t={metadata:{version:4.7,type:"Curve",generator:"Curve.toJSON"}};return t.arcLengthDivisions=this.arcLengthDivisions,t.type=this.type,t}fromJSON(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}}class Gs extends Vs{constructor(t=0,e=0,n=1,i=1,r=0,s=2*Math.PI,a=!1,o=0){super(),this.isEllipseCurve=!0,this.type="EllipseCurve",this.aX=t,this.aY=e,this.xRadius=n,this.yRadius=i,this.aStartAngle=r,this.aEndAngle=s,this.aClockwise=a,this.aRotation=o}getPoint(t,e=new ge){const n=e,i=2*Math.PI;let r=this.aEndAngle-this.aStartAngle;const s=Math.abs(r)i;)r-=i;ri.length-2?i.length-1:s+1],h=i[s>i.length-3?i.length-1:s+2];return n.set(Ks(a,o.x,l.x,c.x,h.x),Ks(a,o.y,l.y,c.y,h.y)),n}copy(t){super.copy(t),this.points=[];for(let e=0,n=t.points.length;e0?0:(Math.floor(Math.abs(l)/r)+1)*r:0===c&&l===r-1&&(l=r-2,c=1),this.closed||l>0?a=i[(l-1)%r]:(js.subVectors(i[0],i[1]).add(i[0]),a=js);const h=i[l%r],u=i[(l+1)%r];if(this.closed||l+2=n){const t=i[r]-n,s=this.curves[r],a=s.getLength(),o=0===a?0:1-t/a;return s.getPointAt(o,e)}r++}return null}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()}getCurveLengths(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;const t=[];let e=0;for(let n=0,i=this.curves.length;n1&&!e[e.length-1].equals(e[0])&&e.push(e[0]),e}copy(t){super.copy(t),this.curves=[];for(let e=0,n=t.curves.length;e0){const t=l.getPoint(0);t.equals(this.currentPoint)||this.lineTo(t.x,t.y)}this.curves.push(l);const c=l.getPoint(1);return this.currentPoint.copy(c),this}copy(t){return super.copy(t),this.currentPoint.copy(t.currentPoint),this}toJSON(){const t=super.toJSON();return t.currentPoint=this.currentPoint.toArray(),t}fromJSON(t){return super.fromJSON(t),this.currentPoint.fromArray(t.currentPoint),this}}class sa extends ra{constructor(t){super(t),this.uuid=ce(),this.type="Shape",this.holes=[]}getPointsHoles(t){const e=[];for(let n=0,i=this.holes.length;n0)for(let r=e;r=e;r-=i)s=Ra(r/i|0,t[r],t[r+1],s);return s&&ba(s,s.next)&&(Ca(s),s=s.next),s}function oa(t,e){if(!t)return t;e||(e=t);let n,i=t;do{if(n=!1,i.steiner||!ba(i,i.next)&&0!==Ma(i.prev,i,i.next))i=i.next;else{if(Ca(i),i=e=i.prev,i===i.next)break;n=!0}}while(n||i!==e);return e}function la(t,e,n,i,r,s,a){if(!t)return;!a&&s&&function(t,e,n,i){let r=t;do{0===r.z&&(r.z=ga(r.x,r.y,e,n,i)),r.prevZ=r.prev,r.nextZ=r.next,r=r.next}while(r!==t);r.prevZ.nextZ=null,r.prevZ=null,function(t){let e,n=1;do{let i,r=t;t=null;let s=null;for(e=0;r;){e++;let a=r,o=0;for(let t=0;t0||l>0&&a;)0!==o&&(0===l||!a||r.z<=a.z)?(i=r,r=r.nextZ,o--):(i=a,a=a.nextZ,l--),s?s.nextZ=i:t=i,i.prevZ=s,s=i;r=a}s.nextZ=null,n*=2}while(e>1)}(r)}(t,i,r,s);let o=t;for(;t.prev!==t.next;){const l=t.prev,c=t.next;if(s?ha(t,i,r,s):ca(t))e.push(l.i,t.i,c.i),Ca(t),t=c.next,o=c.next;else if((t=c)===o){a?1===a?la(t=ua(oa(t),e),e,n,i,r,s,2):2===a&&da(t,e,n,i,r,s):la(oa(t),e,n,i,r,s,1);break}}}function ca(t){const e=t.prev,n=t,i=t.next;if(Ma(e,n,i)>=0)return!1;const r=e.x,s=n.x,a=i.x,o=e.y,l=n.y,c=i.y,h=Math.min(r,s,a),u=Math.min(o,l,c),d=Math.max(r,s,a),p=Math.max(o,l,c);let f=i.next;for(;f!==e;){if(f.x>=h&&f.x<=d&&f.y>=u&&f.y<=p&&ya(r,o,s,l,a,c,f.x,f.y)&&Ma(f.prev,f,f.next)>=0)return!1;f=f.next}return!0}function ha(t,e,n,i){const r=t.prev,s=t,a=t.next;if(Ma(r,s,a)>=0)return!1;const o=r.x,l=s.x,c=a.x,h=r.y,u=s.y,d=a.y,p=Math.min(o,l,c),f=Math.min(h,u,d),m=Math.max(o,l,c),g=Math.max(h,u,d),v=ga(p,f,e,n,i),_=ga(m,g,e,n,i);let y=t.prevZ,x=t.nextZ;for(;y&&y.z>=v&&x&&x.z<=_;){if(y.x>=p&&y.x<=m&&y.y>=f&&y.y<=g&&y!==r&&y!==a&&ya(o,h,l,u,c,d,y.x,y.y)&&Ma(y.prev,y,y.next)>=0)return!1;if(y=y.prevZ,x.x>=p&&x.x<=m&&x.y>=f&&x.y<=g&&x!==r&&x!==a&&ya(o,h,l,u,c,d,x.x,x.y)&&Ma(x.prev,x,x.next)>=0)return!1;x=x.nextZ}for(;y&&y.z>=v;){if(y.x>=p&&y.x<=m&&y.y>=f&&y.y<=g&&y!==r&&y!==a&&ya(o,h,l,u,c,d,y.x,y.y)&&Ma(y.prev,y,y.next)>=0)return!1;y=y.prevZ}for(;x&&x.z<=_;){if(x.x>=p&&x.x<=m&&x.y>=f&&x.y<=g&&x!==r&&x!==a&&ya(o,h,l,u,c,d,x.x,x.y)&&Ma(x.prev,x,x.next)>=0)return!1;x=x.nextZ}return!0}function ua(t,e){let n=t;do{const i=n.prev,r=n.next.next;!ba(i,r)&&Sa(i,n,n.next,r)&&Ea(i,r)&&Ea(r,i)&&(e.push(i.i,n.i,r.i),Ca(n),Ca(n.next),n=t=r),n=n.next}while(n!==t);return oa(n)}function da(t,e,n,i,r,s){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&xa(a,t)){let o=Aa(a,t);return a=oa(a,a.next),o=oa(o,o.next),la(a,e,n,i,r,s,0),void la(o,e,n,i,r,s,0)}t=t.next}a=a.next}while(a!==t)}function pa(t,e){let n=t.x-e.x;return 0===n&&(n=t.y-e.y,0===n)&&(n=(t.next.y-t.y)/(t.next.x-t.x)-(e.next.y-e.y)/(e.next.x-e.x)),n}function fa(t,e){const n=function(t,e){let n=e;const i=t.x,r=t.y;let s,a=-1/0;if(ba(t,n))return n;do{if(ba(t,n.next))return n.next;if(r<=n.y&&r>=n.next.y&&n.next.y!==n.y){const t=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(t<=i&&t>a&&(a=t,s=n.x=n.x&&n.x>=l&&i!==n.x&&_a(rs.x||n.x===s.x&&ma(s,n)))&&(s=n,h=e)}n=n.next}while(n!==o);return s}(t,e);if(!n)return e;const i=Aa(n,t);return oa(i,i.next),oa(n,n.next)}function ma(t,e){return Ma(t.prev,t,e.prev)<0&&Ma(e.next,t,t.next)<0}function ga(t,e,n,i,r){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-n)*r|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-i)*r|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function va(t){let e=t,n=t;do{(e.x=(t-a)*(s-o)&&(t-a)*(i-o)>=(n-a)*(e-o)&&(n-a)*(s-o)>=(r-a)*(i-o)}function ya(t,e,n,i,r,s,a,o){return!(t===a&&e===o)&&_a(t,e,n,i,r,s,a,o)}function xa(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){let n=t;do{if(n.i!==t.i&&n.next.i!==t.i&&n.i!==e.i&&n.next.i!==e.i&&Sa(n,n.next,t,e))return!0;n=n.next}while(n!==t);return!1}(t,e)&&(Ea(t,e)&&Ea(e,t)&&function(t,e){let n=t,i=!1;const r=(t.x+e.x)/2,s=(t.y+e.y)/2;do{n.y>s!=n.next.y>s&&n.next.y!==n.y&&r<(n.next.x-n.x)*(s-n.y)/(n.next.y-n.y)+n.x&&(i=!i),n=n.next}while(n!==t);return i}(t,e)&&(Ma(t.prev,t,e.prev)||Ma(t,e.prev,e))||ba(t,e)&&Ma(t.prev,t,t.next)>0&&Ma(e.prev,e,e.next)>0)}function Ma(t,e,n){return(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y)}function ba(t,e){return t.x===e.x&&t.y===e.y}function Sa(t,e,n,i){const r=wa(Ma(t,e,n)),s=wa(Ma(t,e,i)),a=wa(Ma(n,i,t)),o=wa(Ma(n,i,e));return r!==s&&a!==o||!(0!==r||!Ta(t,n,e))||!(0!==s||!Ta(t,i,e))||!(0!==a||!Ta(n,t,i))||!(0!==o||!Ta(n,e,i))}function Ta(t,e,n){return e.x<=Math.max(t.x,n.x)&&e.x>=Math.min(t.x,n.x)&&e.y<=Math.max(t.y,n.y)&&e.y>=Math.min(t.y,n.y)}function wa(t){return t>0?1:t<0?-1:0}function Ea(t,e){return Ma(t.prev,t,t.next)<0?Ma(t,e,t.next)>=0&&Ma(t,t.prev,e)>=0:Ma(t,e,t.prev)<0||Ma(t,t.next,e)<0}function Aa(t,e){const n=Pa(t.i,t.x,t.y),i=Pa(e.i,e.x,e.y),r=t.next,s=e.prev;return t.next=e,e.prev=t,n.next=r,r.prev=n,i.next=n,n.prev=i,s.next=i,i.prev=s,i}function Ra(t,e,n,i){const r=Pa(t,e,n);return i?(r.next=i.next,r.prev=i,i.next.prev=r,i.next=r):(r.prev=r,r.next=r),r}function Ca(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function Pa(t,e,n){return{i:t,x:e,y:n,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}class Ia{static triangulate(t,e,n=2){return function(t,e,n=2){const i=e&&e.length,r=i?e[0]*n:t.length;let s=aa(t,0,r,n,!0);const a=[];if(!s||s.next===s.prev)return a;let o,l,c;if(i&&(s=function(t,e,n,i){const r=[];for(let n=0,s=e.length;n80*n){o=1/0,l=1/0;let e=-1/0,i=-1/0;for(let s=n;se&&(e=n),r>i&&(i=r)}c=Math.max(e-o,i-l),c=0!==c?32767/c:0}return la(s,a,n,o,l,c,0),a}(t,e,n)}}class La{static area(t){const e=t.length;let n=0;for(let i=e-1,r=0;r2&&t[e-1].equals(t[0])&&t.pop()}function Da(t,e){for(let n=0;nNumber.EPSILON){const u=Math.sqrt(h),d=Math.sqrt(l*l+c*c),p=e.x-o/u,f=e.y+a/u,m=((n.x-c/d-p)*c-(n.y+l/d-f)*l)/(a*c-o*l);i=p+a*m-t.x,r=f+o*m-t.y;const g=i*i+r*r;if(g<=2)return new ge(i,r);s=Math.sqrt(g/2)}else{let t=!1;a>Number.EPSILON?l>Number.EPSILON&&(t=!0):a<-Number.EPSILON?l<-Number.EPSILON&&(t=!0):Math.sign(o)===Math.sign(c)&&(t=!0),t?(i=-o,r=a,s=Math.sqrt(h)):(i=a,r=o,s=Math.sqrt(h/2))}return new ge(i/s,r/s)}const I=[];for(let t=0,e=A.length,n=e-1,i=t+1;t=0;t--){const e=t/p,n=h*Math.cos(e*Math.PI/2),i=u*Math.sin(e*Math.PI/2)+d;for(let t=0,e=A.length;t=0;){const i=n;let r=n-1;r<0&&(r=t.length-1);for(let t=0,n=o+2*p;t0)&&d.push(e,r,l),(t!==n-1||o0!=t>0&&this.version++,this._anisotropy=t}get clearcoat(){return this._clearcoat}set clearcoat(t){this._clearcoat>0!=t>0&&this.version++,this._clearcoat=t}get iridescence(){return this._iridescence}set iridescence(t){this._iridescence>0!=t>0&&this.version++,this._iridescence=t}get dispersion(){return this._dispersion}set dispersion(t){this._dispersion>0!=t>0&&this.version++,this._dispersion=t}get sheen(){return this._sheen}set sheen(t){this._sheen>0!=t>0&&this.version++,this._sheen=t}get transmission(){return this._transmission}set transmission(t){this._transmission>0!=t>0&&this.version++,this._transmission=t}copy(t){return super.copy(t),this.defines={STANDARD:"",PHYSICAL:""},this.anisotropy=t.anisotropy,this.anisotropyRotation=t.anisotropyRotation,this.anisotropyMap=t.anisotropyMap,this.clearcoat=t.clearcoat,this.clearcoatMap=t.clearcoatMap,this.clearcoatRoughness=t.clearcoatRoughness,this.clearcoatRoughnessMap=t.clearcoatRoughnessMap,this.clearcoatNormalMap=t.clearcoatNormalMap,this.clearcoatNormalScale.copy(t.clearcoatNormalScale),this.dispersion=t.dispersion,this.ior=t.ior,this.iridescence=t.iridescence,this.iridescenceMap=t.iridescenceMap,this.iridescenceIOR=t.iridescenceIOR,this.iridescenceThicknessRange=[...t.iridescenceThicknessRange],this.iridescenceThicknessMap=t.iridescenceThicknessMap,this.sheen=t.sheen,this.sheenColor.copy(t.sheenColor),this.sheenColorMap=t.sheenColorMap,this.sheenRoughness=t.sheenRoughness,this.sheenRoughnessMap=t.sheenRoughnessMap,this.transmission=t.transmission,this.transmissionMap=t.transmissionMap,this.thickness=t.thickness,this.thicknessMap=t.thicknessMap,this.attenuationDistance=t.attenuationDistance,this.attenuationColor.copy(t.attenuationColor),this.specularIntensity=t.specularIntensity,this.specularIntensityMap=t.specularIntensityMap,this.specularColor.copy(t.specularColor),this.specularColorMap=t.specularColorMap,this}}class Ya extends gi{constructor(t){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new pi(16777215),this.specular=new pi(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new pi(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new ge(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new In,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.specular.copy(t.specular),this.shininess=t.shininess,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Ka extends gi{constructor(t){super(),this.isMeshLambertMaterial=!0,this.type="MeshLambertMaterial",this.color=new pi(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new pi(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new ge(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new In,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Ja extends gi{constructor(t){super(),this.isMeshDepthMaterial=!0,this.type="MeshDepthMaterial",this.depthPacking=3200,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.setValues(t)}copy(t){return super.copy(t),this.depthPacking=t.depthPacking,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this}}class Za extends gi{constructor(t){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.setValues(t)}copy(t){return super.copy(t),this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this}}function $a(t,e){return t&&t.constructor!==e?"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t):t}function Qa(t){const e=t.length,n=new Array(e);for(let t=0;t!==e;++t)n[t]=t;return n.sort(function(e,n){return t[e]-t[n]}),n}function to(t,e,n){const i=t.length,r=new t.constructor(i);for(let s=0,a=0;a!==i;++s){const i=n[s]*e;for(let n=0;n!==e;++n)r[a++]=t[i+n]}return r}function eo(t,e,n,i){let r=1,s=t[0];for(;void 0!==s&&void 0===s[i];)s=t[r++];if(void 0===s)return;let a=s[i];if(void 0!==a)if(Array.isArray(a))do{a=s[i],void 0!==a&&(e.push(s.time),n.push(...a)),s=t[r++]}while(void 0!==s);else if(void 0!==a.toArray)do{a=s[i],void 0!==a&&(e.push(s.time),a.toArray(n,n.length)),s=t[r++]}while(void 0!==s);else do{a=s[i],void 0!==a&&(e.push(s.time),n.push(a)),s=t[r++]}while(void 0!==s)}class no{constructor(t,e,n,i){this.parameterPositions=t,this._cachedIndex=0,this.resultBuffer=void 0!==i?i:new e.constructor(n),this.sampleValues=e,this.valueSize=n,this.settings=null,this.DefaultSettings_={}}evaluate(t){const e=this.parameterPositions;let n=this._cachedIndex,i=e[n],r=e[n-1];t:{e:{let s;n:{i:if(!(t=r)){const a=e[1];t=r)break e}s=n,n=0;break n}break t}for(;n>>1;te;)--s;if(++s,0!==r||s!==i){r>=s&&(s=Math.max(s,1),r=s-1);const t=this.getValueSize();this.times=n.slice(r,s),this.values=this.values.slice(r*t,s*t)}return this}validate(){let t=!0;const e=this.getValueSize();e-Math.floor(e)!==0&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),t=!1);const n=this.times,i=this.values,r=n.length;0===r&&(console.error("THREE.KeyframeTrack: Track is empty.",this),t=!1);let s=null;for(let e=0;e!==r;e++){const i=n[e];if("number"==typeof i&&isNaN(i)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,e,i),t=!1;break}if(null!==s&&s>i){console.error("THREE.KeyframeTrack: Out of order keys.",this,e,i,s),t=!1;break}s=i}if(void 0!==i&&(a=i,ArrayBuffer.isView(a)&&!(a instanceof DataView)))for(let e=0,n=i.length;e!==n;++e){const n=i[e];if(isNaN(n)){console.error("THREE.KeyframeTrack: Value is not a valid number.",this,e,n),t=!1;break}}var a;return t}optimize(){const t=this.times.slice(),e=this.values.slice(),n=this.getValueSize(),i=this.getInterpolation()===Bt,r=t.length-1;let s=1;for(let a=1;a0){t[s]=t[r];for(let t=r*n,i=s*n,a=0;a!==n;++a)e[i+a]=e[t+a];++s}return s!==t.length?(this.times=t.slice(0,s),this.values=e.slice(0,s*n)):(this.times=t,this.values=e),this}clone(){const t=this.times.slice(),e=this.values.slice(),n=new(0,this.constructor)(this.name,t,e);return n.createInterpolant=this.createInterpolant,n}}ao.prototype.ValueTypeName="",ao.prototype.TimeBufferType=Float32Array,ao.prototype.ValueBufferType=Float32Array,ao.prototype.DefaultInterpolation=kt;class oo extends ao{constructor(t,e,n){super(t,e,n)}}oo.prototype.ValueTypeName="bool",oo.prototype.ValueBufferType=Array,oo.prototype.DefaultInterpolation=Ft,oo.prototype.InterpolantFactoryMethodLinear=void 0,oo.prototype.InterpolantFactoryMethodSmooth=void 0;class lo extends ao{constructor(t,e,n,i){super(t,e,n,i)}}lo.prototype.ValueTypeName="color";class co extends ao{constructor(t,e,n,i){super(t,e,n,i)}}co.prototype.ValueTypeName="number";class ho extends no{constructor(t,e,n,i){super(t,e,n,i)}interpolate_(t,e,n,i){const r=this.resultBuffer,s=this.sampleValues,a=this.valueSize,o=(n-e)/(i-e);let l=t*a;for(let t=l+a;l!==t;l+=4)ve.slerpFlat(r,0,s,l-a,s,l,o);return r}}class uo extends ao{constructor(t,e,n,i){super(t,e,n,i)}InterpolantFactoryMethodLinear(t){return new ho(this.times,this.values,this.getValueSize(),t)}}uo.prototype.ValueTypeName="quaternion",uo.prototype.InterpolantFactoryMethodSmooth=void 0;class po extends ao{constructor(t,e,n){super(t,e,n)}}po.prototype.ValueTypeName="string",po.prototype.ValueBufferType=Array,po.prototype.DefaultInterpolation=Ft,po.prototype.InterpolantFactoryMethodLinear=void 0,po.prototype.InterpolantFactoryMethodSmooth=void 0;class fo extends ao{constructor(t,e,n,i){super(t,e,n,i)}}fo.prototype.ValueTypeName="vector";class mo{constructor(t="",e=-1,n=[],i=2500){this.name=t,this.tracks=n,this.duration=e,this.blendMode=i,this.uuid=ce(),this.duration<0&&this.resetDuration()}static parse(t){const e=[],n=t.tracks,i=1/(t.fps||1);for(let t=0,r=n.length;t!==r;++t)e.push(go(n[t]).scale(i));const r=new this(t.name,t.duration,e,t.blendMode);return r.uuid=t.uuid,r}static toJSON(t){const e=[],n=t.tracks,i={name:t.name,duration:t.duration,tracks:e,uuid:t.uuid,blendMode:t.blendMode};for(let t=0,i=n.length;t!==i;++t)e.push(ao.toJSON(n[t]));return i}static CreateFromMorphTargetSequence(t,e,n,i){const r=e.length,s=[];for(let t=0;t1){const t=s[1];let e=i[t];e||(i[t]=e=[]),e.push(n)}}const s=[];for(const t in i)s.push(this.CreateFromMorphTargetSequence(t,i[t],e,n));return s}static parseAnimation(t,e){if(console.warn("THREE.AnimationClip: parseAnimation() is deprecated and will be removed with r185"),!t)return console.error("THREE.AnimationClip: No animation in JSONLoader data."),null;const n=function(t,e,n,i,r){if(0!==n.length){const s=[],a=[];eo(n,s,a,i),0!==s.length&&r.push(new t(e,s,a))}},i=[],r=t.name||"default",s=t.fps||30,a=t.blendMode;let o=t.length||-1;const l=t.hierarchy||[];for(let t=0;t{e&&e(r),this.manager.itemEnd(t)},0),r;if(void 0!==Mo[t])return void Mo[t].push({onLoad:e,onProgress:n,onError:i});Mo[t]=[],Mo[t].push({onLoad:e,onProgress:n,onError:i});const s=new Request(t,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?"include":"same-origin"}),a=this.mimeType,o=this.responseType;fetch(s).then(e=>{if(200===e.status||0===e.status){if(0===e.status&&console.warn("THREE.FileLoader: HTTP Status 0 received."),"undefined"==typeof ReadableStream||void 0===e.body||void 0===e.body.getReader)return e;const n=Mo[t],i=e.body.getReader(),r=e.headers.get("X-File-Size")||e.headers.get("Content-Length"),s=r?parseInt(r):0,a=0!==s;let o=0;const l=new ReadableStream({start(t){!function e(){i.read().then(({done:i,value:r})=>{if(i)t.close();else{o+=r.byteLength;const i=new ProgressEvent("progress",{lengthComputable:a,loaded:o,total:s});for(let t=0,e=n.length;t{t.error(e)})}()}});return new Response(l)}throw new bo(`fetch for "${e.url}" responded with ${e.status}: ${e.statusText}`,e)}).then(t=>{switch(o){case"arraybuffer":return t.arrayBuffer();case"blob":return t.blob();case"document":return t.text().then(t=>(new DOMParser).parseFromString(t,a));case"json":return t.json();default:if(""===a)return t.text();{const e=/charset="?([^;"\s]*)"?/i.exec(a),n=e&&e[1]?e[1].toLowerCase():void 0,i=new TextDecoder(n);return t.arrayBuffer().then(t=>i.decode(t))}}}).then(e=>{vo.add(`file:${t}`,e);const n=Mo[t];delete Mo[t];for(let t=0,i=n.length;t{const n=Mo[t];if(void 0===n)throw this.manager.itemError(t),e;delete Mo[t];for(let t=0,i=n.length;t{this.manager.itemEnd(t)}),this.manager.itemStart(t)}setResponseType(t){return this.responseType=t,this}setMimeType(t){return this.mimeType=t,this}}const To=new WeakMap;class wo extends xo{constructor(t){super(t)}load(t,e,n,i){void 0!==this.path&&(t=this.path+t),t=this.manager.resolveURL(t);const r=this,s=vo.get(`image:${t}`);if(void 0!==s){if(!0===s.complete)r.manager.itemStart(t),setTimeout(function(){e&&e(s),r.manager.itemEnd(t)},0);else{let t=To.get(s);void 0===t&&(t=[],To.set(s,t)),t.push({onLoad:e,onError:i})}return s}const a=Te("img");function o(){c(),e&&e(this);const n=To.get(this)||[];for(let t=0;t{if(!0!==jo.has(s))return e&&e(n),r.manager.itemEnd(t),n;i&&i(jo.get(s)),r.manager.itemError(t),r.manager.itemEnd(t)}):(setTimeout(function(){e&&e(s),r.manager.itemEnd(t)},0),s);const a={};a.credentials="anonymous"===this.crossOrigin?"same-origin":"include",a.headers=this.requestHeader;const o=fetch(t,a).then(function(t){return t.blob()}).then(function(t){return createImageBitmap(t,Object.assign(r.options,{colorSpaceConversion:"none"}))}).then(function(n){return vo.add(`image-bitmap:${t}`,n),e&&e(n),r.manager.itemEnd(t),n}).catch(function(e){i&&i(e),jo.set(o,e),vo.remove(`image-bitmap:${t}`),r.manager.itemError(t),r.manager.itemEnd(t)});vo.add(`image-bitmap:${t}`,o),r.manager.itemStart(t)}}class qo extends nr{constructor(t=[]){super(),this.isArrayCamera=!0,this.isMultiViewCamera=!1,this.cameras=t}}class Yo{constructor(t=!0){this.autoStart=t,this.startTime=0,this.oldTime=0,this.elapsedTime=0,this.running=!1}start(){this.startTime=performance.now(),this.oldTime=this.startTime,this.elapsedTime=0,this.running=!0}stop(){this.getElapsedTime(),this.running=!1,this.autoStart=!1}getElapsedTime(){return this.getDelta(),this.elapsedTime}getDelta(){let t=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){const e=performance.now();t=(e-this.oldTime)/1e3,this.oldTime=e,this.elapsedTime+=t}return t}}const Ko="\\[\\]\\.:\\/",Jo=new RegExp("["+Ko+"]","g"),Zo="[^"+Ko+"]",$o="[^"+Ko.replace("\\.","")+"]",Qo=new RegExp("^"+/((?:WC+[\/:])*)/.source.replace("WC",Zo)+/(WCOD+)?/.source.replace("WCOD",$o)+/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",Zo)+/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",Zo)+"$"),tl=["material","materials","bones","map"];class el{constructor(t,e,n){this.path=e,this.parsedPath=n||el.parseTrackName(e),this.node=el.findNode(t,this.parsedPath.nodeName),this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,e,n){return t&&t.isAnimationObjectGroup?new el.Composite(t,e,n):new el(t,e,n)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace(Jo,"")}static parseTrackName(t){const e=Qo.exec(t);if(null===e)throw new Error("PropertyBinding: Cannot parse trackName: "+t);const n={nodeName:e[2],objectName:e[3],objectIndex:e[4],propertyName:e[5],propertyIndex:e[6]},i=n.nodeName&&n.nodeName.lastIndexOf(".");if(void 0!==i&&-1!==i){const t=n.nodeName.substring(i+1);-1!==tl.indexOf(t)&&(n.nodeName=n.nodeName.substring(0,i),n.objectName=t)}if(null===n.propertyName||0===n.propertyName.length)throw new Error("PropertyBinding: can not parse propertyName from trackName: "+t);return n}static findNode(t,e){if(void 0===e||""===e||"."===e||-1===e||e===t.name||e===t.uuid)return t;if(t.skeleton){const n=t.skeleton.getBoneByName(e);if(void 0!==n)return n}if(t.children){const n=function(t){for(let i=0;i=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y))}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return this.clampPoint(t,ol).distanceTo(t)}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}class cl extends Wi{constructor(t,e,n){super(new Va(e,4,2),new vi({wireframe:!0,fog:!1,toneMapped:!1})),this.light=t,this.color=n,this.type="PointLightHelper",this.matrix=this.light.matrixWorld,this.matrixAutoUpdate=!1,this.update()}dispose(){this.geometry.dispose(),this.material.dispose()}update(){this.light.updateWorldMatrix(!0,!1),void 0!==this.color?this.material.color.set(this.color):this.material.color.copy(this.light.color)}}class hl extends xs{constructor(t=10,e=10,n=4473924,i=8947848){n=new pi(n),i=new pi(i);const r=e/2,s=t/e,a=t/2,o=[],l=[];for(let t=0,c=0,h=-a;t<=e;t++,h+=s){o.push(-a,0,h,a,0,h),o.push(h,0,-a,h,0,a);const e=t===r?n:i;e.toArray(l,c),c+=3,e.toArray(l,c),c+=3,e.toArray(l,c),c+=3,e.toArray(l,c),c+=3}const c=new Li;c.setAttribute("position",new Ti(o,3)),c.setAttribute("color",new Ti(l,3)),super(c,new ls({vertexColors:!0,toneMapped:!1})),this.type="GridHelper"}dispose(){this.geometry.dispose(),this.material.dispose()}}class ul extends xs{constructor(t=10,e=16,n=8,i=64,r=4473924,s=8947848){r=new pi(r),s=new pi(s);const a=[],o=[];if(e>1)for(let n=0;n.99999)this.quaternion.set(0,0,0,1);else if(t.y<-.99999)this.quaternion.set(1,0,0,0);else{ml.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle(ml,e)}}setLength(t,e=.2*t,n=.2*e){this.line.scale.set(1,Math.max(1e-4,t-e),1),this.line.updateMatrix(),this.cone.scale.set(n,e,n),this.cone.position.y=t,this.cone.updateMatrix()}setColor(t){this.line.material.color.set(t),this.cone.material.color.set(t)}copy(t){return super.copy(t,!1),this.line.copy(t.line),this.cone.copy(t.cone),this}dispose(){this.line.geometry.dispose(),this.line.material.dispose(),this.cone.geometry.dispose(),this.cone.material.dispose()}}class yl extends xs{constructor(t=1){const e=[0,0,0,t,0,0,0,0,0,0,t,0,0,0,0,0,0,t],n=new Li;n.setAttribute("position",new Ti(e,3)),n.setAttribute("color",new Ti([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1],3)),super(n,new ls({vertexColors:!0,toneMapped:!1})),this.type="AxesHelper"}setColors(t,e,n){const i=new pi,r=this.geometry.attributes.color.array;return i.set(t),i.toArray(r,0),i.toArray(r,3),i.set(e),i.toArray(r,6),i.toArray(r,9),i.set(n),i.toArray(r,12),i.toArray(r,15),this.geometry.attributes.color.needsUpdate=!0,this}dispose(){this.geometry.dispose(),this.material.dispose()}}class xl{constructor(){this.type="ShapePath",this.color=new pi,this.subPaths=[],this.currentPath=null}moveTo(t,e){return this.currentPath=new ra,this.subPaths.push(this.currentPath),this.currentPath.moveTo(t,e),this}lineTo(t,e){return this.currentPath.lineTo(t,e),this}quadraticCurveTo(t,e,n,i){return this.currentPath.quadraticCurveTo(t,e,n,i),this}bezierCurveTo(t,e,n,i,r,s){return this.currentPath.bezierCurveTo(t,e,n,i,r,s),this}splineThru(t){return this.currentPath.splineThru(t),this}toShapes(t){function e(t,e){const n=e.length;let i=!1;for(let r=n-1,s=0;sNumber.EPSILON){if(l<0&&(n=e[s],o=-o,a=e[r],l=-l),t.ya.y)continue;if(t.y===n.y){if(t.x===n.x)return!0}else{const e=l*(t.x-n.x)-o*(t.y-n.y);if(0===e)return!0;if(e<0)continue;i=!i}}else{if(t.y!==n.y)continue;if(a.x<=t.x&&t.x<=n.x||n.x<=t.x&&t.x<=a.x)return!0}}return i}const n=La.isClockWise,i=this.subPaths;if(0===i.length)return[];let r,s,a;const o=[];if(1===i.length)return s=i[0],a=new sa,a.curves=s.curves,o.push(a),o;let l=!n(i[0].getPoints());l=t?!l:l;const c=[],h=[];let u,d,p=[],f=0;h[f]=void 0,p[f]=[];for(let e=0,a=i.length;e1){let t=!1,n=0;for(let t=0,e=h.length;t0&&!1===t&&(p=c)}for(let t=0,e=h.length;tt.start-e.start);let e=0;for(let t=1;t 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif",color_fragment:"#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvarying vec3 vColor;\n#endif",color_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvec3 batchingColor = getBatchingColor( getIndirectIndex( gl_DrawID ) );\n\tvColor.xyz *= batchingColor.xyz;\n#endif",common:"#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif",defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n\t\temissiveColor = sRGBTransferEOTF( emissiveColor );\n\t#endif\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",colorspace_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",colorspace_pars_fragment:"vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}",envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif",envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif",envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif",envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif",gradientmap_pars_fragment:"#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_fragment:"LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;",lights_lambert_pars_fragment:"varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert",lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif",lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong",lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif",lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\tfloat dispersion;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn saturate(v);\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColor;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}",lights_fragment_begin:"\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif",lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif",lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\tvFragDepth = 1.0 + gl_Position.w;\n\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t#if defined( USE_POINTS_UV )\n\t\tvec2 uv = vUv;\n\t#else\n\t\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif",map_particle_pars_fragment:"#if defined( USE_POINTS_UV )\n\tvarying vec2 vUv;\n#else\n\t#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t\tuniform mat3 uvTransform;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphinstance_vertex:"#ifdef USE_INSTANCING_MORPH\n\tfloat morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\tfloat morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tmorphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n\t}\n#endif",morphcolor_vertex:"#if defined( USE_MORPHCOLORS )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING_MORPH\n\t\tuniform float morphTargetBaseInfluence;\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t#endif\n\tuniform sampler2DArray morphTargetsTexture;\n\tuniform ivec2 morphTargetsTextureSize;\n\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t}\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",normal_fragment_begin:"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;",normal_fragment_maps:"#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif",normal_pars_fragment:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_pars_vertex:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_vertex:"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif",normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif",clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = nonPerturbedNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\tclearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif",clearcoat_pars_fragment:"#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif",iridescence_pars_fragment:"#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif",opaque_fragment:"#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec4( 0., 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec4( 1., 1., 1., 1. );\n\tfloat vuf;\n\tfloat af = modf( v * PackFactors.a, vuf );\n\tfloat bf = modf( vuf * ShiftRight8, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec3( 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec3( 1., 1., 1. );\n\tfloat vuf;\n\tfloat bf = modf( v * PackFactors.b, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec2( 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec2( 1., 1. );\n\tfloat vuf;\n\tfloat gf = modf( v * 256., vuf );\n\treturn vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n\treturn dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n\treturn v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn depth * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * depth - far );\n}",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\t\n\t\tfloat lightToPositionLength = length( lightToPosition );\n\t\tif ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) {\n\t\t\tfloat dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\t\tdp += shadowBias;\n\t\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\t\tshadow = (\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t\t) * ( 1.0 / 9.0 );\n\t\t\t#else\n\t\t\t\tshadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n#endif",shadowmap_pars_vertex:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif",shadowmap_vertex:"#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif",shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}",skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif",specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }",transmission_fragment:"#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif",transmission_pars_fragment:"#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif",uv_pars_fragment:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_pars_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tuniform mat3 mapTransform;\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform mat3 alphaMapTransform;\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tuniform mat3 lightMapTransform;\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tuniform mat3 aoMapTransform;\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tuniform mat3 bumpMapTransform;\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tuniform mat3 normalMapTransform;\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tuniform mat3 displacementMapTransform;\n\tvarying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tuniform mat3 emissiveMapTransform;\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tuniform mat3 metalnessMapTransform;\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tuniform mat3 roughnessMapTransform;\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tuniform mat3 anisotropyMapTransform;\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tuniform mat3 clearcoatMapTransform;\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform mat3 clearcoatNormalMapTransform;\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform mat3 clearcoatRoughnessMapTransform;\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tuniform mat3 sheenColorMapTransform;\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tuniform mat3 sheenRoughnessMapTransform;\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tuniform mat3 iridescenceMapTransform;\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform mat3 iridescenceThicknessMapTransform;\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tuniform mat3 specularMapTransform;\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tuniform mat3 specularColorMapTransform;\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tuniform mat3 specularIntensityMapTransform;\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",background_frag:"uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",backgroundCube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",backgroundCube_frag:"#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#elif DEPTH_PACKING == 3202\n\t\tgl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n\t#elif DEPTH_PACKING == 3203\n\t\tgl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n\t#endif\n}",distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}",distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}",equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n\t#include \n}",linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include