{"version":3,"file":"default-utils.js@_0.45.2zM9jpKf.mjs","names":["useState","useMemo","useState","useRef","useRef","useState","useState","useRef","useCallback","handleError","length","copy","set","add","subtract","multiply","scale","normalize","dot","Vec3Func.length","Vec3Func.distance","Vec3Func.squaredLength","Vec3Func.squaredDistance","Vec3Func.dot","Vec3Func.exactEquals","Vec3Func.angle","tempVec3","ID","scale","length","ID","ID","copy","set","add","scale","length","normalize","dot","lerp","identity","multiply","invert","dot","copy","vec4.copy","set","vec4.set","add","vec4.add","scale","vec4.scale","vec4.dot","lerp","vec4.lerp","vec4.length","vec4.normalize","QuatFunc.dot","copy","set","identity","invert","multiply","translate","scale","rotate","vec3.length","te","fromQuat","scale","Mat4Func.getMaxScaleOnAxis","Mat4Func.determinant","invert","ID","length","p","useRef","useState","useCallback","options","calculatePlaneSize","distance","vertexShader","fragmentShader","useRef","angle","useMemo","values","progress","angle","useMemo","useMemo"],"sources":["https:/framerusercontent.com/modules/yiDyco0u2VIMCjawUp4K/SbAiryFn9g8ffjbuHQHj/GLUtils.js","https:/framer.com/m/GLUtils-cYf4.js","https:/framerusercontent.com/modules/MpdGPgep8CrmVuG8IclI/3flka5fkGcFUNVW00KRS/OGLUtils.js","https:/framer.com/m/OGLUtils-LEvG.js","https:/framerusercontent.com/modules/iz4j9aR1Hz2B8RkMogH4/AGDgcLdj5rKsWYMCweUZ/UseVariantValue.js","https:/framer.com/m/UseVariantValue-mxjI.js","https:/framerusercontent.com/modules/3Dc1qksRQy0igUBXLpC8/O0d7Tn7RulZ8jPX1N6S2/UseAnimatedValue.js","https:/framer.com/m/UseAnimatedValue-6Bkx.js","https:/framerusercontent.com/modules/DGJpj5NFNaYVLbwIQLV3/ITjnQ5HfCGlk0h6nR2c1/UseMedia.js","https:/framer.com/m/UseMedia-AW14.js","https:/unpkg.com/ogl@1.0.11/src/math/functions/Vec3Func.js","https:/unpkg.com/ogl@1.0.11/src/math/Vec3.js","https:/unpkg.com/ogl@1.0.11/src/core/Geometry.js","https:/unpkg.com/ogl@1.0.11/src/core/Program.js","https:/unpkg.com/ogl@1.0.11/src/core/Renderer.js","https:/unpkg.com/ogl@1.0.11/src/math/functions/Vec4Func.js","https:/unpkg.com/ogl@1.0.11/src/math/functions/QuatFunc.js","https:/unpkg.com/ogl@1.0.11/src/math/Quat.js","https:/unpkg.com/ogl@1.0.11/src/math/functions/Mat4Func.js","https:/unpkg.com/ogl@1.0.11/src/math/Mat4.js","https:/unpkg.com/ogl@1.0.11/src/math/functions/EulerFunc.js","https:/unpkg.com/ogl@1.0.11/src/math/Euler.js","https:/unpkg.com/ogl@1.0.11/src/core/Transform.js","https:/unpkg.com/ogl@1.0.11/src/core/Camera.js","https:/unpkg.com/ogl@1.0.11/src/math/functions/Mat3Func.js","https:/unpkg.com/ogl@1.0.11/src/math/Mat3.js","https:/unpkg.com/ogl@1.0.11/src/core/Mesh.js","https:/unpkg.com/ogl@1.0.11/src/core/Texture.js","https:/unpkg.com/ogl@1.0.11/src/core/RenderTarget.js","https:/unpkg.com/ogl@1.0.11/src/extras/Plane.js","https:/unpkg.com/ogl@1.0.11/src/extras/Box.js","https:/unpkg.com/ogl@1.0.11/src/extras/Sphere.js","https:/unpkg.com/ogl@1.0.11/src/extras/Cylinder.js","https:/unpkg.com/ogl@1.0.11/src/extras/Triangle.js","https:/unpkg.com/ogl@1.0.11/src/extras/Torus.js","https:/unpkg.com/ogl@1.0.11/src/extras/Orbit.js","https:/unpkg.com/ogl@1.0.11/src/extras/Raycast.js","https:/unpkg.com/ogl@1.0.11/src/extras/Curve.js","https:/unpkg.com/ogl@1.0.11/src/extras/path/CubicBezierSegment.js","https:/unpkg.com/ogl@1.0.11/src/extras/path/QuadraticBezierSegment.js","https:/unpkg.com/ogl@1.0.11/src/extras/path/LineSegment.js","https:/unpkg.com/ogl@1.0.11/src/extras/path/Path.js","https:/unpkg.com/ogl@1.0.11/src/extras/Tube.js","https:/unpkg.com/ogl@1.0.11/src/extras/Post.js","https:/unpkg.com/ogl@1.0.11/src/extras/Animation.js","https:/unpkg.com/ogl@1.0.11/src/extras/Skin.js","https:/unpkg.com/ogl@1.0.11/src/extras/Flowmap.js","https:/unpkg.com/ogl@1.0.11/src/extras/GPGPU.js","https:/unpkg.com/ogl@1.0.11/src/extras/Polyline.js","https:/unpkg.com/ogl@1.0.11/src/extras/Shadow.js","https:/unpkg.com/ogl@1.0.11/src/extras/KTXTexture.js","https:/unpkg.com/ogl@1.0.11/src/extras/TextureLoader.js","https:/unpkg.com/ogl@1.0.11/src/extras/GLTFAnimation.js","https:/unpkg.com/ogl@1.0.11/src/extras/GLTFSkin.js","https:/unpkg.com/ogl@1.0.11/src/extras/InstancedMesh.js","https:/unpkg.com/ogl@1.0.11/src/extras/GLTFLoader.js","https:/unpkg.com/ogl@1.0.11/src/extras/WireMesh.js","https:/unpkg.com/ogl@1.0.11/src/extras/helpers/AxesHelper.js","https:/unpkg.com/ogl@1.0.11/src/extras/helpers/GridHelper.js","https:/unpkg.com/ogl@1.0.11/src/extras/helpers/VertexNormalsHelper.js","https:/unpkg.com/ogl@1.0.11/src/extras/helpers/FaceNormalsHelper.js","https:/unpkg.com/ogl@1.0.11/src/extras/Texture3D.js","https:/unpkg.com/ogl","https:/framerusercontent.com/modules/Qdd3eGacdk0a7XalD9lO/LmjERPAe2BydyHLwJYQM/UseOGLScene.js","https:/framer.com/m/UseOGLScene-gg2G.js","https:/framerusercontent.com/modules/mSJ52dBkVivlfYMsRpwj/z319KePspYG0E1KkmAJd/UseSetup.js","https:/framerusercontent.com/modules/jypow408LDgPDnL677k2/Dg0auyGnIrsdg2LBcXmt/Shaders.js","https:/framerusercontent.com/modules/7zxjrN9X6oe3IFas7UpS/imR8plZxz6TwO8xlwuod/OGL.js","https:/framerusercontent.com/modules/oaA9N1sWyc1tB57T7xaj/YxlTLBSLBUyLyALkWkvh/Unfocused.js","https:/framerusercontent.com/modules/bjUTEQt5uFu8cIOVtWXD/r674MsvdtSSHCQGPTaai/FramerIcon.js","https:/framerusercontent.com/modules/VTUDdizacRHpwbkOamr7/AykinQJbgwl92LvMGZwu/constants.js","https:/framerusercontent.com/modules/D4TWeLfcxT6Tysr2BlYg/iZjmqdxVx1EOiM3k1FaW/useOnNavigationTargetChange.js","https:/framerusercontent.com/modules/ExNgrA7EJTKUPpH6vIlN/eiOrSJ2Ab5M9jPCvVwUz/useConstant.js","https:/framerusercontent.com/modules/D2Lz5CmnNVPZFFiZXalt/QaCzPbriZBfXWZIIycFI/colorFromToken.js","https:/framerusercontent.com/modules/3mKFSGQqKHV82uOV1eBc/5fbRLvOpxZC0JOXugvwm/isMotionValue.js","https:/framerusercontent.com/modules/xDiQsqBGXzmMsv7AlEVy/uhunpMiNsbXxzjlXsg1y/useUniqueClassName.js","https:/framerusercontent.com/modules/ETACN5BJyFTSo0VVDJfu/NHRqowOiXkF9UwOzczF7/variantUtils.js","https:/framerusercontent.com/modules/eMBrwoqQK7h6mEeGQUH8/GuplvPJVjmxpk9zqOTcb/isBrowser.js","https:/framerusercontent.com/modules/v9AWX2URmiYsHf7GbctE/XxKAZ9KlhWqf5x1JMyyF/useOnChange.js","https:/framerusercontent.com/modules/kNDwabfjDEb3vUxkQlZS/fSIr3AOAYbGlfSPgXpYu/useAutoMotionValue.js","https:/framerusercontent.com/modules/zGkoP8tPDCkoBzMdt5uq/0zFSjxIYliHxrQQnryFX/useControlledState.js","https:/framerusercontent.com/modules/5SM58HxZHxjjv7aLMOgQ/WXz9i6mVki0bBCrKdqB3/propUtils.js","https:/framerusercontent.com/modules/cuQH4dmpDnV8YK1mSgQX/KqRXqunFjE6ufhpc7ZRu/useFontControls.js","https:/framerusercontent.com/modules/afBE9Yx1W6bY5q32qPxe/m3q7puE2tbo1S2C0s0CT/useRenderTarget.js","https:/framerusercontent.com/modules/G4IfyjvwmaeSBpdb4TWu/OIjZRBmWDcIE2B6qgG1j/index.js","https:/framer.com/m/framer/default-utils.js@^0.45.0"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{ControlType,useIsStaticRenderer}from\"framer\";import{useEffect,useMemo,useState}from\"react\";export default function GLUtils(props){return /*#__PURE__*/_jsx(\"div\",{});}export const DEFAULT_IMAGE=\"https://framerusercontent.com/images/6MTlf3HAzQ2kjMqPur2sdbkznQ.png?scale-down-to=2048\";export const DEFAULT_IMAGE_FLOWER=\"https://framerusercontent.com/images/cz3ePY6OFcSC4EItQFuQxLrQbBA.jpg\";export const DEFAULT_IMAGE_FLOWER_DARK=\"https://framerusercontent.com/images/l4gFK0Yuorz9j7RwU2EbwWxpw.jpg\";export const DEFAULT_ALT=\"Default image\";export const DEFAULT_ALT_FLOWER=\"A wilted tulip with red and yellow petals.\";export const DEFAULT_ALT_FLOWER_DARK=\"A bright yellow sunflower against a dark background.\";export function degToRad(degrees){return degrees*(Math.PI/180);}export function colorToVec4(color){let actualColor=color;if(color.startsWith(\"var(\")){const varMatch=color.match(/var\\([^,]+,\\s*(.+)\\)$/);if(varMatch){actualColor=varMatch[1].trim();}else{console.warn(\"无法解析 CSS 变量:\",color);return[0,0,0,1];}}actualColor=actualColor.replace(/\\s/g,\"\");let r,g,b,a=1;// 处理 rgb() 和 rgba() 格式\nconst rgbaMatch=actualColor.match(/rgba?\\((\\d+),(\\d+),(\\d+)(?:,([0-9]*\\.?[0-9]+))?\\)/);if(rgbaMatch){r=parseInt(rgbaMatch[1]);g=parseInt(rgbaMatch[2]);b=parseInt(rgbaMatch[3]);if(rgbaMatch[4]!==undefined){a=parseFloat(rgbaMatch[4]);}return[r/255,g/255,b/255,a];}// 处理十六进制格式 (#RGB 或 #RRGGBB)\nconst hexMatch=actualColor.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);if(hexMatch){const hex=hexMatch[1];if(hex.length===3){// 处理 #RGB 格式，扩展为 #RRGGBB\nr=parseInt(hex[0]+hex[0],16);g=parseInt(hex[1]+hex[1],16);b=parseInt(hex[2]+hex[2],16);}else{// 处理 #RRGGBB 格式\nr=parseInt(hex.substr(0,2),16);g=parseInt(hex.substr(2,2),16);b=parseInt(hex.substr(4,2),16);}return[r/255,g/255,b/255,a];}console.warn(\"无法解析颜色格式:\",color);return[0,0,0,1];}export function colorToVec3(color){let actualColor=color;if(color.startsWith(\"var(\")){const varMatch=color.match(/var\\([^,]+,\\s*(.+)\\)$/);if(varMatch){actualColor=varMatch[1].trim();}else{console.warn(\"无法解析 CSS 变量:\",color);return[0,0,0];}}actualColor=actualColor.replace(/\\s/g,\"\");let r,g,b;// 处理 rgb() 和 rgba() 格式\nconst rgbaMatch=actualColor.match(/rgba?\\((\\d+),(\\d+),(\\d+)(?:,([0-9]*\\.?[0-9]+))?\\)/);if(rgbaMatch){r=parseInt(rgbaMatch[1]);g=parseInt(rgbaMatch[2]);b=parseInt(rgbaMatch[3]);return[r/255,g/255,b/255];}// 处理十六进制格式 (#RGB 或 #RRGGBB)\nconst hexMatch=actualColor.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);if(hexMatch){const hex=hexMatch[1];if(hex.length===3){// 处理 #RGB 格式，扩展为 #RRGGBB\nr=parseInt(hex[0]+hex[0],16);g=parseInt(hex[1]+hex[1],16);b=parseInt(hex[2]+hex[2],16);}else{// 处理 #RRGGBB 格式\nr=parseInt(hex.substr(0,2),16);g=parseInt(hex.substr(2,2),16);b=parseInt(hex.substr(4,2),16);}return[r/255,g/255,b/255];}console.warn(\"无法解析颜色格式:\",color);return[0,0,0];}export const useDarkMode=()=>{const[isDarkMode,setIsDarkMode]=useState(false);useEffect(()=>{const mediaQuery=window.matchMedia(\"(prefers-color-scheme: dark)\");setIsDarkMode(mediaQuery.matches);const handler=e=>setIsDarkMode(e.matches);mediaQuery.addListener(handler);return()=>mediaQuery.removeListener(handler);},[]);return isDarkMode;};export const CompatibleMedia=({mediaType,mediaSrc,imageAlt,fit,loop,style={},...props})=>{const isStaticRenderer=useIsStaticRenderer();const defaultStyle={width:\"100%\",height:\"100%\",objectFit:fit};if(mediaType===\"image\"){return /*#__PURE__*/_jsx(\"img\",{src:mediaSrc,alt:imageAlt,style:{...defaultStyle,...style},crossOrigin:\"anonymous\"});}else{return /*#__PURE__*/_jsx(\"video\",{src:mediaSrc,autoPlay:!isStaticRenderer,muted:true,playsInline:true,loop:loop,style:{...defaultStyle,...style},crossOrigin:\"anonymous\"});}};export const useMediaSource=(media,file,urlVideo,upVideo,defaultImage,darkImage,dark,placeholder=\"flower_dark\")=>{const isDarkMode=useDarkMode();const getPlaceholderValues=useMemo(()=>{const placeholderMap={reveals:{image:\"https://framerusercontent.com/images/6MTlf3HAzQ2kjMqPur2sdbkznQ.png?scale-down-to=2048\",alt:\"reveals original image.\"},flower_light:{image:\"https://framerusercontent.com/images/cz3ePY6OFcSC4EItQFuQxLrQbBA.jpg\",alt:\"A wilted tulip with red and yellow petals.\"},flower_dark:{image:\"https://framerusercontent.com/images/l4gFK0Yuorz9j7RwU2EbwWxpw.jpg\",alt:\"A bright yellow sunflower against a dark background.\"},arch_dark:{image:\"https://framerusercontent.com/images/kW9tNTLiYRYp7LGxfxbuywTR4I.jpg\",alt:\"A white sphere suspended among curved black metallic ribbons.\"},dice_dark:{image:\"https://framerusercontent.com/images/bXMH0vhJVBjFjMhCnvcVuK0KA0.jpg\",alt:\"A cluster of smooth, reflective metallic shapes on a dark background.\"},astronaut:{image:\"https://framerusercontent.com/images/K54OdkNAJ7dNPCQlcqviSKRrXAY.jpg?width=1920&height=1282\",alt:\"Close-up of an astronaut’s face inside a reflective helmet.\"},silhouetted:{image:\"https://framerusercontent.com/images/CeZXMYBfdBEchX3ub79dGEHlyCQ.jpg?width=1920&height=1280\",alt:\"Silhouetted figure walking behind frosted glass panels.\"},structure:{image:\"https://framerusercontent.com/images/Ud6oqYomUb6OGy9FMr1VmAPXIU.jpg?width=1920&height=1280\",alt:\"Abstract red metal structure against a clear sky.\"},dizzy:{image:\"https://framerusercontent.com/images/JJmc0OZsfY0HhNmbr8W4De17Pw.jpg?width=1920&height=1343\",alt:\"Blurred portrait of a person in motion with hands near the head.\"},hand:{image:\"https://framerusercontent.com/images/qAQg0suczEYw3OPZEmj7XxyW0.jpg?width=1920&height=1440\",alt:\"A hand reaching toward a glowing blue light.\"},porsche:{image:\"https://framerusercontent.com/images/9bPvA91sUvfr4lgE2gQ1MbfUMDs.jpg?width=1920&height=1280\",alt:\"A silver sports car in the rain, seen from the rear side.\"},wheat:{image:\"https://framerusercontent.com/images/jhGTXFJ0WKeCaZXfyfE5pSL1Pbc.jpg?width=1920&height=1280\",alt:\"Golden grass glistening in sunlight.\"}};return placeholderMap[placeholder]||placeholderMap.flower_dark;},[placeholder]);const imageSrc=useMemo(()=>{if(dark&&isDarkMode&&darkImage?.src){return darkImage.src;}return defaultImage?.src||getPlaceholderValues.image;},[isDarkMode,defaultImage,darkImage,dark,getPlaceholderValues.image]);const imageAlt=useMemo(()=>{if(media===\"image\"){if(dark&&isDarkMode&&darkImage?.alt){return darkImage.alt;}return defaultImage?.alt||getPlaceholderValues.alt;}else if(media===\"cms\"){if(dark&&isDarkMode&&darkImage?.alt){return darkImage.alt;}return defaultImage?.alt||getPlaceholderValues.alt;}},[isDarkMode,defaultImage,darkImage,dark,getPlaceholderValues.alt]);const mediaSrc=useMemo(()=>{if(media===\"image\"){return imageSrc;}return file===\"url\"?urlVideo:upVideo;},[media,file,imageSrc,urlVideo,upVideo,defaultImage,darkImage,dark]);const mediaType=useMemo(()=>{const mediaTypeMap={image:\"image\",cms:\"image\",video:\"video\"};return mediaTypeMap[media]||\"video\";},[media]);return{imageSrc,imageAlt,mediaSrc,mediaType};};export const propertyControls={media:{type:{type:ControlType.Enum,title:\"Media\",options:[\"image\",\"video\"],optionTitles:[\"Image\",\"Video\"],displaySegmentedControl:true,defaultValue:\"image\"},file:{type:ControlType.Enum,title:\"File\",options:[\"url\",\"upload\"],optionTitles:[\"URL\",\"Upload\"],displaySegmentedControl:true,defaultValue:\"url\",hidden(props){return props.type!==\"video\";}},defaultImage:{type:ControlType.ResponsiveImage,title:\"Image\",hidden(props){return props.type!==\"image\";}},// dark: {\n//     type: ControlType.Boolean,\n//     title: \"Dark Mode\",\n//     defaultValue: false,\n//     hidden(props) {\n//         return props.type !== \"image\"\n//     },\n// },\n// darkImage: {\n//     type: ControlType.ResponsiveImage,\n//     title: \"Dark Image\",\n//     hidden(props) {\n//         return props.dark\n//             ? props.type === \"image\"\n//                 ? false\n//                 : true\n//             : true\n//     },\n// },\nurlVideo:{type:ControlType.String,title:\"URL\",defaultValue:\"https://framerusercontent.com/assets/Jhocnrz23GM4PK1CT7mBiwAu5U.mp4\",// description: \"Use video will affect performance more.\",\nhidden(props){return props.file===\"url\"?props.type===\"video\"?false:true:true;}},upVideo:{type:ControlType.File,title:\"Upload\",allowedFileTypes:[\"mp4\",\"webm\"],description:\"Use video will affect performance more.\",hidden(props){return props.file===\"upload\"?props.type===\"video\"?false:true:true;}},loop:{type:ControlType.Boolean,title:\"Loop\",defaultValue:true,hidden(props){return props.type!==\"video\";}}},size:{fit:{type:ControlType.Enum,title:\"Fit\",options:[\"cover\",\"contain\"],optionTitles:[\"Cover\",\"Contain\"],defaultValue:\"cover\"}},animateControls:{type:{type:ControlType.Enum,title:\"Type\",options:[\"disable\",\"appear\",\"enter\",\"transform\",\"variant\"],optionTitles:[\"Disable\",\"Appear\",\"Enter\",\"Transform\",\"Variant\"],defaultValue:\"appear\"},replay:{type:ControlType.Boolean,title:\"Replay\",defaultValue:true,hidden(props){return props.type!==\"enter\";}},trigger:{type:ControlType.Enum,title:\"Trigger\",options:[\"layer\",\"section\"],optionTitles:[\"Layer in View\",\"Section in View\"],defaultValue:\"layer\",hidden(props){return props.type==\"appear\"||props.type==\"disable\"||props.type==\"variant\";}},section:{// @ts-ignore\ntype:ControlType.ScrollSectionRef,title:\"Section\",hidden(props){if((props.type===\"transform\"||props.type===\"enter\")&&props.trigger===\"section\"){return false;}return true;}},amount:{type:ControlType.Enum,title:\"Amount\",options:[1,.5,0],optionTitles:[\"Top\",\"Center\",\"Bottom\"],displaySegmentedControl:true,defaultValue:0,description:\"Play animation when how much of the media comes into view.\",hidden(props){return props.type!==\"enter\";}},viewport:{type:ControlType.Enum,title:\"Viewport\",options:[\"top\",\"center\",\"bottom\"],optionTitles:[\"Top\",\"Center\",\"Bottom\"],displaySegmentedControl:true,defaultValue:\"center\",description:\"Start transforming when how much of the media comes into view.\",hidden(props){return props.type!==\"transform\";}}},accessibility:{accessibility:{type:ControlType.Object,title:\"Accessibility\",buttonTitle:\"Aria Label\",icon:\"boolean\",// description: \"Learn more on [Reveals](https://reveals.cool).\",\ncontrols:{enableAria:{type:ControlType.Boolean,title:\"Aria Label\",defaultValue:false},compatibility:{type:ControlType.Boolean,title:\"Compatibility\",defaultValue:false,description:\"Disable effects and use regular *image/video* elements. e.g. use on Phone layout for better performance.\"},reduce:{type:ControlType.Enum,title:\"Reduce Motion\",displaySegmentedControl:true,segmentedControlDirection:\"horizontal\",options:[true,false],optionTitles:[\"Allow\",\"Block\"],defaultValue:false,description:\"Whether to allow Reduce Motion to control animation.\"},renderer:{type:ControlType.Enum,title:\"Renderer\",displaySegmentedControl:true,segmentedControlDirection:\"horizontal\",options:[\"auto\",\"always\"],optionTitles:[\"Auto\",\"Always\"],defaultValue:\"auto\",description:\"Control when the renderer will render.\"}}},ariaLabel:{type:ControlType.String,title:\"Aria Label\",defaultValue:\"\",hidden(props){return!props.accessibility.enableAria;}}},eventHandler:{onLoad:{type:ControlType.EventHandler,title:\"Load\"},onError:{type:ControlType.EventHandler,title:\"Error\"},onVideoEnd:{type:ControlType.EventHandler,title:\"Video End\"},onAnimationComplete:{type:ControlType.EventHandler,title:\"Animation Complete\"}}};\nexport const __FramerMetadata__ = {\"exports\":{\"DEFAULT_ALT_FLOWER_DARK\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"CompatibleMedia\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useDarkMode\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DEFAULT_ALT_FLOWER\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DEFAULT_IMAGE_FLOWER\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"colorToVec3\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DEFAULT_IMAGE_FLOWER_DARK\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"propertyControls\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"reactComponent\",\"name\":\"GLUtils\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"colorToVec4\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useMediaSource\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DEFAULT_IMAGE\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DEFAULT_ALT\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"degToRad\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./GLUtils.map","/*\n * GLUtils\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/yiDyco0u2VIMCjawUp4K/SbAiryFn9g8ffjbuHQHj/GLUtils.js\"\nexport { default } from \"https://framerusercontent.com/modules/yiDyco0u2VIMCjawUp4K/SbAiryFn9g8ffjbuHQHj/GLUtils.js\"\n","import{jsx as _jsx}from\"react/jsx-runtime\";export default function OGLUtils(props){return /*#__PURE__*/_jsx(\"div\",{});}export const calculatePlaneSize=(mediaWidth,mediaHeight,containerWidth,containerHeight,fitMode)=>{const mediaAspect=mediaWidth/mediaHeight;const containerAspect=containerWidth/containerHeight;let planeWidth,planeHeight;if(fitMode===\"cover\"){if(mediaAspect>containerAspect){planeHeight=containerHeight;planeWidth=containerHeight*mediaAspect;}else{planeWidth=containerWidth;planeHeight=containerWidth/mediaAspect;}}else if(fitMode===\"contain\"){if(mediaAspect>containerAspect){planeWidth=containerWidth;planeHeight=containerWidth/mediaAspect;}else{planeHeight=containerHeight;planeWidth=containerHeight*mediaAspect;}}return{width:planeWidth,height:planeHeight};};export const defaultPostProcessVertexShader=`\n    attribute vec2 uv;\n    attribute vec3 position;\n\n    varying vec2 vUv;\n\n    void main() {\n        vUv = uv;\n        gl_Position = vec4(position, 1.0);\n    }\n`;export const defaultPostProcessFragmentShader=`\n    precision highp float;\n\n    uniform sampler2D uTexture;\n    uniform float uTime;\n    uniform vec2 uResolution;\n\n    varying vec2 vUv;\n\n    void main() {\n        vec4 color = texture2D(uTexture, vUv);\n        gl_FragColor = color;\n    }\n`;export const defaultVertexShader=`\n        attribute vec3 position;\n        attribute vec2 uv;\n        uniform mat4 modelViewMatrix;\n        uniform mat4 projectionMatrix;\n        varying vec2 vUv;\n        \n        void main() {\n            vUv = uv;\n            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n        }\n    `;export const defaultFragmentShader=`\n        precision mediump float;\n        \n        uniform sampler2D uTexture;\n        varying vec2 vUv;\n        \n        void main() {\n            vec4 textureColor = texture2D(uTexture, vUv);\n            gl_FragColor = textureColor;\n        }\n    `;\nexport const __FramerMetadata__ = {\"exports\":{\"defaultVertexShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"reactComponent\",\"name\":\"OGLUtils\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultPostProcessVertexShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultFragmentShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultPostProcessFragmentShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"calculatePlaneSize\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./OGLUtils.map","/*\n * OGLUtils\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/MpdGPgep8CrmVuG8IclI/3flka5fkGcFUNVW00KRS/OGLUtils.js\"\nexport { default } from \"https://framerusercontent.com/modules/MpdGPgep8CrmVuG8IclI/3flka5fkGcFUNVW00KRS/OGLUtils.js\"\n","import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef,useState}from\"react\";import{animate,MotionValue}from\"framer-motion\";export default function VariantValue(props){return /*#__PURE__*/_jsx(\"div\",{});}export const useVariantValues=(values,transition,enabled=true)=>{const[isAnimating,setIsAnimating]=useState(false);const motionValuesRef=useRef({});// 确保 motionValuesRef.current 拥有所有当前值的 MotionValue 实例\nfor(const key in values){if(!motionValuesRef.current[key]){motionValuesRef.current[key]=new MotionValue(values[key]);}}// Effect 用于处理值的更新（带或不带动画）\nuseEffect(()=>{// 如果禁用了动画，立即设置值并确保动画状态为 false\nif(!enabled){for(const key in values){const mv=motionValuesRef.current[key];const targetValue=values[key];if(mv&&mv.get()!==targetValue){// 直接设置值，不进行动画\nmv.set(targetValue);}}// 确保动画状态为 false\nif(isAnimating){setIsAnimating(false);}return;// 提前退出 effect\n}// --- 如果启用了动画，执行以下逻辑 ---\nconst allAnimations=[];let hasStartedAnimation=false;for(const key in values){const mv=motionValuesRef.current[key];const targetValue=values[key];if(mv&&mv.get()!==targetValue){hasStartedAnimation=true;const animationPromise=animate(mv,targetValue,transition);allAnimations.push(animationPromise);}}if(hasStartedAnimation){setIsAnimating(true);}// 等待所有动画完成\nPromise.all(allAnimations).then(()=>{if(hasStartedAnimation){setIsAnimating(false);}});// 清理函数\nreturn()=>{allAnimations.forEach(animationControl=>{animationControl.stop();});};// 将 enabled 添加到依赖数组\n},[JSON.stringify(values),transition,enabled]);return{variantValue:motionValuesRef.current,isVariantUpdating:isAnimating};};\nexport const __FramerMetadata__ = {\"exports\":{\"useVariantValues\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"reactComponent\",\"name\":\"VariantValue\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./UseVariantValue.map","/*\n * UseVariantValue\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/iz4j9aR1Hz2B8RkMogH4/AGDgcLdj5rKsWYMCweUZ/UseVariantValue.js\"\nexport { default } from \"https://framerusercontent.com/modules/iz4j9aR1Hz2B8RkMogH4/AGDgcLdj5rKsWYMCweUZ/UseVariantValue.js\"\n","import{jsx as _jsx}from\"react/jsx-runtime\";export default function AnimatedValue(props){return /*#__PURE__*/_jsx(\"div\",{});}import{useRef,useEffect,useState}from\"react\";import{useInView,useScroll}from\"framer-motion\";import{animate}from\"framer-motion\";export function useAnimatedValues(config,animateProp,transition,mountRef,enable=true){const values=useRef(Object.fromEntries(Object.entries(config).map(([key,{from}])=>[key,from])));const[isUpdating,setIsUpdating]=useState(false);const animationControlsRef=useRef(null);const targetRef=enable?animateProp.trigger===\"section\"&&animateProp.section?animateProp.section:mountRef:mountRef;const isInView=useInView(targetRef,{once:!animateProp.replay,amount:animateProp.amount});const{scrollYProgress}=useScroll({target:targetRef,layoutEffect:false,offset:animateProp.viewport===\"top\"?[\"start start\",\"end start\"]:animateProp.viewport===\"bottom\"?[\"start end\",\"start start\"]:[\"start center\",\"end center\"]});const[scrollProgress,setScrollProgress]=useState(0);// 只有在启用时才监听滚动进度变化\nuseEffect(()=>{if(enable&&animateProp.type===\"transform\"){const unsubscribe=scrollYProgress.onChange(latest=>{setScrollProgress(1-latest);});return unsubscribe;}},[scrollYProgress,animateProp.type,enable]);useEffect(()=>{// 清理之前的动画\nif(animationControlsRef.current){animationControlsRef.current.stop();animationControlsRef.current=null;}// 如果禁用，重置到初始值\nif(!enable){Object.entries(config).forEach(([key,{from}])=>{values.current[key]=from;});// 不需要手动设置 isUpdating，因为没有动画在运行\nreturn;}const targets={};const animatableTargets={};let shouldAnimate=false;let hasAnimatableValues=false;Object.entries(config).forEach(([key,{from,to}])=>{let targetValue;switch(animateProp.type){case\"appear\":targetValue=to;shouldAnimate=true;break;case\"enter\":targetValue=isInView?to:from;shouldAnimate=true;break;case\"transform\":targetValue=from+(to-from)*scrollProgress;shouldAnimate=true;break;default:values.current[key]=from;return;}targets[key]=targetValue;// 只有当值确实需要改变时才加入动画目标\nif(Math.abs(values.current[key]-targetValue)>.001){animatableTargets[key]=targetValue;hasAnimatableValues=true;}else{// 直接设置不需要动画的值\nvalues.current[key]=targetValue;}});// 如果不需要动画或没有可动画的值，直接返回\nif(!shouldAnimate||!hasAnimatableValues){return;}const controls=animate(values.current,animatableTargets,{...transition,restDelta:.001,restSpeed:.001,onComplete:()=>{setIsUpdating(false);animationControlsRef.current=null;},onUpdate:latest=>{if(!isUpdating){setIsUpdating(true);}}});animationControlsRef.current=controls;return()=>{if(controls){controls.stop();// setIsUpdating(false)\nanimationControlsRef.current=null;}};},[isInView,scrollProgress,animateProp.type,enable]);return{values:values.current,isUpdating};}export function useAnimatedProgress(animateProp,transition,mountRef,enable=true){const progressRef=useRef(1);const[progress,setProgress]=useState(1);const[isUpdatingProgress,setIsUpdatingProgress]=useState(false);const[scrollProgress,setScrollProgress]=useState(1);// 滚动动画 - 根据 enable 状态决定监听目标\nconst isInView=useInView(enable&&animateProp.trigger===\"section\"&&animateProp.section?animateProp.section:mountRef,{once:enable?!animateProp.replay:true,amount:enable?animateProp.amount:0});// 滚动进度 - 根据 enable 状态决定监听目标\nconst{scrollYProgress}=useScroll({target:enable&&animateProp.trigger===\"section\"&&animateProp.section?animateProp.section:mountRef,layoutEffect:false,offset:enable&&animateProp.viewport===\"top\"?[\"start start\",\"end start\"]:enable&&animateProp.viewport===\"bottom\"?[\"start end\",\"start start\"]:[\"start center\",\"end center\"]});// 监听滚动进度变化\nuseEffect(()=>{if(enable&&animateProp.type===\"transform\"){const unsubscribe=scrollYProgress.onChange(latest=>{setScrollProgress(1-latest);});return unsubscribe;}},[scrollYProgress,animateProp.type,enable]);// 动画控制逻辑\nuseEffect(()=>{// 如果禁用了 Hook，重置为默认状态\nif(!enable){progressRef.current=1;setProgress(1);setIsUpdatingProgress(false);return;}let targetValue=1;let shouldAnimate=false;switch(animateProp.type){case\"appear\":// 直接动画\ntargetValue=0;shouldAnimate=true;break;case\"enter\":// 滚动动画\ntargetValue=isInView?0:1;shouldAnimate=true;break;case\"transform\":// 滚动进度\ntargetValue=scrollProgress;shouldAnimate=true;break;default:progressRef.current=1;setProgress(1);setIsUpdatingProgress(false);return;}if(!shouldAnimate)return;setIsUpdatingProgress(true);const controls=animate(progressRef.current,targetValue,{...transition,restDelta:.001,restSpeed:.001,onUpdate:latest=>{progressRef.current=latest;setProgress(latest);},onComplete:()=>{setIsUpdatingProgress(false);}});return()=>{controls.stop();};},[enable,isInView,scrollProgress,animateProp.type,transition]);return{progress,isUpdatingProgress};}\nexport const __FramerMetadata__ = {\"exports\":{\"useAnimatedProgress\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"reactComponent\",\"name\":\"AnimatedValue\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"useAnimatedValues\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./UseAnimatedValue.map","/*\n * UseAnimatedValue\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/3Dc1qksRQy0igUBXLpC8/O0d7Tn7RulZ8jPX1N6S2/UseAnimatedValue.js\"\nexport { default } from \"https://framerusercontent.com/modules/3Dc1qksRQy0igUBXLpC8/O0d7Tn7RulZ8jPX1N6S2/UseAnimatedValue.js\"\n","import{jsx as _jsx}from\"react/jsx-runtime\";import{useRef,useEffect,useState,useCallback}from\"react\";export default function Media(props){return /*#__PURE__*/_jsx(\"div\",{});}const initialState={media:null,dimensions:{width:0,height:0},isLoaded:false,isError:false,isVideoPlaying:false,playVideo:null,pauseVideo:null};export function useMedia(src,mediaType=\"image\",loop=true,autoplay=true){const[mediaState,setMediaState]=useState(initialState);const currentMediaRef=useRef(null);const loadIdRef=useRef(0);const cleanupCurrentMedia=useCallback(()=>{const current=currentMediaRef.current;if(!current)return;if(current instanceof HTMLVideoElement){try{current.pause();}catch{}try{current.removeAttribute(\"src\");current.load();}catch{}}currentMediaRef.current=null;},[]);const loadMedia=useCallback((mediaSrc,type)=>{if(!mediaSrc){cleanupCurrentMedia();setMediaState(initialState);return()=>{};}const loadId=++loadIdRef.current;let disposed=false;const isCurrent=()=>!disposed&&loadIdRef.current===loadId&&currentMediaRef.current!==null;cleanupCurrentMedia();setMediaState(initialState);if(type===\"image\"){const img=new Image;img.crossOrigin=\"anonymous\";currentMediaRef.current=img;const handleLoad=()=>{if(!isCurrent()||currentMediaRef.current!==img)return;setMediaState({media:img,dimensions:{width:img.naturalWidth||img.width,height:img.naturalHeight||img.height},isLoaded:true,isError:false,isVideoPlaying:false,playVideo:null,pauseVideo:null});};const handleError=()=>{if(!isCurrent()||currentMediaRef.current!==img)return;setMediaState({media:null,dimensions:{width:0,height:0},isLoaded:false,isError:true,isVideoPlaying:false,playVideo:null,pauseVideo:null});};img.addEventListener(\"load\",handleLoad);img.addEventListener(\"error\",handleError);img.src=mediaSrc;return()=>{disposed=true;img.removeEventListener(\"load\",handleLoad);img.removeEventListener(\"error\",handleError);if(currentMediaRef.current===img){currentMediaRef.current=null;}};}const video=document.createElement(\"video\");currentMediaRef.current=video;video.crossOrigin=\"anonymous\";video.muted=true;video.loop=loop;video.autoplay=autoplay;video.playsInline=true;video.preload=\"auto\";// Safari / iPhone 更稳妥\nvideo.setAttribute(\"playsinline\",\"\");video.setAttribute(\"webkit-playsinline\",\"\");video.setAttribute(\"muted\",\"\");let firstFrameReady=false;const updateBaseVideoState=()=>{if(!isCurrent()||currentMediaRef.current!==video)return;setMediaState(prev=>({...prev,media:video,dimensions:{width:video.videoWidth||0,height:video.videoHeight||0},isError:false,playVideo:async()=>{try{await video.play();}catch(error){console.error(\"video.play() failed:\",error);throw error;}},pauseVideo:()=>{video.pause();}}));};const markFirstFrameReady=()=>{if(firstFrameReady||!isCurrent()||currentMediaRef.current!==video){return;}if(video.readyState<2)return;firstFrameReady=true;setMediaState(prev=>({...prev,media:video,dimensions:{width:video.videoWidth||0,height:video.videoHeight||0},isLoaded:true,isError:false,isVideoPlaying:!video.paused&&!video.ended,playVideo:async()=>{try{await video.play();}catch(error){console.error(\"video.play() failed:\",error);throw error;}},pauseVideo:()=>{video.pause();}}));};const handleLoadedMetadata=()=>{updateBaseVideoState();};const handleLoadedData=async()=>{markFirstFrameReady();if(!autoplay){try{if(video.currentTime!==0){video.currentTime=0;}}catch(error){console.warn(\"setting currentTime failed:\",error);}return;}try{await video.play();}catch(error){console.error(\"video autoplay failed:\",error);}};const handleCanPlay=()=>{markFirstFrameReady();};const handlePlaying=()=>{if(!isCurrent()||currentMediaRef.current!==video)return;setMediaState(prev=>({...prev,isVideoPlaying:true,isLoaded:prev.isLoaded||video.readyState>=2}));};const handlePause=()=>{if(!isCurrent()||currentMediaRef.current!==video)return;setMediaState(prev=>({...prev,isVideoPlaying:false}));};const handleEnded=()=>{if(!isCurrent()||currentMediaRef.current!==video)return;setMediaState(prev=>({...prev,isVideoPlaying:false}));};const handleError=()=>{if(!isCurrent()||currentMediaRef.current!==video)return;setMediaState({media:null,dimensions:{width:0,height:0},isLoaded:false,isError:true,isVideoPlaying:false,playVideo:null,pauseVideo:null});};video.addEventListener(\"loadedmetadata\",handleLoadedMetadata);video.addEventListener(\"loadeddata\",handleLoadedData);video.addEventListener(\"canplay\",handleCanPlay);video.addEventListener(\"playing\",handlePlaying);video.addEventListener(\"pause\",handlePause);video.addEventListener(\"ended\",handleEnded);video.addEventListener(\"error\",handleError);video.src=mediaSrc;video.load();return()=>{disposed=true;video.removeEventListener(\"loadedmetadata\",handleLoadedMetadata);video.removeEventListener(\"loadeddata\",handleLoadedData);video.removeEventListener(\"canplay\",handleCanPlay);video.removeEventListener(\"playing\",handlePlaying);video.removeEventListener(\"pause\",handlePause);video.removeEventListener(\"ended\",handleEnded);video.removeEventListener(\"error\",handleError);try{video.pause();}catch{}try{video.removeAttribute(\"src\");video.load();}catch{}if(currentMediaRef.current===video){currentMediaRef.current=null;}};},[autoplay,loop,cleanupCurrentMedia]);useEffect(()=>{if(!src){cleanupCurrentMedia();setMediaState(initialState);return;}const cleanup=loadMedia(src,mediaType);return()=>{if(cleanup)cleanup();};},[src,mediaType,loadMedia,cleanupCurrentMedia]);return mediaState;}\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"Media\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"useMedia\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./UseMedia.map","/*\n * UseMedia\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/DGJpj5NFNaYVLbwIQLV3/ITjnQ5HfCGlk0h6nR2c1/UseMedia.js\"\nexport { default } from \"https://framerusercontent.com/modules/DGJpj5NFNaYVLbwIQLV3/ITjnQ5HfCGlk0h6nR2c1/UseMedia.js\"\n","const EPSILON = 0.000001;\n\n/**\n * Calculates the length of a vec3\n *\n * @param {vec3} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport function length(a) {\n    let x = a[0];\n    let y = a[1];\n    let z = a[2];\n    return Math.sqrt(x * x + y * y + z * z);\n}\n\n/**\n * Copy the values from one vec3 to another\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the source vector\n * @returns {vec3} out\n */\nexport function copy(out, a) {\n    out[0] = a[0];\n    out[1] = a[1];\n    out[2] = a[2];\n    return out;\n}\n\n/**\n * Set the components of a vec3 to the given values\n *\n * @param {vec3} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} out\n */\nexport function set(out, x, y, z) {\n    out[0] = x;\n    out[1] = y;\n    out[2] = z;\n    return out;\n}\n\n/**\n * Adds two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {vec3} out\n */\nexport function add(out, a, b) {\n    out[0] = a[0] + b[0];\n    out[1] = a[1] + b[1];\n    out[2] = a[2] + b[2];\n    return out;\n}\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {vec3} out\n */\nexport function subtract(out, a, b) {\n    out[0] = a[0] - b[0];\n    out[1] = a[1] - b[1];\n    out[2] = a[2] - b[2];\n    return out;\n}\n\n/**\n * Multiplies two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {vec3} out\n */\nexport function multiply(out, a, b) {\n    out[0] = a[0] * b[0];\n    out[1] = a[1] * b[1];\n    out[2] = a[2] * b[2];\n    return out;\n}\n\n/**\n * Divides two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {vec3} out\n */\nexport function divide(out, a, b) {\n    out[0] = a[0] / b[0];\n    out[1] = a[1] / b[1];\n    out[2] = a[2] / b[2];\n    return out;\n}\n\n/**\n * Scales a vec3 by a scalar number\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec3} out\n */\nexport function scale(out, a, b) {\n    out[0] = a[0] * b;\n    out[1] = a[1] * b;\n    out[2] = a[2] * b;\n    return out;\n}\n\n/**\n * Calculates the euclidian distance between two vec3's\n *\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {Number} distance between a and b\n */\nexport function distance(a, b) {\n    let x = b[0] - a[0];\n    let y = b[1] - a[1];\n    let z = b[2] - a[2];\n    return Math.sqrt(x * x + y * y + z * z);\n}\n\n/**\n * Calculates the squared euclidian distance between two vec3's\n *\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {Number} squared distance between a and b\n */\nexport function squaredDistance(a, b) {\n    let x = b[0] - a[0];\n    let y = b[1] - a[1];\n    let z = b[2] - a[2];\n    return x * x + y * y + z * z;\n}\n\n/**\n * Calculates the squared length of a vec3\n *\n * @param {vec3} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\nexport function squaredLength(a) {\n    let x = a[0];\n    let y = a[1];\n    let z = a[2];\n    return x * x + y * y + z * z;\n}\n\n/**\n * Negates the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a vector to negate\n * @returns {vec3} out\n */\nexport function negate(out, a) {\n    out[0] = -a[0];\n    out[1] = -a[1];\n    out[2] = -a[2];\n    return out;\n}\n\n/**\n * Returns the inverse of the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a vector to invert\n * @returns {vec3} out\n */\nexport function inverse(out, a) {\n    out[0] = 1.0 / a[0];\n    out[1] = 1.0 / a[1];\n    out[2] = 1.0 / a[2];\n    return out;\n}\n\n/**\n * Normalize a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a vector to normalize\n * @returns {vec3} out\n */\nexport function normalize(out, a) {\n    let x = a[0];\n    let y = a[1];\n    let z = a[2];\n    let len = x * x + y * y + z * z;\n    if (len > 0) {\n        //TODO: evaluate use of glm_invsqrt here?\n        len = 1 / Math.sqrt(len);\n    }\n    out[0] = a[0] * len;\n    out[1] = a[1] * len;\n    out[2] = a[2] * len;\n    return out;\n}\n\n/**\n * Calculates the dot product of two vec3's\n *\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {Number} dot product of a and b\n */\nexport function dot(a, b) {\n    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\n/**\n * Computes the cross product of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @returns {vec3} out\n */\nexport function cross(out, a, b) {\n    let ax = a[0],\n        ay = a[1],\n        az = a[2];\n    let bx = b[0],\n        by = b[1],\n        bz = b[2];\n\n    out[0] = ay * bz - az * by;\n    out[1] = az * bx - ax * bz;\n    out[2] = ax * by - ay * bx;\n    return out;\n}\n\n/**\n * Performs a linear interpolation between two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @param {Number} t interpolation amount between the two inputs\n * @returns {vec3} out\n */\nexport function lerp(out, a, b, t) {\n    let ax = a[0];\n    let ay = a[1];\n    let az = a[2];\n    out[0] = ax + t * (b[0] - ax);\n    out[1] = ay + t * (b[1] - ay);\n    out[2] = az + t * (b[2] - az);\n    return out;\n}\n\n/**\n * Performs a frame rate independant, linear interpolation between two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the first operand\n * @param {vec3} b the second operand\n * @param {Number} decay decay constant for interpolation. useful range between 1 and 25, from slow to fast.\n * @param {Number} dt delta time\n * @returns {vec3} out\n */\nexport function smoothLerp(out, a, b, decay, dt) {\n    const exp = Math.exp(-decay * dt);\n    let ax = a[0];\n    let ay = a[1];\n    let az = a[2];\n\n    out[0] = b[0] + (ax - b[0]) * exp;\n    out[1] = b[1] + (ay - b[1]) * exp;\n    out[2] = b[2] + (az - b[2]) * exp;\n    return out;\n}\n\n/**\n * Transforms the vec3 with a mat4.\n * 4th vector component is implicitly '1'\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the vector to transform\n * @param {mat4} m matrix to transform with\n * @returns {vec3} out\n */\nexport function transformMat4(out, a, m) {\n    let x = a[0],\n        y = a[1],\n        z = a[2];\n    let w = m[3] * x + m[7] * y + m[11] * z + m[15];\n    w = w || 1.0;\n    out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;\n    out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;\n    out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;\n    return out;\n}\n\n/**\n * Same as above but doesn't apply translation.\n * Useful for rays.\n */\nexport function scaleRotateMat4(out, a, m) {\n    let x = a[0],\n        y = a[1],\n        z = a[2];\n    let w = m[3] * x + m[7] * y + m[11] * z + m[15];\n    w = w || 1.0;\n    out[0] = (m[0] * x + m[4] * y + m[8] * z) / w;\n    out[1] = (m[1] * x + m[5] * y + m[9] * z) / w;\n    out[2] = (m[2] * x + m[6] * y + m[10] * z) / w;\n    return out;\n}\n\n/**\n * Transforms the vec3 with a mat3.\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the vector to transform\n * @param {mat3} m the 3x3 matrix to transform with\n * @returns {vec3} out\n */\nexport function transformMat3(out, a, m) {\n    let x = a[0],\n        y = a[1],\n        z = a[2];\n    out[0] = x * m[0] + y * m[3] + z * m[6];\n    out[1] = x * m[1] + y * m[4] + z * m[7];\n    out[2] = x * m[2] + y * m[5] + z * m[8];\n    return out;\n}\n\n/**\n * Transforms the vec3 with a quat\n *\n * @param {vec3} out the receiving vector\n * @param {vec3} a the vector to transform\n * @param {quat} q quaternion to transform with\n * @returns {vec3} out\n */\nexport function transformQuat(out, a, q) {\n    // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed\n\n    let x = a[0],\n        y = a[1],\n        z = a[2];\n    let qx = q[0],\n        qy = q[1],\n        qz = q[2],\n        qw = q[3];\n\n    let uvx = qy * z - qz * y;\n    let uvy = qz * x - qx * z;\n    let uvz = qx * y - qy * x;\n\n    let uuvx = qy * uvz - qz * uvy;\n    let uuvy = qz * uvx - qx * uvz;\n    let uuvz = qx * uvy - qy * uvx;\n\n    let w2 = qw * 2;\n    uvx *= w2;\n    uvy *= w2;\n    uvz *= w2;\n\n    uuvx *= 2;\n    uuvy *= 2;\n    uuvz *= 2;\n\n    out[0] = x + uvx + uuvx;\n    out[1] = y + uvy + uuvy;\n    out[2] = z + uvz + uuvz;\n    return out;\n}\n\n/**\n * Get the angle between two 3D vectors\n * @param {vec3} a The first operand\n * @param {vec3} b The second operand\n * @returns {Number} The angle in radians\n */\nexport const angle = (function () {\n    const tempA = [0, 0, 0];\n    const tempB = [0, 0, 0];\n\n    return function (a, b) {\n        copy(tempA, a);\n        copy(tempB, b);\n\n        normalize(tempA, tempA);\n        normalize(tempB, tempB);\n\n        let cosine = dot(tempA, tempB);\n\n        if (cosine > 1.0) {\n            return 0;\n        } else if (cosine < -1.0) {\n            return Math.PI;\n        } else {\n            return Math.acos(cosine);\n        }\n    };\n})();\n\n/**\n * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)\n *\n * @param {vec3} a The first vector.\n * @param {vec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n    return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\n}\n","import * as Vec3Func from './functions/Vec3Func.js';\n\nexport class Vec3 extends Array {\n    constructor(x = 0, y = x, z = x) {\n        super(x, y, z);\n        return this;\n    }\n\n    get x() {\n        return this[0];\n    }\n\n    get y() {\n        return this[1];\n    }\n\n    get z() {\n        return this[2];\n    }\n\n    set x(v) {\n        this[0] = v;\n    }\n\n    set y(v) {\n        this[1] = v;\n    }\n\n    set z(v) {\n        this[2] = v;\n    }\n\n    set(x, y = x, z = x) {\n        if (x.length) return this.copy(x);\n        Vec3Func.set(this, x, y, z);\n        return this;\n    }\n\n    copy(v) {\n        Vec3Func.copy(this, v);\n        return this;\n    }\n\n    add(va, vb) {\n        if (vb) Vec3Func.add(this, va, vb);\n        else Vec3Func.add(this, this, va);\n        return this;\n    }\n\n    sub(va, vb) {\n        if (vb) Vec3Func.subtract(this, va, vb);\n        else Vec3Func.subtract(this, this, va);\n        return this;\n    }\n\n    multiply(v) {\n        if (v.length) Vec3Func.multiply(this, this, v);\n        else Vec3Func.scale(this, this, v);\n        return this;\n    }\n\n    divide(v) {\n        if (v.length) Vec3Func.divide(this, this, v);\n        else Vec3Func.scale(this, this, 1 / v);\n        return this;\n    }\n\n    inverse(v = this) {\n        Vec3Func.inverse(this, v);\n        return this;\n    }\n\n    // Can't use 'length' as Array.prototype uses it\n    len() {\n        return Vec3Func.length(this);\n    }\n\n    distance(v) {\n        if (v) return Vec3Func.distance(this, v);\n        else return Vec3Func.length(this);\n    }\n\n    squaredLen() {\n        return Vec3Func.squaredLength(this);\n    }\n\n    squaredDistance(v) {\n        if (v) return Vec3Func.squaredDistance(this, v);\n        else return Vec3Func.squaredLength(this);\n    }\n\n    negate(v = this) {\n        Vec3Func.negate(this, v);\n        return this;\n    }\n\n    cross(va, vb) {\n        if (vb) Vec3Func.cross(this, va, vb);\n        else Vec3Func.cross(this, this, va);\n        return this;\n    }\n\n    scale(v) {\n        Vec3Func.scale(this, this, v);\n        return this;\n    }\n\n    normalize() {\n        Vec3Func.normalize(this, this);\n        return this;\n    }\n\n    dot(v) {\n        return Vec3Func.dot(this, v);\n    }\n\n    equals(v) {\n        return Vec3Func.exactEquals(this, v);\n    }\n\n    applyMatrix3(mat3) {\n        Vec3Func.transformMat3(this, this, mat3);\n        return this;\n    }\n\n    applyMatrix4(mat4) {\n        Vec3Func.transformMat4(this, this, mat4);\n        return this;\n    }\n\n    scaleRotateMatrix4(mat4) {\n        Vec3Func.scaleRotateMat4(this, this, mat4);\n        return this;\n    }\n\n    applyQuaternion(q) {\n        Vec3Func.transformQuat(this, this, q);\n        return this;\n    }\n\n    angle(v) {\n        return Vec3Func.angle(this, v);\n    }\n\n    lerp(v, t) {\n        Vec3Func.lerp(this, this, v, t);\n        return this;\n    }\n\n    smoothLerp(v, decay, dt) {\n        Vec3Func.smoothLerp(this, this, v, decay, dt);\n        return this;\n    }\n\n    clone() {\n        return new Vec3(this[0], this[1], this[2]);\n    }\n\n    fromArray(a, o = 0) {\n        this[0] = a[o];\n        this[1] = a[o + 1];\n        this[2] = a[o + 2];\n        return this;\n    }\n\n    toArray(a = [], o = 0) {\n        a[o] = this[0];\n        a[o + 1] = this[1];\n        a[o + 2] = this[2];\n        return a;\n    }\n\n    transformDirection(mat4) {\n        const x = this[0];\n        const y = this[1];\n        const z = this[2];\n\n        this[0] = mat4[0] * x + mat4[4] * y + mat4[8] * z;\n        this[1] = mat4[1] * x + mat4[5] * y + mat4[9] * z;\n        this[2] = mat4[2] * x + mat4[6] * y + mat4[10] * z;\n\n        return this.normalize();\n    }\n}\n","// attribute params\n// {\n//     data - typed array eg UInt16Array for indices, Float32Array\n//     size - int default 1\n//     instanced - default null. Pass divisor amount\n//     type - gl enum default gl.UNSIGNED_SHORT for 'index', gl.FLOAT for others\n//     normalized - boolean default false\n\n//     buffer - gl buffer, if buffer exists, don't need to provide data - although needs position data for bounds calculation\n//     stride - default 0 - for when passing in buffer\n//     offset - default 0 - for when passing in buffer\n//     count - default null - for when passing in buffer\n//     min - array - for when passing in buffer\n//     max - array - for when passing in buffer\n// }\n\n// TODO: fit in transform feedback\n\nimport { Vec3 } from '../math/Vec3.js';\n\nconst tempVec3 = /* @__PURE__ */ new Vec3();\n\nlet ID = 1;\nlet ATTR_ID = 1;\n\n// To stop inifinite warnings\nlet isBoundsWarned = false;\n\nexport class Geometry {\n    constructor(gl, attributes = {}) {\n        if (!gl.canvas) console.error('gl not passed as first argument to Geometry');\n        this.gl = gl;\n        this.attributes = attributes;\n        this.id = ID++;\n\n        // Store one VAO per program attribute locations order\n        this.VAOs = {};\n\n        this.drawRange = { start: 0, count: 0 };\n        this.instancedCount = 0;\n\n        // Unbind current VAO so that new buffers don't get added to active mesh\n        this.gl.renderer.bindVertexArray(null);\n        this.gl.renderer.currentGeometry = null;\n\n        // Alias for state store to avoid redundant calls for global state\n        this.glState = this.gl.renderer.state;\n\n        // create the buffers\n        for (let key in attributes) {\n            this.addAttribute(key, attributes[key]);\n        }\n    }\n\n    addAttribute(key, attr) {\n        this.attributes[key] = attr;\n\n        // Set options\n        attr.id = ATTR_ID++; // TODO: currently unused, remove?\n        attr.size = attr.size || 1;\n        attr.type =\n            attr.type ||\n            (attr.data.constructor === Float32Array\n                ? this.gl.FLOAT\n                : attr.data.constructor === Uint16Array\n                ? this.gl.UNSIGNED_SHORT\n                : this.gl.UNSIGNED_INT); // Uint32Array\n        attr.target = key === 'index' ? this.gl.ELEMENT_ARRAY_BUFFER : this.gl.ARRAY_BUFFER;\n        attr.normalized = attr.normalized || false;\n        attr.stride = attr.stride || 0;\n        attr.offset = attr.offset || 0;\n        attr.count = attr.count || (attr.stride ? attr.data.byteLength / attr.stride : attr.data.length / attr.size);\n        attr.divisor = attr.instanced || 0;\n        attr.needsUpdate = false;\n        attr.usage = attr.usage || this.gl.STATIC_DRAW;\n\n        if (!attr.buffer) {\n            // Push data to buffer\n            this.updateAttribute(attr);\n        }\n\n        // Update geometry counts. If indexed, ignore regular attributes\n        if (attr.divisor) {\n            this.isInstanced = true;\n            if (this.instancedCount && this.instancedCount !== attr.count * attr.divisor) {\n                console.warn('geometry has multiple instanced buffers of different length');\n                return (this.instancedCount = Math.min(this.instancedCount, attr.count * attr.divisor));\n            }\n            this.instancedCount = attr.count * attr.divisor;\n        } else if (key === 'index') {\n            this.drawRange.count = attr.count;\n        } else if (!this.attributes.index) {\n            this.drawRange.count = Math.max(this.drawRange.count, attr.count);\n        }\n    }\n\n    updateAttribute(attr) {\n        const isNewBuffer = !attr.buffer;\n        if (isNewBuffer) attr.buffer = this.gl.createBuffer();\n        if (this.glState.boundBuffer !== attr.buffer) {\n            this.gl.bindBuffer(attr.target, attr.buffer);\n            this.glState.boundBuffer = attr.buffer;\n        }\n        if (isNewBuffer) {\n            this.gl.bufferData(attr.target, attr.data, attr.usage);\n        } else {\n            this.gl.bufferSubData(attr.target, 0, attr.data);\n        }\n        attr.needsUpdate = false;\n    }\n\n    setIndex(value) {\n        this.addAttribute('index', value);\n    }\n\n    setDrawRange(start, count) {\n        this.drawRange.start = start;\n        this.drawRange.count = count;\n    }\n\n    setInstancedCount(value) {\n        this.instancedCount = value;\n    }\n\n    createVAO(program) {\n        this.VAOs[program.attributeOrder] = this.gl.renderer.createVertexArray();\n        this.gl.renderer.bindVertexArray(this.VAOs[program.attributeOrder]);\n        this.bindAttributes(program);\n    }\n\n    bindAttributes(program) {\n        // Link all attributes to program using gl.vertexAttribPointer\n        program.attributeLocations.forEach((location, { name, type }) => {\n            // If geometry missing a required shader attribute\n            if (!this.attributes[name]) {\n                console.warn(`active attribute ${name} not being supplied`);\n                return;\n            }\n\n            const attr = this.attributes[name];\n\n            this.gl.bindBuffer(attr.target, attr.buffer);\n            this.glState.boundBuffer = attr.buffer;\n\n            // For matrix attributes, buffer needs to be defined per column\n            let numLoc = 1;\n            if (type === 35674) numLoc = 2; // mat2\n            if (type === 35675) numLoc = 3; // mat3\n            if (type === 35676) numLoc = 4; // mat4\n\n            const size = attr.size / numLoc;\n            const stride = numLoc === 1 ? 0 : numLoc * numLoc * 4;\n            const offset = numLoc === 1 ? 0 : numLoc * 4;\n\n            for (let i = 0; i < numLoc; i++) {\n                this.gl.vertexAttribPointer(location + i, size, attr.type, attr.normalized, attr.stride + stride, attr.offset + i * offset);\n                this.gl.enableVertexAttribArray(location + i);\n\n                // For instanced attributes, divisor needs to be set.\n                // For firefox, need to set back to 0 if non-instanced drawn after instanced. Else won't render\n                this.gl.renderer.vertexAttribDivisor(location + i, attr.divisor);\n            }\n        });\n\n        // Bind indices if geometry indexed\n        if (this.attributes.index) this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.attributes.index.buffer);\n    }\n\n    draw({ program, mode = this.gl.TRIANGLES }) {\n        if (this.gl.renderer.currentGeometry !== `${this.id}_${program.attributeOrder}`) {\n            if (!this.VAOs[program.attributeOrder]) this.createVAO(program);\n            this.gl.renderer.bindVertexArray(this.VAOs[program.attributeOrder]);\n            this.gl.renderer.currentGeometry = `${this.id}_${program.attributeOrder}`;\n        }\n\n        // Check if any attributes need updating\n        program.attributeLocations.forEach((location, { name }) => {\n            const attr = this.attributes[name];\n            if (attr.needsUpdate) this.updateAttribute(attr);\n        });\n\n        // For drawElements, offset needs to be multiple of type size\n        let indexBytesPerElement = 2;\n        if (this.attributes.index?.type === this.gl.UNSIGNED_INT) indexBytesPerElement = 4;\n\n        if (this.isInstanced) {\n            if (this.attributes.index) {\n                this.gl.renderer.drawElementsInstanced(\n                    mode,\n                    this.drawRange.count,\n                    this.attributes.index.type,\n                    this.attributes.index.offset + this.drawRange.start * indexBytesPerElement,\n                    this.instancedCount\n                );\n            } else {\n                this.gl.renderer.drawArraysInstanced(mode, this.drawRange.start, this.drawRange.count, this.instancedCount);\n            }\n        } else {\n            if (this.attributes.index) {\n                this.gl.drawElements(\n                    mode,\n                    this.drawRange.count,\n                    this.attributes.index.type,\n                    this.attributes.index.offset + this.drawRange.start * indexBytesPerElement\n                );\n            } else {\n                this.gl.drawArrays(mode, this.drawRange.start, this.drawRange.count);\n            }\n        }\n    }\n\n    getPosition() {\n        // Use position buffer, or min/max if available\n        const attr = this.attributes.position;\n        // if (attr.min) return [...attr.min, ...attr.max];\n        if (attr.data) return attr;\n        if (isBoundsWarned) return;\n        console.warn('No position buffer data found to compute bounds');\n        return (isBoundsWarned = true);\n    }\n\n    computeBoundingBox(attr) {\n        if (!attr) attr = this.getPosition();\n        const array = attr.data;\n        // Data loaded shouldn't haave stride, only buffers\n        // const stride = attr.stride ? attr.stride / array.BYTES_PER_ELEMENT : attr.size;\n        const stride = attr.size;\n\n        if (!this.bounds) {\n            this.bounds = {\n                min: new Vec3(),\n                max: new Vec3(),\n                center: new Vec3(),\n                scale: new Vec3(),\n                radius: Infinity,\n            };\n        }\n\n        const min = this.bounds.min;\n        const max = this.bounds.max;\n        const center = this.bounds.center;\n        const scale = this.bounds.scale;\n\n        min.set(+Infinity);\n        max.set(-Infinity);\n\n        // TODO: check size of position (eg triangle with Vec2)\n        for (let i = 0, l = array.length; i < l; i += stride) {\n            const x = array[i];\n            const y = array[i + 1];\n            const z = array[i + 2];\n\n            min.x = Math.min(x, min.x);\n            min.y = Math.min(y, min.y);\n            min.z = Math.min(z, min.z);\n\n            max.x = Math.max(x, max.x);\n            max.y = Math.max(y, max.y);\n            max.z = Math.max(z, max.z);\n        }\n\n        scale.sub(max, min);\n        center.add(min, max).divide(2);\n    }\n\n    computeBoundingSphere(attr) {\n        if (!attr) attr = this.getPosition();\n        const array = attr.data;\n        // Data loaded shouldn't haave stride, only buffers\n        // const stride = attr.stride ? attr.stride / array.BYTES_PER_ELEMENT : attr.size;\n        const stride = attr.size;\n\n        if (!this.bounds) this.computeBoundingBox(attr);\n\n        let maxRadiusSq = 0;\n        for (let i = 0, l = array.length; i < l; i += stride) {\n            tempVec3.fromArray(array, i);\n            maxRadiusSq = Math.max(maxRadiusSq, this.bounds.center.squaredDistance(tempVec3));\n        }\n\n        this.bounds.radius = Math.sqrt(maxRadiusSq);\n    }\n\n    remove() {\n        for (let key in this.VAOs) {\n            this.gl.renderer.deleteVertexArray(this.VAOs[key]);\n            delete this.VAOs[key];\n        }\n        for (let key in this.attributes) {\n            this.gl.deleteBuffer(this.attributes[key].buffer);\n            delete this.attributes[key];\n        }\n    }\n}\n","// TODO: upload empty texture if null ? maybe not\n// TODO: upload identity matrix if null ?\n// TODO: sampler Cube\n\nlet ID = 1;\n\n// cache of typed arrays used to flatten uniform arrays\nconst arrayCacheF32 = {};\n\nexport class Program {\n    constructor(\n        gl,\n        {\n            vertex,\n            fragment,\n            uniforms = {},\n\n            transparent = false,\n            cullFace = gl.BACK,\n            frontFace = gl.CCW,\n            depthTest = true,\n            depthWrite = true,\n            depthFunc = gl.LEQUAL,\n        } = {}\n    ) {\n        if (!gl.canvas) console.error('gl not passed as first argument to Program');\n        this.gl = gl;\n        this.uniforms = uniforms;\n        this.id = ID++;\n\n        if (!vertex) console.warn('vertex shader not supplied');\n        if (!fragment) console.warn('fragment shader not supplied');\n\n        // Store program state\n        this.transparent = transparent;\n        this.cullFace = cullFace;\n        this.frontFace = frontFace;\n        this.depthTest = depthTest;\n        this.depthWrite = depthWrite;\n        this.depthFunc = depthFunc;\n        this.blendFunc = {};\n        this.blendEquation = {};\n        this.stencilFunc = {};\n        this.stencilOp = {}\n\n        // set default blendFunc if transparent flagged\n        if (this.transparent && !this.blendFunc.src) {\n            if (this.gl.renderer.premultipliedAlpha) this.setBlendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);\n            else this.setBlendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);\n        }\n\n        // Create empty shaders and attach to program\n        this.vertexShader = gl.createShader(gl.VERTEX_SHADER);\n        this.fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n        this.program = gl.createProgram();\n        gl.attachShader(this.program, this.vertexShader);\n        gl.attachShader(this.program, this.fragmentShader);\n\n        // Compile shaders with source\n        this.setShaders({ vertex, fragment });\n    }\n\n    setShaders({ vertex, fragment }) {\n        if (vertex) {\n            // compile vertex shader and log errors\n            this.gl.shaderSource(this.vertexShader, vertex);\n            this.gl.compileShader(this.vertexShader);\n            if (this.gl.getShaderInfoLog(this.vertexShader) !== '') {\n                console.warn(`${this.gl.getShaderInfoLog(this.vertexShader)}\\nVertex Shader\\n${addLineNumbers(vertex)}`);\n            }\n        }\n\n        if (fragment) {\n            // compile fragment shader and log errors\n            this.gl.shaderSource(this.fragmentShader, fragment);\n            this.gl.compileShader(this.fragmentShader);\n            if (this.gl.getShaderInfoLog(this.fragmentShader) !== '') {\n                console.warn(`${this.gl.getShaderInfoLog(this.fragmentShader)}\\nFragment Shader\\n${addLineNumbers(fragment)}`);\n            }\n        }\n\n        // compile program and log errors\n        this.gl.linkProgram(this.program);\n        if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {\n            return console.warn(this.gl.getProgramInfoLog(this.program));\n        }\n\n        // Get active uniform locations\n        this.uniformLocations = new Map();\n        let numUniforms = this.gl.getProgramParameter(this.program, this.gl.ACTIVE_UNIFORMS);\n        for (let uIndex = 0; uIndex < numUniforms; uIndex++) {\n            let uniform = this.gl.getActiveUniform(this.program, uIndex);\n            this.uniformLocations.set(uniform, this.gl.getUniformLocation(this.program, uniform.name));\n\n            // split uniforms' names to separate array and struct declarations\n            const split = uniform.name.match(/(\\w+)/g);\n\n            uniform.uniformName = split[0];\n            uniform.nameComponents = split.slice(1);\n        }\n\n        // Get active attribute locations\n        this.attributeLocations = new Map();\n        const locations = [];\n        const numAttribs = this.gl.getProgramParameter(this.program, this.gl.ACTIVE_ATTRIBUTES);\n        for (let aIndex = 0; aIndex < numAttribs; aIndex++) {\n            const attribute = this.gl.getActiveAttrib(this.program, aIndex);\n            const location = this.gl.getAttribLocation(this.program, attribute.name);\n            // Ignore special built-in inputs. eg gl_VertexID, gl_InstanceID\n            if (location === -1) continue;\n            locations[location] = attribute.name;\n            this.attributeLocations.set(attribute, location);\n        }\n        this.attributeOrder = locations.join('');\n    }\n\n    setBlendFunc(src, dst, srcAlpha, dstAlpha) {\n        this.blendFunc.src = src;\n        this.blendFunc.dst = dst;\n        this.blendFunc.srcAlpha = srcAlpha;\n        this.blendFunc.dstAlpha = dstAlpha;\n        if (src) this.transparent = true;\n    }\n\n    setBlendEquation(modeRGB, modeAlpha) {\n        this.blendEquation.modeRGB = modeRGB;\n        this.blendEquation.modeAlpha = modeAlpha;\n    }\n\n    setStencilFunc(func, ref, mask) {\n        this.stencilRef = ref;\n        this.stencilFunc.func = func;\n        this.stencilFunc.ref = ref;\n        this.stencilFunc.mask = mask;\n    }\n\n    setStencilOp(stencilFail, depthFail, depthPass) {\n        this.stencilOp.stencilFail = stencilFail;\n        this.stencilOp.depthFail = depthFail;\n        this.stencilOp.depthPass = depthPass;\n    }\n\n    applyState() {\n        if (this.depthTest) this.gl.renderer.enable(this.gl.DEPTH_TEST);\n        else this.gl.renderer.disable(this.gl.DEPTH_TEST);\n\n        if (this.cullFace) this.gl.renderer.enable(this.gl.CULL_FACE);\n        else this.gl.renderer.disable(this.gl.CULL_FACE);\n\n        if (this.blendFunc.src) this.gl.renderer.enable(this.gl.BLEND);\n        else this.gl.renderer.disable(this.gl.BLEND);\n\n        if (this.cullFace) this.gl.renderer.setCullFace(this.cullFace);\n        this.gl.renderer.setFrontFace(this.frontFace);\n        this.gl.renderer.setDepthMask(this.depthWrite);\n        this.gl.renderer.setDepthFunc(this.depthFunc);\n        if (this.blendFunc.src) this.gl.renderer.setBlendFunc(this.blendFunc.src, this.blendFunc.dst, this.blendFunc.srcAlpha, this.blendFunc.dstAlpha);\n        this.gl.renderer.setBlendEquation(this.blendEquation.modeRGB, this.blendEquation.modeAlpha);\n\n        if(this.stencilFunc.func || this.stencilOp.stencilFail) this.gl.renderer.enable(this.gl.STENCIL_TEST)\n            else this.gl.renderer.disable(this.gl.STENCIL_TEST)\n\n        this.gl.renderer.setStencilFunc(this.stencilFunc.func, this.stencilFunc.ref, this.stencilFunc.mask)\n        this.gl.renderer.setStencilOp(this.stencilOp.stencilFail, this.stencilOp.depthFail, this.stencilOp.depthPass)\n\n    }\n\n    use({ flipFaces = false } = {}) {\n        let textureUnit = -1;\n        const programActive = this.gl.renderer.state.currentProgram === this.id;\n\n        // Avoid gl call if program already in use\n        if (!programActive) {\n            this.gl.useProgram(this.program);\n            this.gl.renderer.state.currentProgram = this.id;\n        }\n\n        // Set only the active uniforms found in the shader\n        this.uniformLocations.forEach((location, activeUniform) => {\n            let uniform = this.uniforms[activeUniform.uniformName];\n\n            for (const component of activeUniform.nameComponents) {\n                if (!uniform) break;\n\n                if (component in uniform) {\n                    uniform = uniform[component];\n                } else if (Array.isArray(uniform.value)) {\n                    break;\n                } else {\n                    uniform = undefined;\n                    break;\n                }\n            }\n\n            if (!uniform) {\n                return warn(`Active uniform ${activeUniform.name} has not been supplied`);\n            }\n\n            if (uniform && uniform.value === undefined) {\n                return warn(`${activeUniform.name} uniform is missing a value parameter`);\n            }\n\n            if (uniform.value.texture) {\n                textureUnit = textureUnit + 1;\n\n                // Check if texture needs to be updated\n                uniform.value.update(textureUnit);\n                return setUniform(this.gl, activeUniform.type, location, textureUnit);\n            }\n\n            // For texture arrays, set uniform as an array of texture units instead of just one\n            if (uniform.value.length && uniform.value[0].texture) {\n                const textureUnits = [];\n                uniform.value.forEach((value) => {\n                    textureUnit = textureUnit + 1;\n                    value.update(textureUnit);\n                    textureUnits.push(textureUnit);\n                });\n\n                return setUniform(this.gl, activeUniform.type, location, textureUnits);\n            }\n\n            setUniform(this.gl, activeUniform.type, location, uniform.value);\n        });\n\n        this.applyState();\n        if (flipFaces) this.gl.renderer.setFrontFace(this.frontFace === this.gl.CCW ? this.gl.CW : this.gl.CCW);\n    }\n\n    remove() {\n        this.gl.deleteProgram(this.program);\n    }\n}\n\nfunction setUniform(gl, type, location, value) {\n    value = value.length ? flatten(value) : value;\n    const setValue = gl.renderer.state.uniformLocations.get(location);\n\n    // Avoid redundant uniform commands\n    if (value.length) {\n        if (setValue === undefined || setValue.length !== value.length) {\n            // clone array to store as cache\n            gl.renderer.state.uniformLocations.set(location, value.slice(0));\n        } else {\n            if (arraysEqual(setValue, value)) return;\n\n            // Update cached array values\n            setValue.set ? setValue.set(value) : setArray(setValue, value);\n            gl.renderer.state.uniformLocations.set(location, setValue);\n        }\n    } else {\n        if (setValue === value) return;\n        gl.renderer.state.uniformLocations.set(location, value);\n    }\n\n    switch (type) {\n        case 5126:\n            return value.length ? gl.uniform1fv(location, value) : gl.uniform1f(location, value); // FLOAT\n        case 35664:\n            return gl.uniform2fv(location, value); // FLOAT_VEC2\n        case 35665:\n            return gl.uniform3fv(location, value); // FLOAT_VEC3\n        case 35666:\n            return gl.uniform4fv(location, value); // FLOAT_VEC4\n        case 35670: // BOOL\n        case 5124: // INT\n        case 35678: // SAMPLER_2D\n        case 36306: // U_SAMPLER_2D\n        case 35680: // SAMPLER_CUBE\n        case 36289: // SAMPLER_2D_ARRAY\n            return value.length ? gl.uniform1iv(location, value) : gl.uniform1i(location, value); // SAMPLER_CUBE\n        case 35671: // BOOL_VEC2\n        case 35667:\n            return gl.uniform2iv(location, value); // INT_VEC2\n        case 35672: // BOOL_VEC3\n        case 35668:\n            return gl.uniform3iv(location, value); // INT_VEC3\n        case 35673: // BOOL_VEC4\n        case 35669:\n            return gl.uniform4iv(location, value); // INT_VEC4\n        case 35674:\n            return gl.uniformMatrix2fv(location, false, value); // FLOAT_MAT2\n        case 35675:\n            return gl.uniformMatrix3fv(location, false, value); // FLOAT_MAT3\n        case 35676:\n            return gl.uniformMatrix4fv(location, false, value); // FLOAT_MAT4\n    }\n}\n\nfunction addLineNumbers(string) {\n    let lines = string.split('\\n');\n    for (let i = 0; i < lines.length; i++) {\n        lines[i] = i + 1 + ': ' + lines[i];\n    }\n    return lines.join('\\n');\n}\n\nfunction flatten(a) {\n    const arrayLen = a.length;\n    const valueLen = a[0].length;\n    if (valueLen === undefined) return a;\n    const length = arrayLen * valueLen;\n    let value = arrayCacheF32[length];\n    if (!value) arrayCacheF32[length] = value = new Float32Array(length);\n    for (let i = 0; i < arrayLen; i++) value.set(a[i], i * valueLen);\n    return value;\n}\n\nfunction arraysEqual(a, b) {\n    if (a.length !== b.length) return false;\n    for (let i = 0, l = a.length; i < l; i++) {\n        if (a[i] !== b[i]) return false;\n    }\n    return true;\n}\n\nfunction setArray(a, b) {\n    for (let i = 0, l = a.length; i < l; i++) {\n        a[i] = b[i];\n    }\n}\n\nlet warnCount = 0;\nfunction warn(message) {\n    if (warnCount > 100) return;\n    console.warn(message);\n    warnCount++;\n    if (warnCount > 100) console.warn('More than 100 program warnings - stopping logs.');\n}\n","import { Vec3 } from '../math/Vec3.js';\n\n// TODO: Handle context loss https://www.khronos.org/webgl/wiki/HandlingContextLost\n\n// Not automatic - devs to use these methods manually\n// gl.colorMask( colorMask, colorMask, colorMask, colorMask );\n// gl.clearColor( r, g, b, a );\n// gl.stencilMask( stencilMask );\n// gl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n// gl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n// gl.clearStencil( stencil );\n\nconst tempVec3 = /* @__PURE__ */ new Vec3();\nlet ID = 1;\n\nexport class Renderer {\n    constructor({\n        canvas = document.createElement('canvas'),\n        width = 300,\n        height = 150,\n        dpr = 1,\n        alpha = false,\n        depth = true,\n        stencil = false,\n        antialias = false,\n        premultipliedAlpha = false,\n        preserveDrawingBuffer = false,\n        powerPreference = 'default',\n        autoClear = true,\n        webgl = 2,\n    } = {}) {\n        const attributes = { alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, powerPreference };\n        this.dpr = dpr;\n        this.alpha = alpha;\n        this.color = true;\n        this.depth = depth;\n        this.stencil = stencil;\n        this.premultipliedAlpha = premultipliedAlpha;\n        this.autoClear = autoClear;\n        this.id = ID++;\n\n        // Attempt WebGL2 unless forced to 1, if not supported fallback to WebGL1\n        if (webgl === 2) this.gl = canvas.getContext('webgl2', attributes);\n        this.isWebgl2 = !!this.gl;\n        if (!this.gl) this.gl = canvas.getContext('webgl', attributes);\n        if (!this.gl) console.error('unable to create webgl context');\n\n        // Attach renderer to gl so that all classes have access to internal state functions\n        this.gl.renderer = this;\n\n        // initialise size values\n        this.setSize(width, height);\n\n        // gl state stores to avoid redundant calls on methods used internally\n        this.state = {};\n        this.state.blendFunc = { src: this.gl.ONE, dst: this.gl.ZERO };\n        this.state.blendEquation = { modeRGB: this.gl.FUNC_ADD };\n        this.state.cullFace = false;\n        this.state.frontFace = this.gl.CCW;\n        this.state.depthMask = true;\n        this.state.depthFunc = this.gl.LEQUAL;\n        this.state.premultiplyAlpha = false;\n        this.state.flipY = false;\n        this.state.unpackAlignment = 4;\n        this.state.framebuffer = null;\n        this.state.viewport = { x: 0, y: 0, width: null, height: null };\n        this.state.textureUnits = [];\n        this.state.activeTextureUnit = 0;\n        this.state.boundBuffer = null;\n        this.state.uniformLocations = new Map();\n        this.state.currentProgram = null;\n\n        // store requested extensions\n        this.extensions = {};\n\n        // Initialise extra format types\n        if (this.isWebgl2) {\n            this.getExtension('EXT_color_buffer_float');\n            this.getExtension('OES_texture_float_linear');\n        } else {\n            this.getExtension('OES_texture_float');\n            this.getExtension('OES_texture_float_linear');\n            this.getExtension('OES_texture_half_float');\n            this.getExtension('OES_texture_half_float_linear');\n            this.getExtension('OES_element_index_uint');\n            this.getExtension('OES_standard_derivatives');\n            this.getExtension('EXT_sRGB');\n            this.getExtension('WEBGL_depth_texture');\n            this.getExtension('WEBGL_draw_buffers');\n        }\n        this.getExtension('WEBGL_compressed_texture_astc');\n        this.getExtension('EXT_texture_compression_bptc');\n        this.getExtension('WEBGL_compressed_texture_s3tc');\n        this.getExtension('WEBGL_compressed_texture_etc1');\n        this.getExtension('WEBGL_compressed_texture_pvrtc');\n        this.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');\n\n        // Create method aliases using extension (WebGL1) or native if available (WebGL2)\n        this.vertexAttribDivisor = this.getExtension('ANGLE_instanced_arrays', 'vertexAttribDivisor', 'vertexAttribDivisorANGLE');\n        this.drawArraysInstanced = this.getExtension('ANGLE_instanced_arrays', 'drawArraysInstanced', 'drawArraysInstancedANGLE');\n        this.drawElementsInstanced = this.getExtension('ANGLE_instanced_arrays', 'drawElementsInstanced', 'drawElementsInstancedANGLE');\n        this.createVertexArray = this.getExtension('OES_vertex_array_object', 'createVertexArray', 'createVertexArrayOES');\n        this.bindVertexArray = this.getExtension('OES_vertex_array_object', 'bindVertexArray', 'bindVertexArrayOES');\n        this.deleteVertexArray = this.getExtension('OES_vertex_array_object', 'deleteVertexArray', 'deleteVertexArrayOES');\n        this.drawBuffers = this.getExtension('WEBGL_draw_buffers', 'drawBuffers', 'drawBuffersWEBGL');\n\n        // Store device parameters\n        this.parameters = {};\n        this.parameters.maxTextureUnits = this.gl.getParameter(this.gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);\n        this.parameters.maxAnisotropy = this.getExtension('EXT_texture_filter_anisotropic')\n            ? this.gl.getParameter(this.getExtension('EXT_texture_filter_anisotropic').MAX_TEXTURE_MAX_ANISOTROPY_EXT)\n            : 0;\n    }\n\n    setSize(width, height) {\n        this.width = width;\n        this.height = height;\n\n        this.gl.canvas.width = width * this.dpr;\n        this.gl.canvas.height = height * this.dpr;\n\n        if (!this.gl.canvas.style) return;\n        Object.assign(this.gl.canvas.style, {\n            width: width + 'px',\n            height: height + 'px',\n        });\n    }\n\n    setViewport(width, height, x = 0, y = 0) {\n        if (this.state.viewport.width === width && this.state.viewport.height === height) return;\n        this.state.viewport.width = width;\n        this.state.viewport.height = height;\n        this.state.viewport.x = x;\n        this.state.viewport.y = y;\n        this.gl.viewport(x, y, width, height);\n    }\n\n    setScissor(width, height, x = 0, y = 0) {\n        this.gl.scissor(x, y, width, height);\n    }\n\n    enable(id) {\n        if (this.state[id] === true) return;\n        this.gl.enable(id);\n        this.state[id] = true;\n    }\n\n    disable(id) {\n        if (this.state[id] === false) return;\n        this.gl.disable(id);\n        this.state[id] = false;\n    }\n\n    setBlendFunc(src, dst, srcAlpha, dstAlpha) {\n        if (\n            this.state.blendFunc.src === src &&\n            this.state.blendFunc.dst === dst &&\n            this.state.blendFunc.srcAlpha === srcAlpha &&\n            this.state.blendFunc.dstAlpha === dstAlpha\n        )\n            return;\n        this.state.blendFunc.src = src;\n        this.state.blendFunc.dst = dst;\n        this.state.blendFunc.srcAlpha = srcAlpha;\n        this.state.blendFunc.dstAlpha = dstAlpha;\n        if (srcAlpha !== undefined) this.gl.blendFuncSeparate(src, dst, srcAlpha, dstAlpha);\n        else this.gl.blendFunc(src, dst);\n    }\n\n    setBlendEquation(modeRGB, modeAlpha) {\n        modeRGB = modeRGB || this.gl.FUNC_ADD;\n        if (this.state.blendEquation.modeRGB === modeRGB && this.state.blendEquation.modeAlpha === modeAlpha) return;\n        this.state.blendEquation.modeRGB = modeRGB;\n        this.state.blendEquation.modeAlpha = modeAlpha;\n        if (modeAlpha !== undefined) this.gl.blendEquationSeparate(modeRGB, modeAlpha);\n        else this.gl.blendEquation(modeRGB);\n    }\n\n    setCullFace(value) {\n        if (this.state.cullFace === value) return;\n        this.state.cullFace = value;\n        this.gl.cullFace(value);\n    }\n\n    setFrontFace(value) {\n        if (this.state.frontFace === value) return;\n        this.state.frontFace = value;\n        this.gl.frontFace(value);\n    }\n\n    setDepthMask(value) {\n        if (this.state.depthMask === value) return;\n        this.state.depthMask = value;\n        this.gl.depthMask(value);\n    }\n\n    setDepthFunc(value) {\n        if (this.state.depthFunc === value) return;\n        this.state.depthFunc = value;\n        this.gl.depthFunc(value);\n    }\n\n    setStencilMask(value) {\n        if(this.state.stencilMask === value) return;\n        this.state.stencilMask = value;\n        this.gl.stencilMask(value)\n    }\n\n    setStencilFunc(func, ref, mask) {\n\n        if((this.state.stencilFunc === func) &&\n            (this.state.stencilRef === ref) &&\n            (this.state.stencilFuncMask === mask)\n        ) return;\n\n        this.state.stencilFunc = func || this.gl.ALWAYS;\n        this.state.stencilRef = ref || 0;\n        this.state.stencilFuncMask = mask || 0;\n\n        this.gl.stencilFunc(func || this.gl.ALWAYS, ref || 0, mask || 0);\n    }\n\n    setStencilOp(stencilFail, depthFail, depthPass) {\n\n        if(this.state.stencilFail === stencilFail &&\n            this.state.stencilDepthFail === depthFail &&\n            this.state.stencilDepthPass === depthPass\n        ) return;\n\n        this.state.stencilFail = stencilFail;\n        this.state.stencilDepthFail = depthFail;\n        this.state.stencilDepthPass = depthPass;\n        \n        this.gl.stencilOp(stencilFail, depthFail, depthPass);\n        \n    }\n\n    activeTexture(value) {\n        if (this.state.activeTextureUnit === value) return;\n        this.state.activeTextureUnit = value;\n        this.gl.activeTexture(this.gl.TEXTURE0 + value);\n    }\n\n    bindFramebuffer({ target = this.gl.FRAMEBUFFER, buffer = null } = {}) {\n        if (this.state.framebuffer === buffer) return;\n        this.state.framebuffer = buffer;\n        this.gl.bindFramebuffer(target, buffer);\n    }\n\n    getExtension(extension, webgl2Func, extFunc) {\n        // if webgl2 function supported, return func bound to gl context\n        if (webgl2Func && this.gl[webgl2Func]) return this.gl[webgl2Func].bind(this.gl);\n\n        // fetch extension once only\n        if (!this.extensions[extension]) {\n            this.extensions[extension] = this.gl.getExtension(extension);\n        }\n\n        // return extension if no function requested\n        if (!webgl2Func) return this.extensions[extension];\n\n        // Return null if extension not supported\n        if (!this.extensions[extension]) return null;\n\n        // return extension function, bound to extension\n        return this.extensions[extension][extFunc].bind(this.extensions[extension]);\n    }\n\n    sortOpaque(a, b) {\n        if (a.renderOrder !== b.renderOrder) {\n            return a.renderOrder - b.renderOrder;\n        } else if (a.program.id !== b.program.id) {\n            return a.program.id - b.program.id;\n        } else if (a.zDepth !== b.zDepth) {\n            return a.zDepth - b.zDepth;\n        } else {\n            return b.id - a.id;\n        }\n    }\n\n    sortTransparent(a, b) {\n        if (a.renderOrder !== b.renderOrder) {\n            return a.renderOrder - b.renderOrder;\n        }\n        if (a.zDepth !== b.zDepth) {\n            return b.zDepth - a.zDepth;\n        } else {\n            return b.id - a.id;\n        }\n    }\n\n    sortUI(a, b) {\n        if (a.renderOrder !== b.renderOrder) {\n            return a.renderOrder - b.renderOrder;\n        } else if (a.program.id !== b.program.id) {\n            return a.program.id - b.program.id;\n        } else {\n            return b.id - a.id;\n        }\n    }\n\n    getRenderList({ scene, camera, frustumCull, sort }) {\n        let renderList = [];\n\n        if (camera && frustumCull) camera.updateFrustum();\n\n        // Get visible\n        scene.traverse((node) => {\n            if (!node.visible) return true;\n            if (!node.draw) return;\n\n            if (frustumCull && node.frustumCulled && camera) {\n                if (!camera.frustumIntersectsMesh(node)) return;\n            }\n\n            renderList.push(node);\n        });\n\n        if (sort) {\n            const opaque = [];\n            const transparent = []; // depthTest true\n            const ui = []; // depthTest false\n\n            renderList.forEach((node) => {\n                // Split into the 3 render groups\n                if (!node.program.transparent) {\n                    opaque.push(node);\n                } else if (node.program.depthTest) {\n                    transparent.push(node);\n                } else {\n                    ui.push(node);\n                }\n\n                node.zDepth = 0;\n\n                // Only calculate z-depth if renderOrder unset and depthTest is true\n                if (node.renderOrder !== 0 || !node.program.depthTest || !camera) return;\n\n                // update z-depth\n                node.worldMatrix.getTranslation(tempVec3);\n                tempVec3.applyMatrix4(camera.projectionViewMatrix);\n                node.zDepth = tempVec3.z;\n            });\n\n            opaque.sort(this.sortOpaque);\n            transparent.sort(this.sortTransparent);\n            ui.sort(this.sortUI);\n\n            renderList = opaque.concat(transparent, ui);\n        }\n\n        return renderList;\n    }\n\n    render({ scene, camera, target = null, update = true, sort = true, frustumCull = true, clear }) {\n        if (target === null) {\n            // make sure no render target bound so draws to canvas\n            this.bindFramebuffer();\n            this.setViewport(this.width * this.dpr, this.height * this.dpr);\n        } else {\n            // bind supplied render target and update viewport\n            this.bindFramebuffer(target);\n            this.setViewport(target.width, target.height);\n        }\n\n        if (clear || (this.autoClear && clear !== false)) {\n            // Ensure depth buffer writing is enabled so it can be cleared\n            if (this.depth && (!target || target.depth)) {\n                this.enable(this.gl.DEPTH_TEST);\n                this.setDepthMask(true);\n            }\n\n            // Same for stencil\n            if(this.stencil || (!target || target.stencil)) {\n                this.enable(this.gl.STENCIL_TEST);\n                this.setStencilMask(0xff)\n            }\n\n            this.gl.clear(\n                (this.color ? this.gl.COLOR_BUFFER_BIT : 0) |\n                    (this.depth ? this.gl.DEPTH_BUFFER_BIT : 0) |\n                    (this.stencil ? this.gl.STENCIL_BUFFER_BIT : 0)\n            );\n        }\n\n        // updates all scene graph matrices\n        if (update) scene.updateMatrixWorld();\n\n        // Update camera separately, in case not in scene graph\n        if (camera) camera.updateMatrixWorld();\n\n        // Get render list - entails culling and sorting\n        const renderList = this.getRenderList({ scene, camera, frustumCull, sort });\n\n        renderList.forEach((node) => {\n            node.draw({ camera });\n        });\n    }\n}\n","const EPSILON = 0.000001;\n\n/**\n * Copy the values from one vec4 to another\n *\n * @param {vec4} out the receiving vector\n * @param {vec4} a the source vector\n * @returns {vec4} out\n */\nexport function copy(out, a) {\n    out[0] = a[0];\n    out[1] = a[1];\n    out[2] = a[2];\n    out[3] = a[3];\n    return out;\n}\n\n/**\n * Set the components of a vec4 to the given values\n *\n * @param {vec4} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {vec4} out\n */\nexport function set(out, x, y, z, w) {\n    out[0] = x;\n    out[1] = y;\n    out[2] = z;\n    out[3] = w;\n    return out;\n}\n\n/**\n * Adds two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {vec4} a the first operand\n * @param {vec4} b the second operand\n * @returns {vec4} out\n */\nexport function add(out, a, b) {\n    out[0] = a[0] + b[0];\n    out[1] = a[1] + b[1];\n    out[2] = a[2] + b[2];\n    out[3] = a[3] + b[3];\n    return out;\n}\n\n/**\n * Scales a vec4 by a scalar number\n *\n * @param {vec4} out the receiving vector\n * @param {vec4} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec4} out\n */\nexport function scale(out, a, b) {\n    out[0] = a[0] * b;\n    out[1] = a[1] * b;\n    out[2] = a[2] * b;\n    out[3] = a[3] * b;\n    return out;\n}\n\n/**\n * Calculates the length of a vec4\n *\n * @param {vec4} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport function length(a) {\n    let x = a[0];\n    let y = a[1];\n    let z = a[2];\n    let w = a[3];\n    return Math.sqrt(x * x + y * y + z * z + w * w);\n}\n\n/**\n * Normalize a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {vec4} a vector to normalize\n * @returns {vec4} out\n */\nexport function normalize(out, a) {\n    let x = a[0];\n    let y = a[1];\n    let z = a[2];\n    let w = a[3];\n    let len = x * x + y * y + z * z + w * w;\n    if (len > 0) {\n        len = 1 / Math.sqrt(len);\n    }\n    out[0] = x * len;\n    out[1] = y * len;\n    out[2] = z * len;\n    out[3] = w * len;\n    return out;\n}\n\n/**\n * Calculates the dot product of two vec4's\n *\n * @param {vec4} a the first operand\n * @param {vec4} b the second operand\n * @returns {Number} dot product of a and b\n */\nexport function dot(a, b) {\n    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];\n}\n\n/**\n * Performs a linear interpolation between two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {vec4} a the first operand\n * @param {vec4} b the second operand\n * @param {Number} t interpolation amount between the two inputs\n * @returns {vec4} out\n */\nexport function lerp(out, a, b, t) {\n    let ax = a[0];\n    let ay = a[1];\n    let az = a[2];\n    let aw = a[3];\n    out[0] = ax + t * (b[0] - ax);\n    out[1] = ay + t * (b[1] - ay);\n    out[2] = az + t * (b[2] - az);\n    out[3] = aw + t * (b[3] - aw);\n    return out;\n}\n","import * as vec4 from './Vec4Func.js';\n\n/**\n * Set a quat to the identity quaternion\n *\n * @param {quat} out the receiving quaternion\n * @returns {quat} out\n */\nexport function identity(out) {\n    out[0] = 0;\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 1;\n    return out;\n}\n\n/**\n * Sets a quat from the given angle and rotation axis,\n * then returns it.\n *\n * @param {quat} out the receiving quaternion\n * @param {vec3} axis the axis around which to rotate\n * @param {Number} rad the angle in radians\n * @returns {quat} out\n **/\nexport function setAxisAngle(out, axis, rad) {\n    rad = rad * 0.5;\n    let s = Math.sin(rad);\n    out[0] = s * axis[0];\n    out[1] = s * axis[1];\n    out[2] = s * axis[2];\n    out[3] = Math.cos(rad);\n    return out;\n}\n\n/**\n * Multiplies two quats\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a the first operand\n * @param {quat} b the second operand\n * @returns {quat} out\n */\nexport function multiply(out, a, b) {\n    let ax = a[0],\n        ay = a[1],\n        az = a[2],\n        aw = a[3];\n    let bx = b[0],\n        by = b[1],\n        bz = b[2],\n        bw = b[3];\n\n    out[0] = ax * bw + aw * bx + ay * bz - az * by;\n    out[1] = ay * bw + aw * by + az * bx - ax * bz;\n    out[2] = az * bw + aw * bz + ax * by - ay * bx;\n    out[3] = aw * bw - ax * bx - ay * by - az * bz;\n    return out;\n}\n\n/**\n * Rotates a quaternion by the given angle about the X axis\n *\n * @param {quat} out quat receiving operation result\n * @param {quat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\nexport function rotateX(out, a, rad) {\n    rad *= 0.5;\n\n    let ax = a[0],\n        ay = a[1],\n        az = a[2],\n        aw = a[3];\n    let bx = Math.sin(rad),\n        bw = Math.cos(rad);\n\n    out[0] = ax * bw + aw * bx;\n    out[1] = ay * bw + az * bx;\n    out[2] = az * bw - ay * bx;\n    out[3] = aw * bw - ax * bx;\n    return out;\n}\n\n/**\n * Rotates a quaternion by the given angle about the Y axis\n *\n * @param {quat} out quat receiving operation result\n * @param {quat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\nexport function rotateY(out, a, rad) {\n    rad *= 0.5;\n\n    let ax = a[0],\n        ay = a[1],\n        az = a[2],\n        aw = a[3];\n    let by = Math.sin(rad),\n        bw = Math.cos(rad);\n\n    out[0] = ax * bw - az * by;\n    out[1] = ay * bw + aw * by;\n    out[2] = az * bw + ax * by;\n    out[3] = aw * bw - ay * by;\n    return out;\n}\n\n/**\n * Rotates a quaternion by the given angle about the Z axis\n *\n * @param {quat} out quat receiving operation result\n * @param {quat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\nexport function rotateZ(out, a, rad) {\n    rad *= 0.5;\n\n    let ax = a[0],\n        ay = a[1],\n        az = a[2],\n        aw = a[3];\n    let bz = Math.sin(rad),\n        bw = Math.cos(rad);\n\n    out[0] = ax * bw + ay * bz;\n    out[1] = ay * bw - ax * bz;\n    out[2] = az * bw + aw * bz;\n    out[3] = aw * bw - az * bz;\n    return out;\n}\n\n/**\n * Performs a spherical linear interpolation between two quat\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a the first operand\n * @param {quat} b the second operand\n * @param {Number} t interpolation amount between the two inputs\n * @returns {quat} out\n */\nexport function slerp(out, a, b, t) {\n    // benchmarks:\n    //    http://jsperf.com/quaternion-slerp-implementations\n    let ax = a[0],\n        ay = a[1],\n        az = a[2],\n        aw = a[3];\n    let bx = b[0],\n        by = b[1],\n        bz = b[2],\n        bw = b[3];\n\n    let omega, cosom, sinom, scale0, scale1;\n\n    // calc cosine\n    cosom = ax * bx + ay * by + az * bz + aw * bw;\n    // adjust signs (if necessary)\n    if (cosom < 0.0) {\n        cosom = -cosom;\n        bx = -bx;\n        by = -by;\n        bz = -bz;\n        bw = -bw;\n    }\n    // calculate coefficients\n    if (1.0 - cosom > 0.000001) {\n        // standard case (slerp)\n        omega = Math.acos(cosom);\n        sinom = Math.sin(omega);\n        scale0 = Math.sin((1.0 - t) * omega) / sinom;\n        scale1 = Math.sin(t * omega) / sinom;\n    } else {\n        // \"from\" and \"to\" quaternions are very close\n        //  ... so we can do a linear interpolation\n        scale0 = 1.0 - t;\n        scale1 = t;\n    }\n    // calculate final values\n    out[0] = scale0 * ax + scale1 * bx;\n    out[1] = scale0 * ay + scale1 * by;\n    out[2] = scale0 * az + scale1 * bz;\n    out[3] = scale0 * aw + scale1 * bw;\n\n    return out;\n}\n\n/**\n * Calculates the inverse of a quat\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a quat to calculate inverse of\n * @returns {quat} out\n */\nexport function invert(out, a) {\n    let a0 = a[0],\n        a1 = a[1],\n        a2 = a[2],\n        a3 = a[3];\n    let dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;\n    let invDot = dot ? 1.0 / dot : 0;\n\n    // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0\n\n    out[0] = -a0 * invDot;\n    out[1] = -a1 * invDot;\n    out[2] = -a2 * invDot;\n    out[3] = a3 * invDot;\n    return out;\n}\n\n/**\n * Calculates the conjugate of a quat\n * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a quat to calculate conjugate of\n * @returns {quat} out\n */\nexport function conjugate(out, a) {\n    out[0] = -a[0];\n    out[1] = -a[1];\n    out[2] = -a[2];\n    out[3] = a[3];\n    return out;\n}\n\n/**\n * Creates a quaternion from the given 3x3 rotation matrix.\n *\n * NOTE: The resultant quaternion is not normalized, so you should be sure\n * to renormalize the quaternion yourself where necessary.\n *\n * @param {quat} out the receiving quaternion\n * @param {mat3} m rotation matrix\n * @returns {quat} out\n * @function\n */\nexport function fromMat3(out, m) {\n    // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes\n    // article \"Quaternion Calculus and Fast Animation\".\n    let fTrace = m[0] + m[4] + m[8];\n    let fRoot;\n\n    if (fTrace > 0.0) {\n        // |w| > 1/2, may as well choose w > 1/2\n        fRoot = Math.sqrt(fTrace + 1.0); // 2w\n        out[3] = 0.5 * fRoot;\n        fRoot = 0.5 / fRoot; // 1/(4w)\n        out[0] = (m[5] - m[7]) * fRoot;\n        out[1] = (m[6] - m[2]) * fRoot;\n        out[2] = (m[1] - m[3]) * fRoot;\n    } else {\n        // |w| <= 1/2\n        let i = 0;\n        if (m[4] > m[0]) i = 1;\n        if (m[8] > m[i * 3 + i]) i = 2;\n        let j = (i + 1) % 3;\n        let k = (i + 2) % 3;\n\n        fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);\n        out[i] = 0.5 * fRoot;\n        fRoot = 0.5 / fRoot;\n        out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;\n        out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;\n        out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;\n    }\n\n    return out;\n}\n\n/**\n * Creates a quaternion from the given euler angle x, y, z.\n *\n * @param {quat} out the receiving quaternion\n * @param {vec3} euler Angles to rotate around each axis in degrees.\n * @param {String} order detailing order of operations. Default 'XYZ'.\n * @returns {quat} out\n * @function\n */\nexport function fromEuler(out, euler, order = 'YXZ') {\n    let sx = Math.sin(euler[0] * 0.5);\n    let cx = Math.cos(euler[0] * 0.5);\n    let sy = Math.sin(euler[1] * 0.5);\n    let cy = Math.cos(euler[1] * 0.5);\n    let sz = Math.sin(euler[2] * 0.5);\n    let cz = Math.cos(euler[2] * 0.5);\n\n    if (order === 'XYZ') {\n        out[0] = sx * cy * cz + cx * sy * sz;\n        out[1] = cx * sy * cz - sx * cy * sz;\n        out[2] = cx * cy * sz + sx * sy * cz;\n        out[3] = cx * cy * cz - sx * sy * sz;\n    } else if (order === 'YXZ') {\n        out[0] = sx * cy * cz + cx * sy * sz;\n        out[1] = cx * sy * cz - sx * cy * sz;\n        out[2] = cx * cy * sz - sx * sy * cz;\n        out[3] = cx * cy * cz + sx * sy * sz;\n    } else if (order === 'ZXY') {\n        out[0] = sx * cy * cz - cx * sy * sz;\n        out[1] = cx * sy * cz + sx * cy * sz;\n        out[2] = cx * cy * sz + sx * sy * cz;\n        out[3] = cx * cy * cz - sx * sy * sz;\n    } else if (order === 'ZYX') {\n        out[0] = sx * cy * cz - cx * sy * sz;\n        out[1] = cx * sy * cz + sx * cy * sz;\n        out[2] = cx * cy * sz - sx * sy * cz;\n        out[3] = cx * cy * cz + sx * sy * sz;\n    } else if (order === 'YZX') {\n        out[0] = sx * cy * cz + cx * sy * sz;\n        out[1] = cx * sy * cz + sx * cy * sz;\n        out[2] = cx * cy * sz - sx * sy * cz;\n        out[3] = cx * cy * cz - sx * sy * sz;\n    } else if (order === 'XZY') {\n        out[0] = sx * cy * cz - cx * sy * sz;\n        out[1] = cx * sy * cz - sx * cy * sz;\n        out[2] = cx * cy * sz + sx * sy * cz;\n        out[3] = cx * cy * cz + sx * sy * sz;\n    }\n\n    return out;\n}\n\n/**\n * Copy the values from one quat to another\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a the source quaternion\n * @returns {quat} out\n * @function\n */\nexport const copy = vec4.copy;\n\n/**\n * Set the components of a quat to the given values\n *\n * @param {quat} out the receiving quaternion\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {quat} out\n * @function\n */\nexport const set = vec4.set;\n\n/**\n * Adds two quat's\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a the first operand\n * @param {quat} b the second operand\n * @returns {quat} out\n * @function\n */\nexport const add = vec4.add;\n\n/**\n * Scales a quat by a scalar number\n *\n * @param {quat} out the receiving vector\n * @param {quat} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {quat} out\n * @function\n */\nexport const scale = vec4.scale;\n\n/**\n * Calculates the dot product of two quat's\n *\n * @param {quat} a the first operand\n * @param {quat} b the second operand\n * @returns {Number} dot product of a and b\n * @function\n */\nexport const dot = vec4.dot;\n\n/**\n * Performs a linear interpolation between two quat's\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a the first operand\n * @param {quat} b the second operand\n * @param {Number} t interpolation amount between the two inputs\n * @returns {quat} out\n * @function\n */\nexport const lerp = vec4.lerp;\n\n/**\n * Calculates the length of a quat\n *\n * @param {quat} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport const length = vec4.length;\n\n/**\n * Normalize a quat\n *\n * @param {quat} out the receiving quaternion\n * @param {quat} a quaternion to normalize\n * @returns {quat} out\n * @function\n */\nexport const normalize = vec4.normalize;\n","import * as QuatFunc from './functions/QuatFunc.js';\n\nexport class Quat extends Array {\n    constructor(x = 0, y = 0, z = 0, w = 1) {\n        super(x, y, z, w);\n        this.onChange = () => {};\n\n        // Keep reference to proxy target to avoid triggering onChange internally\n        this._target = this;\n\n        // Return a proxy to trigger onChange when array elements are edited directly\n        const triggerProps = ['0', '1', '2', '3'];\n        return new Proxy(this, {\n            set(target, property) {\n                const success = Reflect.set(...arguments);\n                if (success && triggerProps.includes(property)) target.onChange();\n                return success;\n            },\n        });\n    }\n\n    get x() {\n        return this[0];\n    }\n\n    get y() {\n        return this[1];\n    }\n\n    get z() {\n        return this[2];\n    }\n\n    get w() {\n        return this[3];\n    }\n\n    set x(v) {\n        this._target[0] = v;\n        this.onChange();\n    }\n\n    set y(v) {\n        this._target[1] = v;\n        this.onChange();\n    }\n\n    set z(v) {\n        this._target[2] = v;\n        this.onChange();\n    }\n\n    set w(v) {\n        this._target[3] = v;\n        this.onChange();\n    }\n\n    identity() {\n        QuatFunc.identity(this._target);\n        this.onChange();\n        return this;\n    }\n\n    set(x, y, z, w) {\n        if (x.length) return this.copy(x);\n        QuatFunc.set(this._target, x, y, z, w);\n        this.onChange();\n        return this;\n    }\n\n    rotateX(a) {\n        QuatFunc.rotateX(this._target, this._target, a);\n        this.onChange();\n        return this;\n    }\n\n    rotateY(a) {\n        QuatFunc.rotateY(this._target, this._target, a);\n        this.onChange();\n        return this;\n    }\n\n    rotateZ(a) {\n        QuatFunc.rotateZ(this._target, this._target, a);\n        this.onChange();\n        return this;\n    }\n\n    inverse(q = this._target) {\n        QuatFunc.invert(this._target, q);\n        this.onChange();\n        return this;\n    }\n\n    conjugate(q = this._target) {\n        QuatFunc.conjugate(this._target, q);\n        this.onChange();\n        return this;\n    }\n\n    copy(q) {\n        QuatFunc.copy(this._target, q);\n        this.onChange();\n        return this;\n    }\n\n    normalize(q = this._target) {\n        QuatFunc.normalize(this._target, q);\n        this.onChange();\n        return this;\n    }\n\n    multiply(qA, qB) {\n        if (qB) {\n            QuatFunc.multiply(this._target, qA, qB);\n        } else {\n            QuatFunc.multiply(this._target, this._target, qA);\n        }\n        this.onChange();\n        return this;\n    }\n\n    dot(v) {\n        return QuatFunc.dot(this._target, v);\n    }\n\n    fromMatrix3(matrix3) {\n        QuatFunc.fromMat3(this._target, matrix3);\n        this.onChange();\n        return this;\n    }\n\n    fromEuler(euler, isInternal) {\n        QuatFunc.fromEuler(this._target, euler, euler.order);\n        // Avoid infinite recursion\n        if (!isInternal) this.onChange();\n        return this;\n    }\n\n    fromAxisAngle(axis, a) {\n        QuatFunc.setAxisAngle(this._target, axis, a);\n        this.onChange();\n        return this;\n    }\n\n    slerp(q, t) {\n        QuatFunc.slerp(this._target, this._target, q, t);\n        this.onChange();\n        return this;\n    }\n\n    fromArray(a, o = 0) {\n        this._target[0] = a[o];\n        this._target[1] = a[o + 1];\n        this._target[2] = a[o + 2];\n        this._target[3] = a[o + 3];\n        this.onChange();\n        return this;\n    }\n\n    toArray(a = [], o = 0) {\n        a[o] = this[0];\n        a[o + 1] = this[1];\n        a[o + 2] = this[2];\n        a[o + 3] = this[3];\n        return a;\n    }\n}\n","import * as vec3 from './Vec3Func.js';\n\nconst EPSILON = 0.000001;\n\n/**\n * Copy the values from one mat4 to another\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the source matrix\n * @returns {mat4} out\n */\nexport function copy(out, a) {\n    out[0] = a[0];\n    out[1] = a[1];\n    out[2] = a[2];\n    out[3] = a[3];\n    out[4] = a[4];\n    out[5] = a[5];\n    out[6] = a[6];\n    out[7] = a[7];\n    out[8] = a[8];\n    out[9] = a[9];\n    out[10] = a[10];\n    out[11] = a[11];\n    out[12] = a[12];\n    out[13] = a[13];\n    out[14] = a[14];\n    out[15] = a[15];\n    return out;\n}\n\n/**\n * Set the components of a mat4 to the given values\n *\n * @param {mat4} out the receiving matrix\n * @returns {mat4} out\n */\nexport function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n    out[0] = m00;\n    out[1] = m01;\n    out[2] = m02;\n    out[3] = m03;\n    out[4] = m10;\n    out[5] = m11;\n    out[6] = m12;\n    out[7] = m13;\n    out[8] = m20;\n    out[9] = m21;\n    out[10] = m22;\n    out[11] = m23;\n    out[12] = m30;\n    out[13] = m31;\n    out[14] = m32;\n    out[15] = m33;\n    return out;\n}\n\n/**\n * Set a mat4 to the identity matrix\n *\n * @param {mat4} out the receiving matrix\n * @returns {mat4} out\n */\nexport function identity(out) {\n    out[0] = 1;\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 0;\n    out[4] = 0;\n    out[5] = 1;\n    out[6] = 0;\n    out[7] = 0;\n    out[8] = 0;\n    out[9] = 0;\n    out[10] = 1;\n    out[11] = 0;\n    out[12] = 0;\n    out[13] = 0;\n    out[14] = 0;\n    out[15] = 1;\n    return out;\n}\n\n/**\n * Transpose the values of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the source matrix\n * @returns {mat4} out\n */\nexport function transpose(out, a) {\n    // If we are transposing ourselves we can skip a few steps but have to cache some values\n    if (out === a) {\n        let a01 = a[1],\n            a02 = a[2],\n            a03 = a[3];\n        let a12 = a[6],\n            a13 = a[7];\n        let a23 = a[11];\n\n        out[1] = a[4];\n        out[2] = a[8];\n        out[3] = a[12];\n        out[4] = a01;\n        out[6] = a[9];\n        out[7] = a[13];\n        out[8] = a02;\n        out[9] = a12;\n        out[11] = a[14];\n        out[12] = a03;\n        out[13] = a13;\n        out[14] = a23;\n    } else {\n        out[0] = a[0];\n        out[1] = a[4];\n        out[2] = a[8];\n        out[3] = a[12];\n        out[4] = a[1];\n        out[5] = a[5];\n        out[6] = a[9];\n        out[7] = a[13];\n        out[8] = a[2];\n        out[9] = a[6];\n        out[10] = a[10];\n        out[11] = a[14];\n        out[12] = a[3];\n        out[13] = a[7];\n        out[14] = a[11];\n        out[15] = a[15];\n    }\n\n    return out;\n}\n\n/**\n * Inverts a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the source matrix\n * @returns {mat4} out\n */\nexport function invert(out, a) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2],\n        a03 = a[3];\n    let a10 = a[4],\n        a11 = a[5],\n        a12 = a[6],\n        a13 = a[7];\n    let a20 = a[8],\n        a21 = a[9],\n        a22 = a[10],\n        a23 = a[11];\n    let a30 = a[12],\n        a31 = a[13],\n        a32 = a[14],\n        a33 = a[15];\n\n    let b00 = a00 * a11 - a01 * a10;\n    let b01 = a00 * a12 - a02 * a10;\n    let b02 = a00 * a13 - a03 * a10;\n    let b03 = a01 * a12 - a02 * a11;\n    let b04 = a01 * a13 - a03 * a11;\n    let b05 = a02 * a13 - a03 * a12;\n    let b06 = a20 * a31 - a21 * a30;\n    let b07 = a20 * a32 - a22 * a30;\n    let b08 = a20 * a33 - a23 * a30;\n    let b09 = a21 * a32 - a22 * a31;\n    let b10 = a21 * a33 - a23 * a31;\n    let b11 = a22 * a33 - a23 * a32;\n\n    // Calculate the determinant\n    let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n    if (!det) {\n        return null;\n    }\n    det = 1.0 / det;\n\n    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n    out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n    out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n    out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n    out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n    out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n    out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n    out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n    out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n    out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n    out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n    out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n    out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n    out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n    out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n    out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n    return out;\n}\n\n/**\n * Calculates the determinant of a mat4\n *\n * @param {mat4} a the source matrix\n * @returns {Number} determinant of a\n */\nexport function determinant(a) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2],\n        a03 = a[3];\n    let a10 = a[4],\n        a11 = a[5],\n        a12 = a[6],\n        a13 = a[7];\n    let a20 = a[8],\n        a21 = a[9],\n        a22 = a[10],\n        a23 = a[11];\n    let a30 = a[12],\n        a31 = a[13],\n        a32 = a[14],\n        a33 = a[15];\n\n    let b00 = a00 * a11 - a01 * a10;\n    let b01 = a00 * a12 - a02 * a10;\n    let b02 = a00 * a13 - a03 * a10;\n    let b03 = a01 * a12 - a02 * a11;\n    let b04 = a01 * a13 - a03 * a11;\n    let b05 = a02 * a13 - a03 * a12;\n    let b06 = a20 * a31 - a21 * a30;\n    let b07 = a20 * a32 - a22 * a30;\n    let b08 = a20 * a33 - a23 * a30;\n    let b09 = a21 * a32 - a22 * a31;\n    let b10 = a21 * a33 - a23 * a31;\n    let b11 = a22 * a33 - a23 * a32;\n\n    // Calculate the determinant\n    return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n}\n\n/**\n * Multiplies two mat4s\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the first operand\n * @param {mat4} b the second operand\n * @returns {mat4} out\n */\nexport function multiply(out, a, b) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2],\n        a03 = a[3];\n    let a10 = a[4],\n        a11 = a[5],\n        a12 = a[6],\n        a13 = a[7];\n    let a20 = a[8],\n        a21 = a[9],\n        a22 = a[10],\n        a23 = a[11];\n    let a30 = a[12],\n        a31 = a[13],\n        a32 = a[14],\n        a33 = a[15];\n\n    // Cache only the current line of the second matrix\n    let b0 = b[0],\n        b1 = b[1],\n        b2 = b[2],\n        b3 = b[3];\n    out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n    out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n    out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n    out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n\n    b0 = b[4];\n    b1 = b[5];\n    b2 = b[6];\n    b3 = b[7];\n    out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n    out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n    out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n    out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n\n    b0 = b[8];\n    b1 = b[9];\n    b2 = b[10];\n    b3 = b[11];\n    out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n    out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n    out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n    out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n\n    b0 = b[12];\n    b1 = b[13];\n    b2 = b[14];\n    b3 = b[15];\n    out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n    out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n    out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n    out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n    return out;\n}\n\n/**\n * Translate a mat4 by the given vector\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the matrix to translate\n * @param {vec3} v vector to translate by\n * @returns {mat4} out\n */\nexport function translate(out, a, v) {\n    let x = v[0],\n        y = v[1],\n        z = v[2];\n    let a00, a01, a02, a03;\n    let a10, a11, a12, a13;\n    let a20, a21, a22, a23;\n\n    if (a === out) {\n        out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n        out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n        out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n        out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n    } else {\n        a00 = a[0];\n        a01 = a[1];\n        a02 = a[2];\n        a03 = a[3];\n        a10 = a[4];\n        a11 = a[5];\n        a12 = a[6];\n        a13 = a[7];\n        a20 = a[8];\n        a21 = a[9];\n        a22 = a[10];\n        a23 = a[11];\n\n        out[0] = a00;\n        out[1] = a01;\n        out[2] = a02;\n        out[3] = a03;\n        out[4] = a10;\n        out[5] = a11;\n        out[6] = a12;\n        out[7] = a13;\n        out[8] = a20;\n        out[9] = a21;\n        out[10] = a22;\n        out[11] = a23;\n\n        out[12] = a00 * x + a10 * y + a20 * z + a[12];\n        out[13] = a01 * x + a11 * y + a21 * z + a[13];\n        out[14] = a02 * x + a12 * y + a22 * z + a[14];\n        out[15] = a03 * x + a13 * y + a23 * z + a[15];\n    }\n\n    return out;\n}\n\n/**\n * Scales the mat4 by the dimensions in the given vec3 not using vectorization\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the matrix to scale\n * @param {vec3} v the vec3 to scale the matrix by\n * @returns {mat4} out\n **/\nexport function scale(out, a, v) {\n    let x = v[0],\n        y = v[1],\n        z = v[2];\n\n    out[0] = a[0] * x;\n    out[1] = a[1] * x;\n    out[2] = a[2] * x;\n    out[3] = a[3] * x;\n    out[4] = a[4] * y;\n    out[5] = a[5] * y;\n    out[6] = a[6] * y;\n    out[7] = a[7] * y;\n    out[8] = a[8] * z;\n    out[9] = a[9] * z;\n    out[10] = a[10] * z;\n    out[11] = a[11] * z;\n    out[12] = a[12];\n    out[13] = a[13];\n    out[14] = a[14];\n    out[15] = a[15];\n    return out;\n}\n\n/**\n * Rotates a mat4 by the given angle around the given axis\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @param {vec3} axis the axis to rotate around\n * @returns {mat4} out\n */\nexport function rotate(out, a, rad, axis) {\n    let x = axis[0],\n        y = axis[1],\n        z = axis[2];\n    let len = Math.hypot(x, y, z);\n    let s, c, t;\n    let a00, a01, a02, a03;\n    let a10, a11, a12, a13;\n    let a20, a21, a22, a23;\n    let b00, b01, b02;\n    let b10, b11, b12;\n    let b20, b21, b22;\n\n    if (Math.abs(len) < EPSILON) {\n        return null;\n    }\n\n    len = 1 / len;\n    x *= len;\n    y *= len;\n    z *= len;\n\n    s = Math.sin(rad);\n    c = Math.cos(rad);\n    t = 1 - c;\n\n    a00 = a[0];\n    a01 = a[1];\n    a02 = a[2];\n    a03 = a[3];\n    a10 = a[4];\n    a11 = a[5];\n    a12 = a[6];\n    a13 = a[7];\n    a20 = a[8];\n    a21 = a[9];\n    a22 = a[10];\n    a23 = a[11];\n\n    // Construct the elements of the rotation matrix\n    b00 = x * x * t + c;\n    b01 = y * x * t + z * s;\n    b02 = z * x * t - y * s;\n    b10 = x * y * t - z * s;\n    b11 = y * y * t + c;\n    b12 = z * y * t + x * s;\n    b20 = x * z * t + y * s;\n    b21 = y * z * t - x * s;\n    b22 = z * z * t + c;\n\n    // Perform rotation-specific matrix multiplication\n    out[0] = a00 * b00 + a10 * b01 + a20 * b02;\n    out[1] = a01 * b00 + a11 * b01 + a21 * b02;\n    out[2] = a02 * b00 + a12 * b01 + a22 * b02;\n    out[3] = a03 * b00 + a13 * b01 + a23 * b02;\n    out[4] = a00 * b10 + a10 * b11 + a20 * b12;\n    out[5] = a01 * b10 + a11 * b11 + a21 * b12;\n    out[6] = a02 * b10 + a12 * b11 + a22 * b12;\n    out[7] = a03 * b10 + a13 * b11 + a23 * b12;\n    out[8] = a00 * b20 + a10 * b21 + a20 * b22;\n    out[9] = a01 * b20 + a11 * b21 + a21 * b22;\n    out[10] = a02 * b20 + a12 * b21 + a22 * b22;\n    out[11] = a03 * b20 + a13 * b21 + a23 * b22;\n\n    if (a !== out) {\n        // If the source and destination differ, copy the unchanged last row\n        out[12] = a[12];\n        out[13] = a[13];\n        out[14] = a[14];\n        out[15] = a[15];\n    }\n    return out;\n}\n\n/**\n * Returns the translation vector component of a transformation\n *  matrix. If a matrix is built with fromRotationTranslation,\n *  the returned vector will be the same as the translation vector\n *  originally supplied.\n * @param  {vec3} out Vector to receive translation component\n * @param  {mat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\nexport function getTranslation(out, mat) {\n    out[0] = mat[12];\n    out[1] = mat[13];\n    out[2] = mat[14];\n\n    return out;\n}\n\n/**\n * Returns the scaling factor component of a transformation\n *  matrix. If a matrix is built with fromRotationTranslationScale\n *  with a normalized Quaternion paramter, the returned vector will be\n *  the same as the scaling vector\n *  originally supplied.\n * @param  {vec3} out Vector to receive scaling factor component\n * @param  {mat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\nexport function getScaling(out, mat) {\n    let m11 = mat[0];\n    let m12 = mat[1];\n    let m13 = mat[2];\n    let m21 = mat[4];\n    let m22 = mat[5];\n    let m23 = mat[6];\n    let m31 = mat[8];\n    let m32 = mat[9];\n    let m33 = mat[10];\n\n    out[0] = Math.hypot(m11, m12, m13);\n    out[1] = Math.hypot(m21, m22, m23);\n    out[2] = Math.hypot(m31, m32, m33);\n\n    return out;\n}\n\nexport function getMaxScaleOnAxis(mat) {\n    let m11 = mat[0];\n    let m12 = mat[1];\n    let m13 = mat[2];\n    let m21 = mat[4];\n    let m22 = mat[5];\n    let m23 = mat[6];\n    let m31 = mat[8];\n    let m32 = mat[9];\n    let m33 = mat[10];\n\n    const x = m11 * m11 + m12 * m12 + m13 * m13;\n    const y = m21 * m21 + m22 * m22 + m23 * m23;\n    const z = m31 * m31 + m32 * m32 + m33 * m33;\n\n    return Math.sqrt(Math.max(x, y, z));\n}\n\n/**\n * Returns a quaternion representing the rotational component\n *  of a transformation matrix. If a matrix is built with\n *  fromRotationTranslation, the returned quaternion will be the\n *  same as the quaternion originally supplied.\n * @param {quat} out Quaternion to receive the rotation component\n * @param {mat4} mat Matrix to be decomposed (input)\n * @return {quat} out\n */\nexport const getRotation = (function () {\n    const temp = [1, 1, 1];\n\n    return function (out, mat) {\n        let scaling = temp;\n        getScaling(scaling, mat);\n\n        let is1 = 1 / scaling[0];\n        let is2 = 1 / scaling[1];\n        let is3 = 1 / scaling[2];\n\n        let sm11 = mat[0] * is1;\n        let sm12 = mat[1] * is2;\n        let sm13 = mat[2] * is3;\n        let sm21 = mat[4] * is1;\n        let sm22 = mat[5] * is2;\n        let sm23 = mat[6] * is3;\n        let sm31 = mat[8] * is1;\n        let sm32 = mat[9] * is2;\n        let sm33 = mat[10] * is3;\n\n        let trace = sm11 + sm22 + sm33;\n        let S = 0;\n\n        if (trace > 0) {\n            S = Math.sqrt(trace + 1.0) * 2;\n            out[3] = 0.25 * S;\n            out[0] = (sm23 - sm32) / S;\n            out[1] = (sm31 - sm13) / S;\n            out[2] = (sm12 - sm21) / S;\n        } else if (sm11 > sm22 && sm11 > sm33) {\n            S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;\n            out[3] = (sm23 - sm32) / S;\n            out[0] = 0.25 * S;\n            out[1] = (sm12 + sm21) / S;\n            out[2] = (sm31 + sm13) / S;\n        } else if (sm22 > sm33) {\n            S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;\n            out[3] = (sm31 - sm13) / S;\n            out[0] = (sm12 + sm21) / S;\n            out[1] = 0.25 * S;\n            out[2] = (sm23 + sm32) / S;\n        } else {\n            S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;\n            out[3] = (sm12 - sm21) / S;\n            out[0] = (sm31 + sm13) / S;\n            out[1] = (sm23 + sm32) / S;\n            out[2] = 0.25 * S;\n        }\n\n        return out;\n    };\n})();\n\n/**\n * From glTF-Transform\n * https://github.com/donmccurdy/glTF-Transform/blob/main/packages/core/src/utils/math-utils.ts\n *\n * Decompose a mat4 to TRS properties.\n *\n * Equivalent to the Matrix4 decompose() method in three.js, and intentionally not using the\n * gl-matrix version. See: https://github.com/toji/gl-matrix/issues/408\n *\n * @param {mat4} srcMat Matrix element, to be decomposed to TRS properties.\n * @param {quat4} dstRotation Rotation element, to be overwritten.\n * @param {vec3} dstTranslation Translation element, to be overwritten.\n * @param {vec3} dstScale Scale element, to be overwritten\n */\nexport function decompose(srcMat, dstRotation, dstTranslation, dstScale) {\n    let sx = vec3.length([srcMat[0], srcMat[1], srcMat[2]]);\n    const sy = vec3.length([srcMat[4], srcMat[5], srcMat[6]]);\n    const sz = vec3.length([srcMat[8], srcMat[9], srcMat[10]]);\n\n    // if determine is negative, we need to invert one scale\n    const det = determinant(srcMat);\n    if (det < 0) sx = -sx;\n\n    dstTranslation[0] = srcMat[12];\n    dstTranslation[1] = srcMat[13];\n    dstTranslation[2] = srcMat[14];\n\n    // scale the rotation part\n    const _m1 = srcMat.slice();\n\n    const invSX = 1 / sx;\n    const invSY = 1 / sy;\n    const invSZ = 1 / sz;\n\n    _m1[0] *= invSX;\n    _m1[1] *= invSX;\n    _m1[2] *= invSX;\n\n    _m1[4] *= invSY;\n    _m1[5] *= invSY;\n    _m1[6] *= invSY;\n\n    _m1[8] *= invSZ;\n    _m1[9] *= invSZ;\n    _m1[10] *= invSZ;\n\n    getRotation(dstRotation, _m1);\n\n    dstScale[0] = sx;\n    dstScale[1] = sy;\n    dstScale[2] = sz;\n}\n\n/**\n * From glTF-Transform\n * https://github.com/donmccurdy/glTF-Transform/blob/main/packages/core/src/utils/math-utils.ts\n *\n * Compose TRS properties to a mat4.\n *\n * Equivalent to the Matrix4 compose() method in three.js, and intentionally not using the\n * gl-matrix version. See: https://github.com/toji/gl-matrix/issues/408\n *\n * @param {mat4} dstMat Matrix element, to be modified and returned.\n * @param {quat4} srcRotation Rotation element of matrix.\n * @param {vec3} srcTranslation Translation element of matrix.\n * @param {vec3} srcScale Scale element of matrix.\n * @returns {mat4} dstMat, overwritten to mat4 equivalent of given TRS properties.\n */\nexport function compose(dstMat, srcRotation, srcTranslation, srcScale) {\n    const te = dstMat;\n\n    const x = srcRotation[0],\n        y = srcRotation[1],\n        z = srcRotation[2],\n        w = srcRotation[3];\n    const x2 = x + x,\n        y2 = y + y,\n        z2 = z + z;\n    const xx = x * x2,\n        xy = x * y2,\n        xz = x * z2;\n    const yy = y * y2,\n        yz = y * z2,\n        zz = z * z2;\n    const wx = w * x2,\n        wy = w * y2,\n        wz = w * z2;\n\n    const sx = srcScale[0],\n        sy = srcScale[1],\n        sz = srcScale[2];\n\n    te[0] = (1 - (yy + zz)) * sx;\n    te[1] = (xy + wz) * sx;\n    te[2] = (xz - wy) * sx;\n    te[3] = 0;\n\n    te[4] = (xy - wz) * sy;\n    te[5] = (1 - (xx + zz)) * sy;\n    te[6] = (yz + wx) * sy;\n    te[7] = 0;\n\n    te[8] = (xz + wy) * sz;\n    te[9] = (yz - wx) * sz;\n    te[10] = (1 - (xx + yy)) * sz;\n    te[11] = 0;\n\n    te[12] = srcTranslation[0];\n    te[13] = srcTranslation[1];\n    te[14] = srcTranslation[2];\n    te[15] = 1;\n\n    return te;\n}\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.translate(dest, vec);\n *     let quatMat = mat4.create();\n *     quat4.toMat4(quat, quatMat);\n *     mat4.multiply(dest, quatMat);\n *     mat4.scale(dest, scale)\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat4} q Rotation quaternion\n * @param {vec3} v Translation vector\n * @param {vec3} s Scaling vector\n * @returns {mat4} out\n */\nexport function fromRotationTranslationScale(out, q, v, s) {\n    // Quaternion math\n    let x = q[0],\n        y = q[1],\n        z = q[2],\n        w = q[3];\n    let x2 = x + x;\n    let y2 = y + y;\n    let z2 = z + z;\n\n    let xx = x * x2;\n    let xy = x * y2;\n    let xz = x * z2;\n    let yy = y * y2;\n    let yz = y * z2;\n    let zz = z * z2;\n    let wx = w * x2;\n    let wy = w * y2;\n    let wz = w * z2;\n    let sx = s[0];\n    let sy = s[1];\n    let sz = s[2];\n\n    out[0] = (1 - (yy + zz)) * sx;\n    out[1] = (xy + wz) * sx;\n    out[2] = (xz - wy) * sx;\n    out[3] = 0;\n    out[4] = (xy - wz) * sy;\n    out[5] = (1 - (xx + zz)) * sy;\n    out[6] = (yz + wx) * sy;\n    out[7] = 0;\n    out[8] = (xz + wy) * sz;\n    out[9] = (yz - wx) * sz;\n    out[10] = (1 - (xx + yy)) * sz;\n    out[11] = 0;\n    out[12] = v[0];\n    out[13] = v[1];\n    out[14] = v[2];\n    out[15] = 1;\n\n    return out;\n}\n\n/**\n * Calculates a 4x4 matrix from the given quaternion\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Quaternion to create matrix from\n *\n * @returns {mat4} out\n */\nexport function fromQuat(out, q) {\n    let x = q[0],\n        y = q[1],\n        z = q[2],\n        w = q[3];\n    let x2 = x + x;\n    let y2 = y + y;\n    let z2 = z + z;\n\n    let xx = x * x2;\n    let yx = y * x2;\n    let yy = y * y2;\n    let zx = z * x2;\n    let zy = z * y2;\n    let zz = z * z2;\n    let wx = w * x2;\n    let wy = w * y2;\n    let wz = w * z2;\n\n    out[0] = 1 - yy - zz;\n    out[1] = yx + wz;\n    out[2] = zx - wy;\n    out[3] = 0;\n\n    out[4] = yx - wz;\n    out[5] = 1 - xx - zz;\n    out[6] = zy + wx;\n    out[7] = 0;\n\n    out[8] = zx + wy;\n    out[9] = zy - wx;\n    out[10] = 1 - xx - yy;\n    out[11] = 0;\n\n    out[12] = 0;\n    out[13] = 0;\n    out[14] = 0;\n    out[15] = 1;\n\n    return out;\n}\n\n/**\n * Generates a perspective projection matrix with the given bounds\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function perspective(out, fovy, aspect, near, far) {\n    let f = 1.0 / Math.tan(fovy / 2);\n    let nf = 1 / (near - far);\n    out[0] = f / aspect;\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 0;\n    out[4] = 0;\n    out[5] = f;\n    out[6] = 0;\n    out[7] = 0;\n    out[8] = 0;\n    out[9] = 0;\n    out[10] = (far + near) * nf;\n    out[11] = -1;\n    out[12] = 0;\n    out[13] = 0;\n    out[14] = 2 * far * near * nf;\n    out[15] = 0;\n    return out;\n}\n\n/**\n * Generates a orthogonal projection matrix with the given bounds\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function ortho(out, left, right, bottom, top, near, far) {\n    let lr = 1 / (left - right);\n    let bt = 1 / (bottom - top);\n    let nf = 1 / (near - far);\n    out[0] = -2 * lr;\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 0;\n    out[4] = 0;\n    out[5] = -2 * bt;\n    out[6] = 0;\n    out[7] = 0;\n    out[8] = 0;\n    out[9] = 0;\n    out[10] = 2 * nf;\n    out[11] = 0;\n    out[12] = (left + right) * lr;\n    out[13] = (top + bottom) * bt;\n    out[14] = (far + near) * nf;\n    out[15] = 1;\n    return out;\n}\n\n/**\n * Generates a matrix that makes something look at something else.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {vec3} eye Position of the viewer\n * @param {vec3} target Point the viewer is looking at\n * @param {vec3} up vec3 pointing up\n * @returns {mat4} out\n */\nexport function targetTo(out, eye, target, up) {\n    let eyex = eye[0],\n        eyey = eye[1],\n        eyez = eye[2],\n        upx = up[0],\n        upy = up[1],\n        upz = up[2];\n\n    let z0 = eyex - target[0],\n        z1 = eyey - target[1],\n        z2 = eyez - target[2];\n\n    let len = z0 * z0 + z1 * z1 + z2 * z2;\n    if (len === 0) {\n        // eye and target are in the same position\n        z2 = 1;\n    } else {\n        len = 1 / Math.sqrt(len);\n        z0 *= len;\n        z1 *= len;\n        z2 *= len;\n    }\n\n    let x0 = upy * z2 - upz * z1,\n        x1 = upz * z0 - upx * z2,\n        x2 = upx * z1 - upy * z0;\n\n    len = x0 * x0 + x1 * x1 + x2 * x2;\n    if (len === 0) {\n        // up and z are parallel\n        if (upz) {\n            upx += 1e-6;\n        } else if (upy) {\n            upz += 1e-6;\n        } else {\n            upy += 1e-6;\n        }\n        (x0 = upy * z2 - upz * z1), (x1 = upz * z0 - upx * z2), (x2 = upx * z1 - upy * z0);\n\n        len = x0 * x0 + x1 * x1 + x2 * x2;\n    }\n\n    len = 1 / Math.sqrt(len);\n    x0 *= len;\n    x1 *= len;\n    x2 *= len;\n\n    out[0] = x0;\n    out[1] = x1;\n    out[2] = x2;\n    out[3] = 0;\n    out[4] = z1 * x2 - z2 * x1;\n    out[5] = z2 * x0 - z0 * x2;\n    out[6] = z0 * x1 - z1 * x0;\n    out[7] = 0;\n    out[8] = z0;\n    out[9] = z1;\n    out[10] = z2;\n    out[11] = 0;\n    out[12] = eyex;\n    out[13] = eyey;\n    out[14] = eyez;\n    out[15] = 1;\n    return out;\n}\n\n/**\n * Adds two mat4's\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the first operand\n * @param {mat4} b the second operand\n * @returns {mat4} out\n */\nexport function add(out, a, b) {\n    out[0] = a[0] + b[0];\n    out[1] = a[1] + b[1];\n    out[2] = a[2] + b[2];\n    out[3] = a[3] + b[3];\n    out[4] = a[4] + b[4];\n    out[5] = a[5] + b[5];\n    out[6] = a[6] + b[6];\n    out[7] = a[7] + b[7];\n    out[8] = a[8] + b[8];\n    out[9] = a[9] + b[9];\n    out[10] = a[10] + b[10];\n    out[11] = a[11] + b[11];\n    out[12] = a[12] + b[12];\n    out[13] = a[13] + b[13];\n    out[14] = a[14] + b[14];\n    out[15] = a[15] + b[15];\n    return out;\n}\n\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the first operand\n * @param {mat4} b the second operand\n * @returns {mat4} out\n */\nexport function subtract(out, a, b) {\n    out[0] = a[0] - b[0];\n    out[1] = a[1] - b[1];\n    out[2] = a[2] - b[2];\n    out[3] = a[3] - b[3];\n    out[4] = a[4] - b[4];\n    out[5] = a[5] - b[5];\n    out[6] = a[6] - b[6];\n    out[7] = a[7] - b[7];\n    out[8] = a[8] - b[8];\n    out[9] = a[9] - b[9];\n    out[10] = a[10] - b[10];\n    out[11] = a[11] - b[11];\n    out[12] = a[12] - b[12];\n    out[13] = a[13] - b[13];\n    out[14] = a[14] - b[14];\n    out[15] = a[15] - b[15];\n    return out;\n}\n\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat4} out the receiving matrix\n * @param {mat4} a the matrix to scale\n * @param {Number} b amount to scale the matrix's elements by\n * @returns {mat4} out\n */\nexport function multiplyScalar(out, a, b) {\n    out[0] = a[0] * b;\n    out[1] = a[1] * b;\n    out[2] = a[2] * b;\n    out[3] = a[3] * b;\n    out[4] = a[4] * b;\n    out[5] = a[5] * b;\n    out[6] = a[6] * b;\n    out[7] = a[7] * b;\n    out[8] = a[8] * b;\n    out[9] = a[9] * b;\n    out[10] = a[10] * b;\n    out[11] = a[11] * b;\n    out[12] = a[12] * b;\n    out[13] = a[13] * b;\n    out[14] = a[14] * b;\n    out[15] = a[15] * b;\n    return out;\n}\n","import * as Mat4Func from './functions/Mat4Func.js';\n\nexport class Mat4 extends Array {\n    constructor(\n        m00 = 1,\n        m01 = 0,\n        m02 = 0,\n        m03 = 0,\n        m10 = 0,\n        m11 = 1,\n        m12 = 0,\n        m13 = 0,\n        m20 = 0,\n        m21 = 0,\n        m22 = 1,\n        m23 = 0,\n        m30 = 0,\n        m31 = 0,\n        m32 = 0,\n        m33 = 1\n    ) {\n        super(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);\n        return this;\n    }\n\n    get x() {\n        return this[12];\n    }\n\n    get y() {\n        return this[13];\n    }\n\n    get z() {\n        return this[14];\n    }\n\n    get w() {\n        return this[15];\n    }\n\n    set x(v) {\n        this[12] = v;\n    }\n\n    set y(v) {\n        this[13] = v;\n    }\n\n    set z(v) {\n        this[14] = v;\n    }\n\n    set w(v) {\n        this[15] = v;\n    }\n\n    set(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n        if (m00.length) return this.copy(m00);\n        Mat4Func.set(this, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);\n        return this;\n    }\n\n    translate(v, m = this) {\n        Mat4Func.translate(this, m, v);\n        return this;\n    }\n\n    rotate(v, axis, m = this) {\n        Mat4Func.rotate(this, m, v, axis);\n        return this;\n    }\n\n    scale(v, m = this) {\n        Mat4Func.scale(this, m, typeof v === 'number' ? [v, v, v] : v);\n        return this;\n    }\n\n    add(ma, mb) {\n        if (mb) Mat4Func.add(this, ma, mb);\n        else Mat4Func.add(this, this, ma);\n        return this;\n    }\n\n    sub(ma, mb) {\n        if (mb) Mat4Func.subtract(this, ma, mb);\n        else Mat4Func.subtract(this, this, ma);\n        return this;\n    }\n\n    multiply(ma, mb) {\n        if (!ma.length) {\n            Mat4Func.multiplyScalar(this, this, ma);\n        } else if (mb) {\n            Mat4Func.multiply(this, ma, mb);\n        } else {\n            Mat4Func.multiply(this, this, ma);\n        }\n        return this;\n    }\n\n    identity() {\n        Mat4Func.identity(this);\n        return this;\n    }\n\n    copy(m) {\n        Mat4Func.copy(this, m);\n        return this;\n    }\n\n    fromPerspective({ fov, aspect, near, far } = {}) {\n        Mat4Func.perspective(this, fov, aspect, near, far);\n        return this;\n    }\n\n    fromOrthogonal({ left, right, bottom, top, near, far }) {\n        Mat4Func.ortho(this, left, right, bottom, top, near, far);\n        return this;\n    }\n\n    fromQuaternion(q) {\n        Mat4Func.fromQuat(this, q);\n        return this;\n    }\n\n    setPosition(v) {\n        this.x = v[0];\n        this.y = v[1];\n        this.z = v[2];\n        return this;\n    }\n\n    inverse(m = this) {\n        Mat4Func.invert(this, m);\n        return this;\n    }\n\n    compose(q, pos, scale) {\n        Mat4Func.compose(this, q, pos, scale);\n        return this;\n    }\n\n    decompose(q, pos, scale) {\n        Mat4Func.decompose(this, q, pos, scale);\n        return this;\n    }\n\n    getRotation(q) {\n        Mat4Func.getRotation(q, this);\n        return this;\n    }\n\n    getTranslation(pos) {\n        Mat4Func.getTranslation(pos, this);\n        return this;\n    }\n\n    getScaling(scale) {\n        Mat4Func.getScaling(scale, this);\n        return this;\n    }\n\n    getMaxScaleOnAxis() {\n        return Mat4Func.getMaxScaleOnAxis(this);\n    }\n\n    lookAt(eye, target, up) {\n        Mat4Func.targetTo(this, eye, target, up);\n        return this;\n    }\n\n    determinant() {\n        return Mat4Func.determinant(this);\n    }\n\n    fromArray(a, o = 0) {\n        this[0] = a[o];\n        this[1] = a[o + 1];\n        this[2] = a[o + 2];\n        this[3] = a[o + 3];\n        this[4] = a[o + 4];\n        this[5] = a[o + 5];\n        this[6] = a[o + 6];\n        this[7] = a[o + 7];\n        this[8] = a[o + 8];\n        this[9] = a[o + 9];\n        this[10] = a[o + 10];\n        this[11] = a[o + 11];\n        this[12] = a[o + 12];\n        this[13] = a[o + 13];\n        this[14] = a[o + 14];\n        this[15] = a[o + 15];\n        return this;\n    }\n\n    toArray(a = [], o = 0) {\n        a[o] = this[0];\n        a[o + 1] = this[1];\n        a[o + 2] = this[2];\n        a[o + 3] = this[3];\n        a[o + 4] = this[4];\n        a[o + 5] = this[5];\n        a[o + 6] = this[6];\n        a[o + 7] = this[7];\n        a[o + 8] = this[8];\n        a[o + 9] = this[9];\n        a[o + 10] = this[10];\n        a[o + 11] = this[11];\n        a[o + 12] = this[12];\n        a[o + 13] = this[13];\n        a[o + 14] = this[14];\n        a[o + 15] = this[15];\n        return a;\n    }\n}\n","// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\nexport function fromRotationMatrix(out, m, order = 'YXZ') {\n    if (order === 'XYZ') {\n        out[1] = Math.asin(Math.min(Math.max(m[8], -1), 1));\n        if (Math.abs(m[8]) < 0.99999) {\n            out[0] = Math.atan2(-m[9], m[10]);\n            out[2] = Math.atan2(-m[4], m[0]);\n        } else {\n            out[0] = Math.atan2(m[6], m[5]);\n            out[2] = 0;\n        }\n    } else if (order === 'YXZ') {\n        out[0] = Math.asin(-Math.min(Math.max(m[9], -1), 1));\n        if (Math.abs(m[9]) < 0.99999) {\n            out[1] = Math.atan2(m[8], m[10]);\n            out[2] = Math.atan2(m[1], m[5]);\n        } else {\n            out[1] = Math.atan2(-m[2], m[0]);\n            out[2] = 0;\n        }\n    } else if (order === 'ZXY') {\n        out[0] = Math.asin(Math.min(Math.max(m[6], -1), 1));\n        if (Math.abs(m[6]) < 0.99999) {\n            out[1] = Math.atan2(-m[2], m[10]);\n            out[2] = Math.atan2(-m[4], m[5]);\n        } else {\n            out[1] = 0;\n            out[2] = Math.atan2(m[1], m[0]);\n        }\n    } else if (order === 'ZYX') {\n        out[1] = Math.asin(-Math.min(Math.max(m[2], -1), 1));\n        if (Math.abs(m[2]) < 0.99999) {\n            out[0] = Math.atan2(m[6], m[10]);\n            out[2] = Math.atan2(m[1], m[0]);\n        } else {\n            out[0] = 0;\n            out[2] = Math.atan2(-m[4], m[5]);\n        }\n    } else if (order === 'YZX') {\n        out[2] = Math.asin(Math.min(Math.max(m[1], -1), 1));\n        if (Math.abs(m[1]) < 0.99999) {\n            out[0] = Math.atan2(-m[9], m[5]);\n            out[1] = Math.atan2(-m[2], m[0]);\n        } else {\n            out[0] = 0;\n            out[1] = Math.atan2(m[8], m[10]);\n        }\n    } else if (order === 'XZY') {\n        out[2] = Math.asin(-Math.min(Math.max(m[4], -1), 1));\n        if (Math.abs(m[4]) < 0.99999) {\n            out[0] = Math.atan2(m[6], m[5]);\n            out[1] = Math.atan2(m[8], m[0]);\n        } else {\n            out[0] = Math.atan2(-m[9], m[10]);\n            out[1] = 0;\n        }\n    }\n\n    return out;\n}\n","import * as EulerFunc from './functions/EulerFunc.js';\nimport { Mat4 } from './Mat4.js';\n\nconst tmpMat4 = /* @__PURE__ */ new Mat4();\n\nexport class Euler extends Array {\n    constructor(x = 0, y = x, z = x, order = 'YXZ') {\n        super(x, y, z);\n        this.order = order;\n        this.onChange = () => {};\n\n        // Keep reference to proxy target to avoid triggering onChange internally\n        this._target = this;\n\n        // Return a proxy to trigger onChange when array elements are edited directly\n        const triggerProps = ['0', '1', '2'];\n        return new Proxy(this, {\n            set(target, property) {\n                const success = Reflect.set(...arguments);\n                if (success && triggerProps.includes(property)) target.onChange();\n                return success;\n            },\n        });\n    }\n\n    get x() {\n        return this[0];\n    }\n\n    get y() {\n        return this[1];\n    }\n\n    get z() {\n        return this[2];\n    }\n\n    set x(v) {\n        this._target[0] = v;\n        this.onChange();\n    }\n\n    set y(v) {\n        this._target[1] = v;\n        this.onChange();\n    }\n\n    set z(v) {\n        this._target[2] = v;\n        this.onChange();\n    }\n\n    set(x, y = x, z = x) {\n        if (x.length) return this.copy(x);\n        this._target[0] = x;\n        this._target[1] = y;\n        this._target[2] = z;\n        this.onChange();\n        return this;\n    }\n\n    copy(v) {\n        this._target[0] = v[0];\n        this._target[1] = v[1];\n        this._target[2] = v[2];\n        this.onChange();\n        return this;\n    }\n\n    reorder(order) {\n        this._target.order = order;\n        this.onChange();\n        return this;\n    }\n\n    fromRotationMatrix(m, order = this.order) {\n        EulerFunc.fromRotationMatrix(this._target, m, order);\n        this.onChange();\n        return this;\n    }\n\n    fromQuaternion(q, order = this.order, isInternal) {\n        tmpMat4.fromQuaternion(q);\n        this._target.fromRotationMatrix(tmpMat4, order);\n        // Avoid infinite recursion\n        if (!isInternal) this.onChange();\n        return this;\n    }\n\n    fromArray(a, o = 0) {\n        this._target[0] = a[o];\n        this._target[1] = a[o + 1];\n        this._target[2] = a[o + 2];\n        return this;\n    }\n\n    toArray(a = [], o = 0) {\n        a[o] = this[0];\n        a[o + 1] = this[1];\n        a[o + 2] = this[2];\n        return a;\n    }\n}\n","import { Vec3 } from '../math/Vec3.js';\nimport { Quat } from '../math/Quat.js';\nimport { Mat4 } from '../math/Mat4.js';\nimport { Euler } from '../math/Euler.js';\n\nexport class Transform {\n    constructor() {\n        this.parent = null;\n        this.children = [];\n        this.visible = true;\n\n        this.matrix = new Mat4();\n        this.worldMatrix = new Mat4();\n        this.matrixAutoUpdate = true;\n        this.worldMatrixNeedsUpdate = false;\n\n        this.position = new Vec3();\n        this.quaternion = new Quat();\n        this.scale = new Vec3(1);\n        this.rotation = new Euler();\n        this.up = new Vec3(0, 1, 0);\n\n        this.rotation._target.onChange = () => this.quaternion.fromEuler(this.rotation, true);\n        this.quaternion._target.onChange = () => this.rotation.fromQuaternion(this.quaternion, undefined, true);\n    }\n\n    setParent(parent, notifyParent = true) {\n        if (this.parent && parent !== this.parent) this.parent.removeChild(this, false);\n        this.parent = parent;\n        if (notifyParent && parent) parent.addChild(this, false);\n    }\n\n    addChild(child, notifyChild = true) {\n        if (!~this.children.indexOf(child)) this.children.push(child);\n        if (notifyChild) child.setParent(this, false);\n    }\n\n    removeChild(child, notifyChild = true) {\n        if (!!~this.children.indexOf(child)) this.children.splice(this.children.indexOf(child), 1);\n        if (notifyChild) child.setParent(null, false);\n    }\n\n    updateMatrixWorld(force) {\n        if (this.matrixAutoUpdate) this.updateMatrix();\n        if (this.worldMatrixNeedsUpdate || force) {\n            if (this.parent === null) this.worldMatrix.copy(this.matrix);\n            else this.worldMatrix.multiply(this.parent.worldMatrix, this.matrix);\n            this.worldMatrixNeedsUpdate = false;\n            force = true;\n        }\n\n        for (let i = 0, l = this.children.length; i < l; i++) {\n            this.children[i].updateMatrixWorld(force);\n        }\n    }\n\n    updateMatrix() {\n        this.matrix.compose(this.quaternion, this.position, this.scale);\n        this.worldMatrixNeedsUpdate = true;\n    }\n\n    traverse(callback) {\n        // Return true in callback to stop traversing children\n        if (callback(this)) return;\n        for (let i = 0, l = this.children.length; i < l; i++) {\n            this.children[i].traverse(callback);\n        }\n    }\n\n    decompose() {\n        this.matrix.decompose(this.quaternion._target, this.position, this.scale);\n        this.rotation.fromQuaternion(this.quaternion);\n    }\n\n    lookAt(target, invert = false) {\n        if (invert) this.matrix.lookAt(this.position, target, this.up);\n        else this.matrix.lookAt(target, this.position, this.up);\n        this.matrix.getRotation(this.quaternion._target);\n        this.rotation.fromQuaternion(this.quaternion);\n    }\n}\n","import { Transform } from './Transform.js';\nimport { Mat4 } from '../math/Mat4.js';\nimport { Vec3 } from '../math/Vec3.js';\n\nconst tempMat4 = /* @__PURE__ */ new Mat4();\nconst tempVec3a = /* @__PURE__ */ new Vec3();\nconst tempVec3b = /* @__PURE__ */ new Vec3();\n\nexport class Camera extends Transform {\n    constructor(gl, { near = 0.1, far = 100, fov = 45, aspect = 1, left, right, bottom, top, zoom = 1 } = {}) {\n        super();\n\n        Object.assign(this, { near, far, fov, aspect, left, right, bottom, top, zoom });\n\n        this.projectionMatrix = new Mat4();\n        this.viewMatrix = new Mat4();\n        this.projectionViewMatrix = new Mat4();\n        this.worldPosition = new Vec3();\n\n        // Use orthographic if left/right set, else default to perspective camera\n        this.type = left || right ? 'orthographic' : 'perspective';\n\n        if (this.type === 'orthographic') this.orthographic();\n        else this.perspective();\n    }\n\n    perspective({ near = this.near, far = this.far, fov = this.fov, aspect = this.aspect } = {}) {\n        Object.assign(this, { near, far, fov, aspect });\n        this.projectionMatrix.fromPerspective({ fov: fov * (Math.PI / 180), aspect, near, far });\n        this.type = 'perspective';\n        return this;\n    }\n\n    orthographic({\n        near = this.near,\n        far = this.far,\n        left = this.left || -1,\n        right = this.right || 1,\n        bottom = this.bottom || -1,\n        top = this.top || 1,\n        zoom = this.zoom,\n    } = {}) {\n        Object.assign(this, { near, far, left, right, bottom, top, zoom });\n        left /= zoom;\n        right /= zoom;\n        bottom /= zoom;\n        top /= zoom;\n        this.projectionMatrix.fromOrthogonal({ left, right, bottom, top, near, far });\n        this.type = 'orthographic';\n        return this;\n    }\n\n    updateMatrixWorld() {\n        super.updateMatrixWorld();\n        this.viewMatrix.inverse(this.worldMatrix);\n        this.worldMatrix.getTranslation(this.worldPosition);\n\n        // used for sorting\n        this.projectionViewMatrix.multiply(this.projectionMatrix, this.viewMatrix);\n        return this;\n    }\n\n    updateProjectionMatrix() {\n        if (this.type === 'perspective') {\n            return this.perspective();\n        } else {\n            return this.orthographic();\n        }\n    }\n\n    lookAt(target) {\n        super.lookAt(target, true);\n        return this;\n    }\n\n    // Project 3D coordinate to 2D point\n    project(v) {\n        v.applyMatrix4(this.viewMatrix);\n        v.applyMatrix4(this.projectionMatrix);\n        return this;\n    }\n\n    // Unproject 2D point to 3D coordinate\n    unproject(v) {\n        v.applyMatrix4(tempMat4.inverse(this.projectionMatrix));\n        v.applyMatrix4(this.worldMatrix);\n        return this;\n    }\n\n    updateFrustum() {\n        if (!this.frustum) {\n            this.frustum = [new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3()];\n        }\n\n        const m = this.projectionViewMatrix;\n        this.frustum[0].set(m[3] - m[0], m[7] - m[4], m[11] - m[8]).constant = m[15] - m[12]; // -x\n        this.frustum[1].set(m[3] + m[0], m[7] + m[4], m[11] + m[8]).constant = m[15] + m[12]; // +x\n        this.frustum[2].set(m[3] + m[1], m[7] + m[5], m[11] + m[9]).constant = m[15] + m[13]; // +y\n        this.frustum[3].set(m[3] - m[1], m[7] - m[5], m[11] - m[9]).constant = m[15] - m[13]; // -y\n        this.frustum[4].set(m[3] - m[2], m[7] - m[6], m[11] - m[10]).constant = m[15] - m[14]; // +z (far)\n        this.frustum[5].set(m[3] + m[2], m[7] + m[6], m[11] + m[10]).constant = m[15] + m[14]; // -z (near)\n\n        for (let i = 0; i < 6; i++) {\n            const invLen = 1.0 / this.frustum[i].distance();\n            this.frustum[i].multiply(invLen);\n            this.frustum[i].constant *= invLen;\n        }\n    }\n\n    frustumIntersectsMesh(node, worldMatrix = node.worldMatrix) {\n        // If no position attribute, treat as frustumCulled false\n        if (!node.geometry.attributes.position) return true;\n\n        if (!node.geometry.bounds || node.geometry.bounds.radius === Infinity) node.geometry.computeBoundingSphere();\n\n        if (!node.geometry.bounds) return true;\n\n        const center = tempVec3a;\n        center.copy(node.geometry.bounds.center);\n        center.applyMatrix4(worldMatrix);\n\n        const radius = node.geometry.bounds.radius * worldMatrix.getMaxScaleOnAxis();\n\n        return this.frustumIntersectsSphere(center, radius);\n    }\n\n    frustumIntersectsSphere(center, radius) {\n        const normal = tempVec3b;\n\n        for (let i = 0; i < 6; i++) {\n            const plane = this.frustum[i];\n            const distance = normal.copy(plane).dot(center) + plane.constant;\n            if (distance < -radius) return false;\n        }\n        return true;\n    }\n}\n","const EPSILON = 0.000001;\n\n/**\n * Copies the upper-left 3x3 values into the given mat3.\n *\n * @param {mat3} out the receiving 3x3 matrix\n * @param {mat4} a   the source 4x4 matrix\n * @returns {mat3} out\n */\nexport function fromMat4(out, a) {\n    out[0] = a[0];\n    out[1] = a[1];\n    out[2] = a[2];\n    out[3] = a[4];\n    out[4] = a[5];\n    out[5] = a[6];\n    out[6] = a[8];\n    out[7] = a[9];\n    out[8] = a[10];\n    return out;\n}\n\n/**\n * Calculates a 3x3 matrix from the given quaternion\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {quat} q Quaternion to create matrix from\n *\n * @returns {mat3} out\n */\nexport function fromQuat(out, q) {\n    let x = q[0],\n        y = q[1],\n        z = q[2],\n        w = q[3];\n    let x2 = x + x;\n    let y2 = y + y;\n    let z2 = z + z;\n\n    let xx = x * x2;\n    let yx = y * x2;\n    let yy = y * y2;\n    let zx = z * x2;\n    let zy = z * y2;\n    let zz = z * z2;\n    let wx = w * x2;\n    let wy = w * y2;\n    let wz = w * z2;\n\n    out[0] = 1 - yy - zz;\n    out[3] = yx - wz;\n    out[6] = zx + wy;\n\n    out[1] = yx + wz;\n    out[4] = 1 - xx - zz;\n    out[7] = zy - wx;\n\n    out[2] = zx - wy;\n    out[5] = zy + wx;\n    out[8] = 1 - xx - yy;\n\n    return out;\n}\n\n/**\n * Copy the values from one mat3 to another\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the source matrix\n * @returns {mat3} out\n */\nexport function copy(out, a) {\n    out[0] = a[0];\n    out[1] = a[1];\n    out[2] = a[2];\n    out[3] = a[3];\n    out[4] = a[4];\n    out[5] = a[5];\n    out[6] = a[6];\n    out[7] = a[7];\n    out[8] = a[8];\n    return out;\n}\n\n/**\n * Set the components of a mat3 to the given values\n *\n * @param {mat3} out the receiving matrix\n * @returns {mat3} out\n */\nexport function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n    out[0] = m00;\n    out[1] = m01;\n    out[2] = m02;\n    out[3] = m10;\n    out[4] = m11;\n    out[5] = m12;\n    out[6] = m20;\n    out[7] = m21;\n    out[8] = m22;\n    return out;\n}\n\n/**\n * Set a mat3 to the identity matrix\n *\n * @param {mat3} out the receiving matrix\n * @returns {mat3} out\n */\nexport function identity(out) {\n    out[0] = 1;\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 0;\n    out[4] = 1;\n    out[5] = 0;\n    out[6] = 0;\n    out[7] = 0;\n    out[8] = 1;\n    return out;\n}\n\n/**\n * Transpose the values of a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the source matrix\n * @returns {mat3} out\n */\nexport function transpose(out, a) {\n    // If we are transposing ourselves we can skip a few steps but have to cache some values\n    if (out === a) {\n        let a01 = a[1],\n            a02 = a[2],\n            a12 = a[5];\n        out[1] = a[3];\n        out[2] = a[6];\n        out[3] = a01;\n        out[5] = a[7];\n        out[6] = a02;\n        out[7] = a12;\n    } else {\n        out[0] = a[0];\n        out[1] = a[3];\n        out[2] = a[6];\n        out[3] = a[1];\n        out[4] = a[4];\n        out[5] = a[7];\n        out[6] = a[2];\n        out[7] = a[5];\n        out[8] = a[8];\n    }\n\n    return out;\n}\n\n/**\n * Inverts a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the source matrix\n * @returns {mat3} out\n */\nexport function invert(out, a) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2];\n    let a10 = a[3],\n        a11 = a[4],\n        a12 = a[5];\n    let a20 = a[6],\n        a21 = a[7],\n        a22 = a[8];\n\n    let b01 = a22 * a11 - a12 * a21;\n    let b11 = -a22 * a10 + a12 * a20;\n    let b21 = a21 * a10 - a11 * a20;\n\n    // Calculate the determinant\n    let det = a00 * b01 + a01 * b11 + a02 * b21;\n\n    if (!det) {\n        return null;\n    }\n    det = 1.0 / det;\n\n    out[0] = b01 * det;\n    out[1] = (-a22 * a01 + a02 * a21) * det;\n    out[2] = (a12 * a01 - a02 * a11) * det;\n    out[3] = b11 * det;\n    out[4] = (a22 * a00 - a02 * a20) * det;\n    out[5] = (-a12 * a00 + a02 * a10) * det;\n    out[6] = b21 * det;\n    out[7] = (-a21 * a00 + a01 * a20) * det;\n    out[8] = (a11 * a00 - a01 * a10) * det;\n    return out;\n}\n\n/**\n * Calculates the determinant of a mat3\n *\n * @param {mat3} a the source matrix\n * @returns {Number} determinant of a\n */\nexport function determinant(a) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2];\n    let a10 = a[3],\n        a11 = a[4],\n        a12 = a[5];\n    let a20 = a[6],\n        a21 = a[7],\n        a22 = a[8];\n\n    return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);\n}\n\n/**\n * Multiplies two mat3's\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the first operand\n * @param {mat3} b the second operand\n * @returns {mat3} out\n */\nexport function multiply(out, a, b) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2];\n    let a10 = a[3],\n        a11 = a[4],\n        a12 = a[5];\n    let a20 = a[6],\n        a21 = a[7],\n        a22 = a[8];\n\n    let b00 = b[0],\n        b01 = b[1],\n        b02 = b[2];\n    let b10 = b[3],\n        b11 = b[4],\n        b12 = b[5];\n    let b20 = b[6],\n        b21 = b[7],\n        b22 = b[8];\n\n    out[0] = b00 * a00 + b01 * a10 + b02 * a20;\n    out[1] = b00 * a01 + b01 * a11 + b02 * a21;\n    out[2] = b00 * a02 + b01 * a12 + b02 * a22;\n\n    out[3] = b10 * a00 + b11 * a10 + b12 * a20;\n    out[4] = b10 * a01 + b11 * a11 + b12 * a21;\n    out[5] = b10 * a02 + b11 * a12 + b12 * a22;\n\n    out[6] = b20 * a00 + b21 * a10 + b22 * a20;\n    out[7] = b20 * a01 + b21 * a11 + b22 * a21;\n    out[8] = b20 * a02 + b21 * a12 + b22 * a22;\n    return out;\n}\n\n/**\n * Translate a mat3 by the given vector\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the matrix to translate\n * @param {vec2} v vector to translate by\n * @returns {mat3} out\n */\nexport function translate(out, a, v) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2],\n        a10 = a[3],\n        a11 = a[4],\n        a12 = a[5],\n        a20 = a[6],\n        a21 = a[7],\n        a22 = a[8],\n        x = v[0],\n        y = v[1];\n\n    out[0] = a00;\n    out[1] = a01;\n    out[2] = a02;\n\n    out[3] = a10;\n    out[4] = a11;\n    out[5] = a12;\n\n    out[6] = x * a00 + y * a10 + a20;\n    out[7] = x * a01 + y * a11 + a21;\n    out[8] = x * a02 + y * a12 + a22;\n    return out;\n}\n\n/**\n * Rotates a mat3 by the given angle\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat3} out\n */\nexport function rotate(out, a, rad) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2],\n        a10 = a[3],\n        a11 = a[4],\n        a12 = a[5],\n        a20 = a[6],\n        a21 = a[7],\n        a22 = a[8],\n        s = Math.sin(rad),\n        c = Math.cos(rad);\n\n    out[0] = c * a00 + s * a10;\n    out[1] = c * a01 + s * a11;\n    out[2] = c * a02 + s * a12;\n\n    out[3] = c * a10 - s * a00;\n    out[4] = c * a11 - s * a01;\n    out[5] = c * a12 - s * a02;\n\n    out[6] = a20;\n    out[7] = a21;\n    out[8] = a22;\n    return out;\n}\n\n/**\n * Scales the mat3 by the dimensions in the given vec2\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the matrix to rotate\n * @param {vec2} v the vec2 to scale the matrix by\n * @returns {mat3} out\n **/\nexport function scale(out, a, v) {\n    let x = v[0],\n        y = v[1];\n\n    out[0] = x * a[0];\n    out[1] = x * a[1];\n    out[2] = x * a[2];\n\n    out[3] = y * a[3];\n    out[4] = y * a[4];\n    out[5] = y * a[5];\n\n    out[6] = a[6];\n    out[7] = a[7];\n    out[8] = a[8];\n    return out;\n}\n\n/**\n * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {mat4} a Mat4 to derive the normal matrix from\n *\n * @returns {mat3} out\n */\nexport function normalFromMat4(out, a) {\n    let a00 = a[0],\n        a01 = a[1],\n        a02 = a[2],\n        a03 = a[3];\n    let a10 = a[4],\n        a11 = a[5],\n        a12 = a[6],\n        a13 = a[7];\n    let a20 = a[8],\n        a21 = a[9],\n        a22 = a[10],\n        a23 = a[11];\n    let a30 = a[12],\n        a31 = a[13],\n        a32 = a[14],\n        a33 = a[15];\n\n    let b00 = a00 * a11 - a01 * a10;\n    let b01 = a00 * a12 - a02 * a10;\n    let b02 = a00 * a13 - a03 * a10;\n    let b03 = a01 * a12 - a02 * a11;\n    let b04 = a01 * a13 - a03 * a11;\n    let b05 = a02 * a13 - a03 * a12;\n    let b06 = a20 * a31 - a21 * a30;\n    let b07 = a20 * a32 - a22 * a30;\n    let b08 = a20 * a33 - a23 * a30;\n    let b09 = a21 * a32 - a22 * a31;\n    let b10 = a21 * a33 - a23 * a31;\n    let b11 = a22 * a33 - a23 * a32;\n\n    // Calculate the determinant\n    let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n    if (!det) {\n        return null;\n    }\n    det = 1.0 / det;\n\n    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n    out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n    out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n\n    out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n    out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n    out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n\n    out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n    out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n    out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n\n    return out;\n}\n\n/**\n * Generates a 2D projection matrix with the given bounds\n *\n * @param {mat3} out mat3 frustum matrix will be written into\n * @param {number} width Width of your gl context\n * @param {number} height Height of gl context\n * @returns {mat3} out\n */\nexport function projection(out, width, height) {\n    out[0] = 2 / width;\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 0;\n    out[4] = -2 / height;\n    out[5] = 0;\n    out[6] = -1;\n    out[7] = 1;\n    out[8] = 1;\n    return out;\n}\n\n/**\n * Adds two mat3's\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the first operand\n * @param {mat3} b the second operand\n * @returns {mat3} out\n */\nexport function add(out, a, b) {\n    out[0] = a[0] + b[0];\n    out[1] = a[1] + b[1];\n    out[2] = a[2] + b[2];\n    out[3] = a[3] + b[3];\n    out[4] = a[4] + b[4];\n    out[5] = a[5] + b[5];\n    out[6] = a[6] + b[6];\n    out[7] = a[7] + b[7];\n    out[8] = a[8] + b[8];\n    return out;\n}\n\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the first operand\n * @param {mat3} b the second operand\n * @returns {mat3} out\n */\nexport function subtract(out, a, b) {\n    out[0] = a[0] - b[0];\n    out[1] = a[1] - b[1];\n    out[2] = a[2] - b[2];\n    out[3] = a[3] - b[3];\n    out[4] = a[4] - b[4];\n    out[5] = a[5] - b[5];\n    out[6] = a[6] - b[6];\n    out[7] = a[7] - b[7];\n    out[8] = a[8] - b[8];\n    return out;\n}\n\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat3} out the receiving matrix\n * @param {mat3} a the matrix to scale\n * @param {Number} b amount to scale the matrix's elements by\n * @returns {mat3} out\n */\nexport function multiplyScalar(out, a, b) {\n    out[0] = a[0] * b;\n    out[1] = a[1] * b;\n    out[2] = a[2] * b;\n    out[3] = a[3] * b;\n    out[4] = a[4] * b;\n    out[5] = a[5] * b;\n    out[6] = a[6] * b;\n    out[7] = a[7] * b;\n    out[8] = a[8] * b;\n    return out;\n}\n","import * as Mat3Func from './functions/Mat3Func.js';\n\nexport class Mat3 extends Array {\n    constructor(m00 = 1, m01 = 0, m02 = 0, m10 = 0, m11 = 1, m12 = 0, m20 = 0, m21 = 0, m22 = 1) {\n        super(m00, m01, m02, m10, m11, m12, m20, m21, m22);\n        return this;\n    }\n\n    set(m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n        if (m00.length) return this.copy(m00);\n        Mat3Func.set(this, m00, m01, m02, m10, m11, m12, m20, m21, m22);\n        return this;\n    }\n\n    translate(v, m = this) {\n        Mat3Func.translate(this, m, v);\n        return this;\n    }\n\n    rotate(v, m = this) {\n        Mat3Func.rotate(this, m, v);\n        return this;\n    }\n\n    scale(v, m = this) {\n        Mat3Func.scale(this, m, v);\n        return this;\n    }\n\n    multiply(ma, mb) {\n        if (mb) {\n            Mat3Func.multiply(this, ma, mb);\n        } else {\n            Mat3Func.multiply(this, this, ma);\n        }\n        return this;\n    }\n\n    identity() {\n        Mat3Func.identity(this);\n        return this;\n    }\n\n    copy(m) {\n        Mat3Func.copy(this, m);\n        return this;\n    }\n\n    fromMatrix4(m) {\n        Mat3Func.fromMat4(this, m);\n        return this;\n    }\n\n    fromQuaternion(q) {\n        Mat3Func.fromQuat(this, q);\n        return this;\n    }\n\n    fromBasis(vec3a, vec3b, vec3c) {\n        this.set(vec3a[0], vec3a[1], vec3a[2], vec3b[0], vec3b[1], vec3b[2], vec3c[0], vec3c[1], vec3c[2]);\n        return this;\n    }\n\n    inverse(m = this) {\n        Mat3Func.invert(this, m);\n        return this;\n    }\n\n    getNormalMatrix(m) {\n        Mat3Func.normalFromMat4(this, m);\n        return this;\n    }\n}\n","import { Transform } from './Transform.js';\nimport { Mat3 } from '../math/Mat3.js';\nimport { Mat4 } from '../math/Mat4.js';\n\nlet ID = 0;\n\nexport class Mesh extends Transform {\n    constructor(gl, { geometry, program, mode = gl.TRIANGLES, frustumCulled = true, renderOrder = 0 } = {}) {\n        super();\n        if (!gl.canvas) console.error('gl not passed as first argument to Mesh');\n        this.gl = gl;\n        this.id = ID++;\n        this.geometry = geometry;\n        this.program = program;\n        this.mode = mode;\n\n        // Used to skip frustum culling\n        this.frustumCulled = frustumCulled;\n\n        // Override sorting to force an order\n        this.renderOrder = renderOrder;\n        this.modelViewMatrix = new Mat4();\n        this.normalMatrix = new Mat3();\n        this.beforeRenderCallbacks = [];\n        this.afterRenderCallbacks = [];\n    }\n\n    onBeforeRender(f) {\n        this.beforeRenderCallbacks.push(f);\n        return this;\n    }\n\n    onAfterRender(f) {\n        this.afterRenderCallbacks.push(f);\n        return this;\n    }\n\n    draw({ camera } = {}) {\n        if (camera) {\n            // Add empty matrix uniforms to program if unset\n            if (!this.program.uniforms.modelMatrix) {\n                Object.assign(this.program.uniforms, {\n                    modelMatrix: { value: null },\n                    viewMatrix: { value: null },\n                    modelViewMatrix: { value: null },\n                    normalMatrix: { value: null },\n                    projectionMatrix: { value: null },\n                    cameraPosition: { value: null },\n                });\n            }\n\n            // Set the matrix uniforms\n            this.program.uniforms.projectionMatrix.value = camera.projectionMatrix;\n            this.program.uniforms.cameraPosition.value = camera.worldPosition;\n            this.program.uniforms.viewMatrix.value = camera.viewMatrix;\n            this.modelViewMatrix.multiply(camera.viewMatrix, this.worldMatrix);\n            this.normalMatrix.getNormalMatrix(this.modelViewMatrix);\n            this.program.uniforms.modelMatrix.value = this.worldMatrix;\n            this.program.uniforms.modelViewMatrix.value = this.modelViewMatrix;\n            this.program.uniforms.normalMatrix.value = this.normalMatrix;\n        }\n        this.beforeRenderCallbacks.forEach((f) => f && f({ mesh: this, camera }));\n\n        // determine if faces need to be flipped - when mesh scaled negatively\n        let flipFaces = this.program.cullFace && this.worldMatrix.determinant() < 0;\n        this.program.use({ flipFaces });\n        this.geometry.draw({ mode: this.mode, program: this.program });\n        this.afterRenderCallbacks.forEach((f) => f && f({ mesh: this, camera }));\n    }\n}\n","// TODO: delete texture\n// TODO: use texSubImage2D for updates (video or when loaded)\n// TODO: need? encoding = linearEncoding\n// TODO: support non-compressed mipmaps uploads\n\nconst emptyPixel = new Uint8Array(4);\n\nfunction isPowerOf2(value) {\n    return (value & (value - 1)) === 0;\n}\n\nlet ID = 1;\n\nexport class Texture {\n    constructor(\n        gl,\n        {\n            image,\n            target = gl.TEXTURE_2D,\n            type = gl.UNSIGNED_BYTE,\n            format = gl.RGBA,\n            internalFormat = format,\n            wrapS = gl.CLAMP_TO_EDGE,\n            wrapT = gl.CLAMP_TO_EDGE,\n            wrapR = gl.CLAMP_TO_EDGE,\n            generateMipmaps = target === (gl.TEXTURE_2D || gl.TEXTURE_CUBE_MAP),\n            minFilter = generateMipmaps ? gl.NEAREST_MIPMAP_LINEAR : gl.LINEAR,\n            magFilter = gl.LINEAR,\n            premultiplyAlpha = false,\n            unpackAlignment = 4,\n            flipY = target == (gl.TEXTURE_2D || gl.TEXTURE_3D) ? true : false,\n            anisotropy = 0,\n            level = 0,\n            width, // used for RenderTargets or Data Textures\n            height = width,\n            length = 1,\n        } = {}\n    ) {\n        this.gl = gl;\n        this.id = ID++;\n\n        this.image = image;\n        this.target = target;\n        this.type = type;\n        this.format = format;\n        this.internalFormat = internalFormat;\n        this.minFilter = minFilter;\n        this.magFilter = magFilter;\n        this.wrapS = wrapS;\n        this.wrapT = wrapT;\n        this.wrapR = wrapR;\n        this.generateMipmaps = generateMipmaps;\n        this.premultiplyAlpha = premultiplyAlpha;\n        this.unpackAlignment = unpackAlignment;\n        this.flipY = flipY;\n        this.anisotropy = Math.min(anisotropy, this.gl.renderer.parameters.maxAnisotropy);\n        this.level = level;\n        this.width = width;\n        this.height = height;\n        this.length = length;\n        this.texture = this.gl.createTexture();\n\n        this.store = {\n            image: null,\n        };\n\n        // Alias for state store to avoid redundant calls for global state\n        this.glState = this.gl.renderer.state;\n\n        // State store to avoid redundant calls for per-texture state\n        this.state = {};\n        this.state.minFilter = this.gl.NEAREST_MIPMAP_LINEAR;\n        this.state.magFilter = this.gl.LINEAR;\n        this.state.wrapS = this.gl.REPEAT;\n        this.state.wrapT = this.gl.REPEAT;\n        this.state.anisotropy = 0;\n    }\n\n    bind() {\n        // Already bound to active texture unit\n        if (this.glState.textureUnits[this.glState.activeTextureUnit] === this.id) return;\n        this.gl.bindTexture(this.target, this.texture);\n        this.glState.textureUnits[this.glState.activeTextureUnit] = this.id;\n    }\n\n    update(textureUnit = 0) {\n        const needsUpdate = !(this.image === this.store.image && !this.needsUpdate);\n\n        // Make sure that texture is bound to its texture unit\n        if (needsUpdate || this.glState.textureUnits[textureUnit] !== this.id) {\n            // set active texture unit to perform texture functions\n            this.gl.renderer.activeTexture(textureUnit);\n            this.bind();\n        }\n\n        if (!needsUpdate) return;\n        this.needsUpdate = false;\n\n        if (this.flipY !== this.glState.flipY) {\n            this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, this.flipY);\n            this.glState.flipY = this.flipY;\n        }\n\n        if (this.premultiplyAlpha !== this.glState.premultiplyAlpha) {\n            this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);\n            this.glState.premultiplyAlpha = this.premultiplyAlpha;\n        }\n\n        if (this.unpackAlignment !== this.glState.unpackAlignment) {\n            this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, this.unpackAlignment);\n            this.glState.unpackAlignment = this.unpackAlignment;\n        }\n\n        if (this.minFilter !== this.state.minFilter) {\n            this.gl.texParameteri(this.target, this.gl.TEXTURE_MIN_FILTER, this.minFilter);\n            this.state.minFilter = this.minFilter;\n        }\n\n        if (this.magFilter !== this.state.magFilter) {\n            this.gl.texParameteri(this.target, this.gl.TEXTURE_MAG_FILTER, this.magFilter);\n            this.state.magFilter = this.magFilter;\n        }\n\n        if (this.wrapS !== this.state.wrapS) {\n            this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_S, this.wrapS);\n            this.state.wrapS = this.wrapS;\n        }\n\n        if (this.wrapT !== this.state.wrapT) {\n            this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_T, this.wrapT);\n            this.state.wrapT = this.wrapT;\n        }\n\n        if (this.wrapR !== this.state.wrapR) {\n            this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_R, this.wrapR);\n            this.state.wrapR = this.wrapR;\n        }\n\n        if (this.anisotropy && this.anisotropy !== this.state.anisotropy) {\n            this.gl.texParameterf(this.target, this.gl.renderer.getExtension('EXT_texture_filter_anisotropic').TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropy);\n            this.state.anisotropy = this.anisotropy;\n        }\n\n        if (this.image) {\n            if (this.image.width) {\n                this.width = this.image.width;\n                this.height = this.image.height;\n            }\n\n            if (this.target === this.gl.TEXTURE_CUBE_MAP) {\n                // For cube maps\n                for (let i = 0; i < 6; i++) {\n                    this.gl.texImage2D(this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, this.level, this.internalFormat, this.format, this.type, this.image[i]);\n                }\n            } else if (ArrayBuffer.isView(this.image)) {\n                // Data texture\n                if (this.target === this.gl.TEXTURE_2D) {\n                    this.gl.texImage2D(this.target, this.level, this.internalFormat, this.width, this.height, 0, this.format, this.type, this.image);\n                } else if (this.target === this.gl.TEXTURE_2D_ARRAY || this.target === this.gl.TEXTURE_3D) {\n                    this.gl.texImage3D(this.target, this.level, this.internalFormat, this.width, this.height, this.length, 0, this.format, this.type, this.image);\n                }\n            } else if (this.image.isCompressedTexture) {\n                // Compressed texture\n                for (let level = 0; level < this.image.length; level++) {\n                    this.gl.compressedTexImage2D(this.target, level, this.internalFormat, this.image[level].width, this.image[level].height, 0, this.image[level].data);\n                }\n            } else {\n                // Regular texture\n                if (this.target === this.gl.TEXTURE_2D) {\n                    this.gl.texImage2D(this.target, this.level, this.internalFormat, this.format, this.type, this.image);\n                } else {\n                    this.gl.texImage3D(this.target, this.level, this.internalFormat, this.width, this.height, this.length, 0, this.format, this.type, this.image);\n                }\n            }\n\n            if (this.generateMipmaps) {\n                // For WebGL1, if not a power of 2, turn off mips, set wrapping to clamp to edge and minFilter to linear\n                if (!this.gl.renderer.isWebgl2 && (!isPowerOf2(this.image.width) || !isPowerOf2(this.image.height))) {\n                    this.generateMipmaps = false;\n                    this.wrapS = this.wrapT = this.gl.CLAMP_TO_EDGE;\n                    this.minFilter = this.gl.LINEAR;\n                } else {\n                    this.gl.generateMipmap(this.target);\n                }\n            }\n\n            // Callback for when data is pushed to GPU\n            this.onUpdate && this.onUpdate();\n        } else {\n            if (this.target === this.gl.TEXTURE_CUBE_MAP) {\n                // Upload empty pixel for each side while no image to avoid errors while image or video loading\n                for (let i = 0; i < 6; i++) {\n                    this.gl.texImage2D(this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, this.gl.RGBA, 1, 1, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, emptyPixel);\n                }\n            } else if (this.width) {\n                // image intentionally left null for RenderTarget\n                if (this.target === this.gl.TEXTURE_2D) {\n                    this.gl.texImage2D(this.target, this.level, this.internalFormat, this.width, this.height, 0, this.format, this.type, null);\n                } else {\n                    this.gl.texImage3D(this.target, this.level, this.internalFormat, this.width, this.height, this.length, 0, this.format, this.type, null);\n                }\n            } else {\n                // Upload empty pixel if no image to avoid errors while image or video loading\n                this.gl.texImage2D(this.target, 0, this.gl.RGBA, 1, 1, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, emptyPixel);\n            }\n        }\n        this.store.image = this.image;\n    }\n}\n","import { Texture } from './Texture.js'\n\nexport class RenderTarget {\n    constructor(\n        gl,\n        {\n            width = gl.canvas.width,\n            height = gl.canvas.height,\n            target = gl.FRAMEBUFFER,\n            color = 1, // number of color attachments\n            depth = true,\n            stencil = false,\n            depthTexture = false,\n            wrapS = gl.CLAMP_TO_EDGE,\n            wrapT = gl.CLAMP_TO_EDGE,\n            wrapR = gl.CLAMP_TO_EDGE,\n            minFilter = gl.LINEAR,\n            magFilter = minFilter,\n            type = gl.UNSIGNED_BYTE,\n            format = gl.RGBA,\n            internalFormat = format,\n            unpackAlignment,\n            premultiplyAlpha,\n        } = {}\n    ) {\n        this.gl = gl;\n        this.width = width;\n        this.height = height;\n        this.depth = depth;\n        this.stencil = stencil;\n        this.buffer = this.gl.createFramebuffer();\n        this.target = target;\n        this.gl.renderer.bindFramebuffer(this);\n\n        this.textures = [];\n        const drawBuffers = [];\n\n        // create and attach required num of color textures\n        for (let i = 0; i < color; i++) {\n            this.textures.push(\n                new Texture(gl, {\n                    width,\n                    height,\n                    wrapS,\n                    wrapT,\n                    wrapR,\n                    minFilter,\n                    magFilter,\n                    type,\n                    format,\n                    internalFormat,\n                    unpackAlignment,\n                    premultiplyAlpha,\n                    flipY: false,\n                    generateMipmaps: false,\n                })\n            );\n            this.textures[i].update();\n            this.gl.framebufferTexture2D(this.target, this.gl.COLOR_ATTACHMENT0 + i, this.gl.TEXTURE_2D, this.textures[i].texture, 0 /* level */);\n            drawBuffers.push(this.gl.COLOR_ATTACHMENT0 + i);\n        }\n\n        // For multi-render targets shader access\n        if (drawBuffers.length > 1) this.gl.renderer.drawBuffers(drawBuffers);\n\n        // alias for majority of use cases\n        this.texture = this.textures[0];\n\n        // note depth textures break stencil - so can't use together\n        if (depthTexture && (this.gl.renderer.isWebgl2 || this.gl.renderer.getExtension('WEBGL_depth_texture'))) {\n            this.depthTexture = new Texture(gl, {\n                width,\n                height,\n                minFilter: this.gl.NEAREST,\n                magFilter: this.gl.NEAREST,\n                format: this.stencil ? this.gl.DEPTH_STENCIL : this.gl.DEPTH_COMPONENT,\n                internalFormat: gl.renderer.isWebgl2 ? (this.stencil ? this.gl.DEPTH24_STENCIL8 : this.gl.DEPTH_COMPONENT16) : this.gl.DEPTH_COMPONENT,\n                type: this.stencil ? this.gl.UNSIGNED_INT_24_8 : this.gl.UNSIGNED_INT,\n            });\n            this.depthTexture.update();\n            this.gl.framebufferTexture2D(this.target, this.stencil ? this.gl.DEPTH_STENCIL_ATTACHMENT : this.gl.DEPTH_ATTACHMENT, this.gl.TEXTURE_2D, this.depthTexture.texture, 0 /* level */);\n        } else {\n            // Render buffers\n            if (depth && !stencil) {\n                this.depthBuffer = this.gl.createRenderbuffer();\n                this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.depthBuffer);\n                this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT16, width, height);\n                this.gl.framebufferRenderbuffer(this.target, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.depthBuffer);\n            }\n\n            if (stencil && !depth) {\n                this.stencilBuffer = this.gl.createRenderbuffer();\n                this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.stencilBuffer);\n                this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.STENCIL_INDEX8, width, height);\n                this.gl.framebufferRenderbuffer(this.target, this.gl.STENCIL_ATTACHMENT, this.gl.RENDERBUFFER, this.stencilBuffer);\n            }\n\n            if (depth && stencil) {\n                this.depthStencilBuffer = this.gl.createRenderbuffer();\n                this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.depthStencilBuffer);\n                this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_STENCIL, width, height);\n                this.gl.framebufferRenderbuffer(this.target, this.gl.DEPTH_STENCIL_ATTACHMENT, this.gl.RENDERBUFFER, this.depthStencilBuffer);\n            }\n        }\n\n        this.gl.renderer.bindFramebuffer({ target: this.target });\n    }\n\n    setSize(width, height) {\n        if (this.width === width && this.height === height) return;\n\n        this.width = width;\n        this.height = height;\n        this.gl.renderer.bindFramebuffer(this);\n\n        for (let i = 0; i < this.textures.length; i++) {\n            this.textures[i].width = width;\n            this.textures[i].height = height;\n            this.textures[i].needsUpdate = true;\n            this.textures[i].update();\n            this.gl.framebufferTexture2D(this.target, this.gl.COLOR_ATTACHMENT0 + i, this.gl.TEXTURE_2D, this.textures[i].texture, 0 /* level */);\n        }\n\n        if (this.depthTexture) {\n            this.depthTexture.width = width;\n            this.depthTexture.height = height;\n            this.depthTexture.needsUpdate = true;\n            this.depthTexture.update();\n            this.gl.framebufferTexture2D(this.target, this.gl.DEPTH_ATTACHMENT, this.gl.TEXTURE_2D, this.depthTexture.texture, 0 /* level */);\n        } else {\n            if (this.depthBuffer) {\n                this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.depthBuffer);\n                this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT16, width, height);\n            }\n\n            if (this.stencilBuffer) {\n                this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.stencilBuffer);\n                this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.STENCIL_INDEX8, width, height);\n            }\n\n            if (this.depthStencilBuffer) {\n                this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.depthStencilBuffer);\n                this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_STENCIL, width, height);\n            }\n        }\n\n        this.gl.renderer.bindFramebuffer({ target: this.target });\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\n\nexport class Plane extends Geometry {\n    constructor(gl, { width = 1, height = 1, widthSegments = 1, heightSegments = 1, attributes = {} } = {}) {\n        const wSegs = widthSegments;\n        const hSegs = heightSegments;\n\n        // Determine length of arrays\n        const num = (wSegs + 1) * (hSegs + 1);\n        const numIndices = wSegs * hSegs * 6;\n\n        // Generate empty arrays once\n        const position = new Float32Array(num * 3);\n        const normal = new Float32Array(num * 3);\n        const uv = new Float32Array(num * 2);\n        const index = numIndices > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices);\n\n        Plane.buildPlane(position, normal, uv, index, width, height, 0, wSegs, hSegs);\n\n        Object.assign(attributes, {\n            position: { size: 3, data: position },\n            normal: { size: 3, data: normal },\n            uv: { size: 2, data: uv },\n            index: { data: index },\n        });\n\n        super(gl, attributes);\n    }\n\n    static buildPlane(position, normal, uv, index, width, height, depth, wSegs, hSegs, u = 0, v = 1, w = 2, uDir = 1, vDir = -1, i = 0, ii = 0) {\n        const io = i;\n        const segW = width / wSegs;\n        const segH = height / hSegs;\n\n        for (let iy = 0; iy <= hSegs; iy++) {\n            let y = iy * segH - height / 2;\n            for (let ix = 0; ix <= wSegs; ix++, i++) {\n                let x = ix * segW - width / 2;\n\n                position[i * 3 + u] = x * uDir;\n                position[i * 3 + v] = y * vDir;\n                position[i * 3 + w] = depth / 2;\n\n                normal[i * 3 + u] = 0;\n                normal[i * 3 + v] = 0;\n                normal[i * 3 + w] = depth >= 0 ? 1 : -1;\n\n                uv[i * 2] = ix / wSegs;\n                uv[i * 2 + 1] = 1 - iy / hSegs;\n\n                if (iy === hSegs || ix === wSegs) continue;\n                let a = io + ix + iy * (wSegs + 1);\n                let b = io + ix + (iy + 1) * (wSegs + 1);\n                let c = io + ix + (iy + 1) * (wSegs + 1) + 1;\n                let d = io + ix + iy * (wSegs + 1) + 1;\n\n                index[ii * 6] = a;\n                index[ii * 6 + 1] = b;\n                index[ii * 6 + 2] = d;\n                index[ii * 6 + 3] = b;\n                index[ii * 6 + 4] = c;\n                index[ii * 6 + 5] = d;\n                ii++;\n            }\n        }\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\nimport { Plane } from './Plane.js';\n\nexport class Box extends Geometry {\n    constructor(gl, { width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1, attributes = {} } = {}) {\n        const wSegs = widthSegments;\n        const hSegs = heightSegments;\n        const dSegs = depthSegments;\n\n        const num = (wSegs + 1) * (hSegs + 1) * 2 + (wSegs + 1) * (dSegs + 1) * 2 + (hSegs + 1) * (dSegs + 1) * 2;\n        const numIndices = (wSegs * hSegs * 2 + wSegs * dSegs * 2 + hSegs * dSegs * 2) * 6;\n\n        const position = new Float32Array(num * 3);\n        const normal = new Float32Array(num * 3);\n        const uv = new Float32Array(num * 2);\n        const index = num > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices);\n\n        let i = 0;\n        let ii = 0;\n\n        // left, right\n        Plane.buildPlane(position, normal, uv, index, depth, height, width, dSegs, hSegs, 2, 1, 0, -1, -1, i, ii);\n        i += (dSegs + 1) * (hSegs + 1);\n        ii += dSegs * hSegs;\n\n        Plane.buildPlane(position, normal, uv, index, depth, height, -width, dSegs, hSegs, 2, 1, 0, 1, -1, i, ii);\n        i += (dSegs + 1) * (hSegs + 1);\n        ii += dSegs * hSegs;\n\n        // top, bottom\n        Plane.buildPlane(position, normal, uv, index, width, depth, height, dSegs, wSegs, 0, 2, 1, 1, 1, i, ii);\n        i += (wSegs + 1) * (dSegs + 1);\n        ii += wSegs * dSegs;\n\n        Plane.buildPlane(position, normal, uv, index, width, depth, -height, dSegs, wSegs, 0, 2, 1, 1, -1, i, ii);\n        i += (wSegs + 1) * (dSegs + 1);\n        ii += wSegs * dSegs;\n\n        // front, back\n        Plane.buildPlane(position, normal, uv, index, width, height, -depth, wSegs, hSegs, 0, 1, 2, -1, -1, i, ii);\n        i += (wSegs + 1) * (hSegs + 1);\n        ii += wSegs * hSegs;\n\n        Plane.buildPlane(position, normal, uv, index, width, height, depth, wSegs, hSegs, 0, 1, 2, 1, -1, i, ii);\n\n        Object.assign(attributes, {\n            position: { size: 3, data: position },\n            normal: { size: 3, data: normal },\n            uv: { size: 2, data: uv },\n            index: { data: index },\n        });\n\n        super(gl, attributes);\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\nimport { Vec3 } from '../math/Vec3.js';\n\nexport class Sphere extends Geometry {\n    constructor(\n        gl,\n        {\n            radius = 0.5,\n            widthSegments = 16,\n            heightSegments = Math.ceil(widthSegments * 0.5),\n            phiStart = 0,\n            phiLength = Math.PI * 2,\n            thetaStart = 0,\n            thetaLength = Math.PI,\n            attributes = {},\n        } = {}\n    ) {\n        const wSegs = widthSegments;\n        const hSegs = heightSegments;\n        const pStart = phiStart;\n        const pLength = phiLength;\n        const tStart = thetaStart;\n        const tLength = thetaLength;\n\n        const num = (wSegs + 1) * (hSegs + 1);\n        const numIndices = wSegs * hSegs * 6;\n\n        const position = new Float32Array(num * 3);\n        const normal = new Float32Array(num * 3);\n        const uv = new Float32Array(num * 2);\n        const index = num > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices);\n\n        let i = 0;\n        let iv = 0;\n        let ii = 0;\n        let te = tStart + tLength;\n        const grid = [];\n\n        let n = new Vec3();\n\n        for (let iy = 0; iy <= hSegs; iy++) {\n            let vRow = [];\n            let v = iy / hSegs;\n            for (let ix = 0; ix <= wSegs; ix++, i++) {\n                let u = ix / wSegs;\n                let x = -radius * Math.cos(pStart + u * pLength) * Math.sin(tStart + v * tLength);\n                let y = radius * Math.cos(tStart + v * tLength);\n                let z = radius * Math.sin(pStart + u * pLength) * Math.sin(tStart + v * tLength);\n\n                position[i * 3] = x;\n                position[i * 3 + 1] = y;\n                position[i * 3 + 2] = z;\n\n                n.set(x, y, z).normalize();\n                normal[i * 3] = n.x;\n                normal[i * 3 + 1] = n.y;\n                normal[i * 3 + 2] = n.z;\n\n                uv[i * 2] = u;\n                uv[i * 2 + 1] = 1 - v;\n\n                vRow.push(iv++);\n            }\n\n            grid.push(vRow);\n        }\n\n        for (let iy = 0; iy < hSegs; iy++) {\n            for (let ix = 0; ix < wSegs; ix++) {\n                let a = grid[iy][ix + 1];\n                let b = grid[iy][ix];\n                let c = grid[iy + 1][ix];\n                let d = grid[iy + 1][ix + 1];\n\n                if (iy !== 0 || tStart > 0) {\n                    index[ii * 3] = a;\n                    index[ii * 3 + 1] = b;\n                    index[ii * 3 + 2] = d;\n                    ii++;\n                }\n                if (iy !== hSegs - 1 || te < Math.PI) {\n                    index[ii * 3] = b;\n                    index[ii * 3 + 1] = c;\n                    index[ii * 3 + 2] = d;\n                    ii++;\n                }\n            }\n        }\n\n        Object.assign(attributes, {\n            position: { size: 3, data: position },\n            normal: { size: 3, data: normal },\n            uv: { size: 2, data: uv },\n            index: { data: index },\n        });\n\n        super(gl, attributes);\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\nimport { Vec3 } from '../math/Vec3.js';\n\nexport class Cylinder extends Geometry {\n    constructor(\n        gl,\n        {\n            radiusTop = 0.5,\n            radiusBottom = 0.5,\n            height = 1,\n            radialSegments = 8,\n            heightSegments = 1,\n            openEnded = false,\n            thetaStart = 0,\n            thetaLength = Math.PI * 2,\n            attributes = {},\n        } = {}\n    ) {\n        const rSegs = radialSegments;\n        const hSegs = heightSegments;\n        const tStart = thetaStart;\n        const tLength = thetaLength;\n\n        const numCaps = openEnded ? 0 : radiusBottom && radiusTop ? 2 : 1;\n        const num = (rSegs + 1) * (hSegs + 1 + numCaps) + numCaps;\n        const numIndices = rSegs * hSegs * 6 + numCaps * rSegs * 3;\n\n        const position = new Float32Array(num * 3);\n        const normal = new Float32Array(num * 3);\n        const uv = new Float32Array(num * 2);\n        const index = num > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices);\n\n        let i = 0;\n        let ii = 0;\n        const indexArray = [];\n\n        addHeight();\n        if (!openEnded) {\n            if (radiusTop) addCap(true);\n            if (radiusBottom) addCap(false);\n        }\n\n        function addHeight() {\n            let x, y;\n            const n = new Vec3();\n            const slope = (radiusBottom - radiusTop) / height;\n\n            for (y = 0; y <= hSegs; y++) {\n                const indexRow = [];\n                const v = y / hSegs;\n\n                const r = v * (radiusBottom - radiusTop) + radiusTop;\n                for (x = 0; x <= rSegs; x++) {\n                    const u = x / rSegs;\n                    const theta = u * tLength + tStart;\n                    const sinTheta = Math.sin(theta);\n                    const cosTheta = Math.cos(theta);\n\n                    position.set([r * sinTheta, (0.5 - v) * height, r * cosTheta], i * 3);\n                    n.set(sinTheta, slope, cosTheta).normalize();\n                    normal.set([n.x, n.y, n.z], i * 3);\n                    uv.set([u, 1 - v], i * 2);\n                    indexRow.push(i++);\n                }\n                indexArray.push(indexRow);\n            }\n\n            for (x = 0; x < rSegs; x++) {\n                for (y = 0; y < hSegs; y++) {\n                    const a = indexArray[y][x];\n                    const b = indexArray[y + 1][x];\n                    const c = indexArray[y + 1][x + 1];\n                    const d = indexArray[y][x + 1];\n\n                    index.set([a, b, d, b, c, d], ii * 3);\n                    ii += 2;\n                }\n            }\n        }\n\n        function addCap(isTop) {\n            let x;\n            const r = isTop === true ? radiusTop : radiusBottom;\n            const sign = isTop === true ? 1 : -1;\n\n            const centerIndex = i;\n            position.set([0, 0.5 * height * sign, 0], i * 3);\n            normal.set([0, sign, 0], i * 3);\n            uv.set([0.5, 0.5], i * 2);\n            i++;\n\n            for (x = 0; x <= rSegs; x++) {\n                const u = x / rSegs;\n                const theta = u * tLength + tStart;\n                const cosTheta = Math.cos(theta);\n                const sinTheta = Math.sin(theta);\n\n                position.set([r * sinTheta, 0.5 * height * sign, r * cosTheta], i * 3);\n                normal.set([0, sign, 0], i * 3);\n                uv.set([cosTheta * 0.5 + 0.5, sinTheta * 0.5 * sign + 0.5], i * 2);\n                i++;\n            }\n\n            for (x = 0; x < rSegs; x++) {\n                const j = centerIndex + x + 1;\n                if (isTop) {\n                    index.set([j, j + 1, centerIndex], ii * 3);\n                } else {\n                    index.set([j + 1, j, centerIndex], ii * 3);\n                }\n                ii++;\n            }\n        }\n\n        Object.assign(attributes, {\n            position: { size: 3, data: position },\n            normal: { size: 3, data: normal },\n            uv: { size: 2, data: uv },\n            index: { data: index },\n        });\n\n        super(gl, attributes);\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\n\nexport class Triangle extends Geometry {\n    constructor(gl, { attributes = {} } = {}) {\n        Object.assign(attributes, {\n            position: { size: 2, data: new Float32Array([-1, -1, 3, -1, -1, 3]) },\n            uv: { size: 2, data: new Float32Array([0, 0, 2, 0, 0, 2]) },\n        });\n\n        super(gl, attributes);\n    }\n}\n","// https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js\n\nimport { Geometry } from '../core/Geometry.js';\nimport { Vec3 } from '../math/Vec3.js';\n\nexport class Torus extends Geometry {\n    constructor(gl, { radius = 0.5, tube = 0.2, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2, attributes = {} } = {}) {\n        const num = (radialSegments + 1) * (tubularSegments + 1);\n        const numIndices = radialSegments * tubularSegments * 6;\n\n        const vertices = new Float32Array(num * 3);\n        const normals = new Float32Array(num * 3);\n        const uvs = new Float32Array(num * 2);\n        const indices = num > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices);\n\n        const center = new Vec3();\n        const vertex = new Vec3();\n        const normal = new Vec3();\n\n        // generate vertices, normals and uvs\n        let idx = 0;\n        for (let j = 0; j <= radialSegments; j++) {\n            for (let i = 0; i <= tubularSegments; i++, idx++) {\n                const u = (i / tubularSegments) * arc;\n                const v = (j / radialSegments) * Math.PI * 2;\n\n                // vertex\n                vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u);\n                vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u);\n                vertex.z = tube * Math.sin(v);\n\n                vertices.set([vertex.x, vertex.y, vertex.z], idx * 3);\n\n                // normal\n                center.x = radius * Math.cos(u);\n                center.y = radius * Math.sin(u);\n                normal.sub(vertex, center).normalize();\n\n                normals.set([normal.x, normal.y, normal.z], idx * 3);\n\n                // uv\n                uvs.set([i / tubularSegments, j / radialSegments], idx * 2);\n            }\n        }\n\n        // generate indices\n        idx = 0;\n        for (let j = 1; j <= radialSegments; j++) {\n            for (let i = 1; i <= tubularSegments; i++, idx++) {\n                // indices\n                const a = (tubularSegments + 1) * j + i - 1;\n                const b = (tubularSegments + 1) * (j - 1) + i - 1;\n                const c = (tubularSegments + 1) * (j - 1) + i;\n                const d = (tubularSegments + 1) * j + i;\n\n                // faces\n                indices.set([a, b, d, b, c, d], idx * 6);\n            }\n        }\n\n        Object.assign(attributes, {\n            position: { size: 3, data: vertices },\n            normal: { size: 3, data: normals },\n            uv: { size: 2, data: uvs },\n            index: { data: indices },\n        });\n\n        super(gl, attributes);\n    }\n}\n","// Based from ThreeJS' OrbitControls class, rewritten using es6 with some additions and subtractions.\n// TODO: abstract event handlers so can be fed from other sources\n// TODO: make scroll zoom more accurate than just >/< zero\n// TODO: be able to pass in new camera position\n\nimport { Vec3 } from '../math/Vec3.js';\nimport { Vec2 } from '../math/Vec2.js';\n\nconst STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, DOLLY_PAN: 3 };\nconst tempVec3 = /* @__PURE__ */ new Vec3();\nconst tempVec2a = /* @__PURE__ */ new Vec2();\nconst tempVec2b = /* @__PURE__ */ new Vec2();\n\nexport function Orbit(\n    object,\n    {\n        element = document,\n        enabled = true,\n        target = new Vec3(),\n        ease = 0.25,\n        inertia = 0.85,\n        enableRotate = true,\n        rotateSpeed = 0.1,\n        autoRotate = false,\n        autoRotateSpeed = 1.0,\n        enableZoom = true,\n        zoomSpeed = 1,\n        zoomStyle = 'dolly',\n        enablePan = true,\n        panSpeed = 0.1,\n        minPolarAngle = 0,\n        maxPolarAngle = Math.PI,\n        minAzimuthAngle = -Infinity,\n        maxAzimuthAngle = Infinity,\n        minDistance = 0,\n        maxDistance = Infinity,\n    } = {}\n) {\n    this.enabled = enabled;\n    this.target = target;\n    this.zoomStyle = zoomStyle;\n\n    // Catch attempts to disable - set to 1 so has no effect\n    ease = ease || 1;\n    inertia = inertia || 0;\n\n    this.minDistance = minDistance;\n    this.maxDistance = maxDistance;\n\n    // current position in sphericalTarget coordinates\n    const sphericalDelta = { radius: 1, phi: 0, theta: 0 };\n    const sphericalTarget = { radius: 1, phi: 0, theta: 0 };\n    const spherical = { radius: 1, phi: 0, theta: 0 };\n    const panDelta = new Vec3();\n\n    // Grab initial position values\n    const offset = new Vec3();\n    offset.copy(object.position).sub(this.target);\n    spherical.radius = sphericalTarget.radius = offset.distance();\n    spherical.theta = sphericalTarget.theta = Math.atan2(offset.x, offset.z);\n    spherical.phi = sphericalTarget.phi = Math.acos(Math.min(Math.max(offset.y / sphericalTarget.radius, -1), 1));\n\n    this.offset = offset;\n\n    this.update = () => {\n        if (autoRotate) {\n            handleAutoRotate();\n        }\n\n        // apply delta\n        sphericalTarget.radius *= sphericalDelta.radius;\n        sphericalTarget.theta += sphericalDelta.theta;\n        sphericalTarget.phi += sphericalDelta.phi;\n\n        // apply boundaries\n        sphericalTarget.theta = Math.max(minAzimuthAngle, Math.min(maxAzimuthAngle, sphericalTarget.theta));\n        sphericalTarget.phi = Math.max(minPolarAngle, Math.min(maxPolarAngle, sphericalTarget.phi));\n        sphericalTarget.radius = Math.max(this.minDistance, Math.min(this.maxDistance, sphericalTarget.radius));\n\n        // ease values\n        spherical.phi += (sphericalTarget.phi - spherical.phi) * ease;\n        spherical.theta += (sphericalTarget.theta - spherical.theta) * ease;\n        spherical.radius += (sphericalTarget.radius - spherical.radius) * ease;\n\n        // apply pan to target. As offset is relative to target, it also shifts\n        this.target.add(panDelta);\n\n        // apply rotation to offset\n        let sinPhiRadius = spherical.radius * Math.sin(Math.max(0.000001, spherical.phi));\n        offset.x = sinPhiRadius * Math.sin(spherical.theta);\n        offset.y = spherical.radius * Math.cos(spherical.phi);\n        offset.z = sinPhiRadius * Math.cos(spherical.theta);\n\n        // Apply updated values to object\n        object.position.copy(this.target).add(offset);\n        object.lookAt(this.target);\n\n        // Apply inertia to values\n        sphericalDelta.theta *= inertia;\n        sphericalDelta.phi *= inertia;\n        panDelta.multiply(inertia);\n\n        // Reset scale every frame to avoid applying scale multiple times\n        sphericalDelta.radius = 1;\n    };\n\n    // Updates internals with new position\n    this.forcePosition = () => {\n        offset.copy(object.position).sub(this.target);\n        spherical.radius = sphericalTarget.radius = offset.distance();\n        spherical.theta = sphericalTarget.theta = Math.atan2(offset.x, offset.z);\n        spherical.phi = sphericalTarget.phi = Math.acos(Math.min(Math.max(offset.y / sphericalTarget.radius, -1), 1));\n        object.lookAt(this.target);\n    };\n\n    // Everything below here just updates panDelta and sphericalDelta\n    // Using those two objects' values, the orbit is calculated\n\n    const rotateStart = new Vec2();\n    const panStart = new Vec2();\n    const dollyStart = new Vec2();\n\n    let state = STATE.NONE;\n    this.mouseButtons = { ORBIT: 0, ZOOM: 1, PAN: 2 };\n\n    function getZoomScale() {\n        return Math.pow(0.95, zoomSpeed);\n    }\n\n    function panLeft(distance, m) {\n        tempVec3.set(m[0], m[1], m[2]);\n        tempVec3.multiply(-distance);\n        panDelta.add(tempVec3);\n    }\n\n    function panUp(distance, m) {\n        tempVec3.set(m[4], m[5], m[6]);\n        tempVec3.multiply(distance);\n        panDelta.add(tempVec3);\n    }\n\n    const pan = (deltaX, deltaY) => {\n        let el = element === document ? document.body : element;\n        tempVec3.copy(object.position).sub(this.target);\n        let targetDistance = tempVec3.distance();\n        targetDistance *= Math.tan((((object.fov || 45) / 2) * Math.PI) / 180.0);\n        panLeft((2 * deltaX * targetDistance) / el.clientHeight, object.matrix);\n        panUp((2 * deltaY * targetDistance) / el.clientHeight, object.matrix);\n    };\n\n    const dolly = (dollyScale) => {\n        if (this.zoomStyle === 'dolly') sphericalDelta.radius /= dollyScale;\n        else {\n            object.fov /= dollyScale;\n            if (object.type === 'orthographic') object.orthographic();\n            else object.perspective();\n        }\n    };\n\n    function handleAutoRotate() {\n        const angle = ((2 * Math.PI) / 60 / 60) * autoRotateSpeed;\n        sphericalDelta.theta -= angle;\n    }\n\n    function handleMoveRotate(x, y) {\n        tempVec2a.set(x, y);\n        tempVec2b.sub(tempVec2a, rotateStart).multiply(rotateSpeed);\n        let el = element === document ? document.body : element;\n        sphericalDelta.theta -= (2 * Math.PI * tempVec2b.x) / el.clientHeight;\n        sphericalDelta.phi -= (2 * Math.PI * tempVec2b.y) / el.clientHeight;\n        rotateStart.copy(tempVec2a);\n    }\n\n    function handleMouseMoveDolly(e) {\n        tempVec2a.set(e.clientX, e.clientY);\n        tempVec2b.sub(tempVec2a, dollyStart);\n        if (tempVec2b.y > 0) {\n            dolly(getZoomScale());\n        } else if (tempVec2b.y < 0) {\n            dolly(1 / getZoomScale());\n        }\n        dollyStart.copy(tempVec2a);\n    }\n\n    function handleMovePan(x, y) {\n        tempVec2a.set(x, y);\n        tempVec2b.sub(tempVec2a, panStart).multiply(panSpeed);\n        pan(tempVec2b.x, tempVec2b.y);\n        panStart.copy(tempVec2a);\n    }\n\n    function handleTouchStartDollyPan(e) {\n        if (enableZoom) {\n            let dx = e.touches[0].pageX - e.touches[1].pageX;\n            let dy = e.touches[0].pageY - e.touches[1].pageY;\n            let distance = Math.sqrt(dx * dx + dy * dy);\n            dollyStart.set(0, distance);\n        }\n\n        if (enablePan) {\n            let x = 0.5 * (e.touches[0].pageX + e.touches[1].pageX);\n            let y = 0.5 * (e.touches[0].pageY + e.touches[1].pageY);\n            panStart.set(x, y);\n        }\n    }\n\n    function handleTouchMoveDollyPan(e) {\n        if (enableZoom) {\n            let dx = e.touches[0].pageX - e.touches[1].pageX;\n            let dy = e.touches[0].pageY - e.touches[1].pageY;\n            let distance = Math.sqrt(dx * dx + dy * dy);\n            tempVec2a.set(0, distance);\n            tempVec2b.set(0, Math.pow(tempVec2a.y / dollyStart.y, zoomSpeed));\n            dolly(tempVec2b.y);\n            dollyStart.copy(tempVec2a);\n        }\n\n        if (enablePan) {\n            let x = 0.5 * (e.touches[0].pageX + e.touches[1].pageX);\n            let y = 0.5 * (e.touches[0].pageY + e.touches[1].pageY);\n            handleMovePan(x, y);\n        }\n    }\n\n    const onMouseDown = (e) => {\n        if (!this.enabled) return;\n\n        switch (e.button) {\n            case this.mouseButtons.ORBIT:\n                if (enableRotate === false) return;\n                rotateStart.set(e.clientX, e.clientY);\n                state = STATE.ROTATE;\n                break;\n            case this.mouseButtons.ZOOM:\n                if (enableZoom === false) return;\n                dollyStart.set(e.clientX, e.clientY);\n                state = STATE.DOLLY;\n                break;\n            case this.mouseButtons.PAN:\n                if (enablePan === false) return;\n                panStart.set(e.clientX, e.clientY);\n                state = STATE.PAN;\n                break;\n        }\n\n        if (state !== STATE.NONE) {\n            window.addEventListener('mousemove', onMouseMove, false);\n            window.addEventListener('mouseup', onMouseUp, false);\n        }\n    };\n\n    const onMouseMove = (e) => {\n        if (!this.enabled) return;\n\n        switch (state) {\n            case STATE.ROTATE:\n                if (enableRotate === false) return;\n                handleMoveRotate(e.clientX, e.clientY);\n                break;\n            case STATE.DOLLY:\n                if (enableZoom === false) return;\n                handleMouseMoveDolly(e);\n                break;\n            case STATE.PAN:\n                if (enablePan === false) return;\n                handleMovePan(e.clientX, e.clientY);\n                break;\n        }\n    };\n\n    const onMouseUp = () => {\n        window.removeEventListener('mousemove', onMouseMove, false);\n        window.removeEventListener('mouseup', onMouseUp, false);\n        state = STATE.NONE;\n    };\n\n    const onMouseWheel = (e) => {\n        if (!this.enabled || !enableZoom || (state !== STATE.NONE && state !== STATE.ROTATE)) return;\n        e.stopPropagation();\n        e.preventDefault();\n\n        if (e.deltaY < 0) {\n            dolly(1 / getZoomScale());\n        } else if (e.deltaY > 0) {\n            dolly(getZoomScale());\n        }\n    };\n\n    const onTouchStart = (e) => {\n        if (!this.enabled) return;\n        e.preventDefault();\n\n        switch (e.touches.length) {\n            case 1:\n                if (enableRotate === false) return;\n                rotateStart.set(e.touches[0].pageX, e.touches[0].pageY);\n                state = STATE.ROTATE;\n                break;\n            case 2:\n                if (enableZoom === false && enablePan === false) return;\n                handleTouchStartDollyPan(e);\n                state = STATE.DOLLY_PAN;\n                break;\n            default:\n                state = STATE.NONE;\n        }\n    };\n\n    const onTouchMove = (e) => {\n        if (!this.enabled) return;\n        e.preventDefault();\n        e.stopPropagation();\n\n        switch (e.touches.length) {\n            case 1:\n                if (enableRotate === false) return;\n                handleMoveRotate(e.touches[0].pageX, e.touches[0].pageY);\n                break;\n            case 2:\n                if (enableZoom === false && enablePan === false) return;\n                handleTouchMoveDollyPan(e);\n                break;\n            default:\n                state = STATE.NONE;\n        }\n    };\n\n    const onTouchEnd = () => {\n        if (!this.enabled) return;\n        state = STATE.NONE;\n    };\n\n    const onContextMenu = (e) => {\n        if (!this.enabled) return;\n        e.preventDefault();\n    };\n\n    function addHandlers() {\n        element.addEventListener('contextmenu', onContextMenu, false);\n        element.addEventListener('mousedown', onMouseDown, false);\n        element.addEventListener('wheel', onMouseWheel, { passive: false });\n        element.addEventListener('touchstart', onTouchStart, { passive: false });\n        element.addEventListener('touchend', onTouchEnd, false);\n        element.addEventListener('touchmove', onTouchMove, { passive: false });\n    }\n\n    this.remove = function () {\n        element.removeEventListener('contextmenu', onContextMenu);\n        element.removeEventListener('mousedown', onMouseDown);\n        element.removeEventListener('wheel', onMouseWheel);\n        element.removeEventListener('touchstart', onTouchStart);\n        element.removeEventListener('touchend', onTouchEnd);\n        element.removeEventListener('touchmove', onTouchMove);\n        window.removeEventListener('mousemove', onMouseMove);\n        window.removeEventListener('mouseup', onMouseUp);\n    };\n\n    addHandlers();\n}\n","// TODO: barycentric code shouldn't be here, but where?\n// TODO: SphereCast?\n\nimport { Vec2 } from '../math/Vec2.js';\nimport { Vec3 } from '../math/Vec3.js';\nimport { Mat4 } from '../math/Mat4.js';\n\nconst tempVec2a = /* @__PURE__ */ new Vec2();\nconst tempVec2b = /* @__PURE__ */ new Vec2();\nconst tempVec2c = /* @__PURE__ */ new Vec2();\n\nconst tempVec3a = /* @__PURE__ */ new Vec3();\nconst tempVec3b = /* @__PURE__ */ new Vec3();\nconst tempVec3c = /* @__PURE__ */ new Vec3();\nconst tempVec3d = /* @__PURE__ */ new Vec3();\nconst tempVec3e = /* @__PURE__ */ new Vec3();\nconst tempVec3f = /* @__PURE__ */ new Vec3();\nconst tempVec3g = /* @__PURE__ */ new Vec3();\nconst tempVec3h = /* @__PURE__ */ new Vec3();\nconst tempVec3i = /* @__PURE__ */ new Vec3();\nconst tempVec3j = /* @__PURE__ */ new Vec3();\nconst tempVec3k = /* @__PURE__ */ new Vec3();\n\nconst tempMat4 = /* @__PURE__ */ new Mat4();\n\nexport class Raycast {\n    constructor() {\n        this.origin = new Vec3();\n        this.direction = new Vec3();\n    }\n\n    // Set ray from mouse unprojection\n    castMouse(camera, mouse = [0, 0]) {\n        if (camera.type === 'orthographic') {\n            // Set origin\n            // Since camera is orthographic, origin is not the camera position\n            const { left, right, bottom, top, zoom } = camera;\n            const x = left / zoom + ((right - left) / zoom) * (mouse[0] * 0.5 + 0.5);\n            const y = bottom / zoom + ((top - bottom) / zoom) * (mouse[1] * 0.5 + 0.5);\n            this.origin.set(x, y, 0);\n            this.origin.applyMatrix4(camera.worldMatrix);\n\n            // Set direction\n            // https://community.khronos.org/t/get-direction-from-transformation-matrix-or-quat/65502/2\n            this.direction.x = -camera.worldMatrix[8];\n            this.direction.y = -camera.worldMatrix[9];\n            this.direction.z = -camera.worldMatrix[10];\n        } else {\n            // Set origin\n            camera.worldMatrix.getTranslation(this.origin);\n\n            // Set direction\n            this.direction.set(mouse[0], mouse[1], 0.5);\n            camera.unproject(this.direction);\n            this.direction.sub(this.origin).normalize();\n        }\n    }\n\n    intersectBounds(meshes, { maxDistance, output = [] } = {}) {\n        if (!Array.isArray(meshes)) meshes = [meshes];\n\n        const invWorldMat4 = tempMat4;\n        const origin = tempVec3a;\n        const direction = tempVec3b;\n\n        const hits = output;\n        hits.length = 0;\n\n        meshes.forEach((mesh) => {\n            // Create bounds\n            if (!mesh.geometry.bounds || mesh.geometry.bounds.radius === Infinity) mesh.geometry.computeBoundingSphere();\n            const bounds = mesh.geometry.bounds;\n            invWorldMat4.inverse(mesh.worldMatrix);\n\n            // Get max distance locally\n            let localMaxDistance;\n            if (maxDistance) {\n                direction.copy(this.direction).scaleRotateMatrix4(invWorldMat4);\n                localMaxDistance = maxDistance * direction.len();\n            }\n\n            // Take world space ray and make it object space to align with bounding box\n            origin.copy(this.origin).applyMatrix4(invWorldMat4);\n            direction.copy(this.direction).transformDirection(invWorldMat4);\n\n            // Break out early if bounds too far away from origin\n            if (maxDistance) {\n                if (origin.distance(bounds.center) - bounds.radius > localMaxDistance) return;\n            }\n\n            let localDistance = 0;\n\n            // Check origin isn't inside bounds before testing intersection\n            if (mesh.geometry.raycast === 'sphere') {\n                if (origin.distance(bounds.center) > bounds.radius) {\n                    localDistance = this.intersectSphere(bounds, origin, direction);\n                    if (!localDistance) return;\n                }\n            } else {\n                if (\n                    origin.x < bounds.min.x ||\n                    origin.x > bounds.max.x ||\n                    origin.y < bounds.min.y ||\n                    origin.y > bounds.max.y ||\n                    origin.z < bounds.min.z ||\n                    origin.z > bounds.max.z\n                ) {\n                    localDistance = this.intersectBox(bounds, origin, direction);\n                    if (!localDistance) return;\n                }\n            }\n\n            if (maxDistance && localDistance > localMaxDistance) return;\n\n            // Create object on mesh to avoid generating lots of objects\n            if (!mesh.hit) mesh.hit = { localPoint: new Vec3(), point: new Vec3() };\n\n            mesh.hit.localPoint.copy(direction).multiply(localDistance).add(origin);\n            mesh.hit.point.copy(mesh.hit.localPoint).applyMatrix4(mesh.worldMatrix);\n            mesh.hit.distance = mesh.hit.point.distance(this.origin);\n\n            hits.push(mesh);\n        });\n\n        hits.sort((a, b) => a.hit.distance - b.hit.distance);\n        return hits;\n    }\n\n    intersectMeshes(meshes, { cullFace = true, maxDistance, includeUV = true, includeNormal = true, output = [] } = {}) {\n        // Test bounds first before testing geometry\n        const hits = this.intersectBounds(meshes, { maxDistance, output });\n        if (!hits.length) return hits;\n\n        const invWorldMat4 = tempMat4;\n        const origin = tempVec3a;\n        const direction = tempVec3b;\n        const a = tempVec3c;\n        const b = tempVec3d;\n        const c = tempVec3e;\n        const closestFaceNormal = tempVec3f;\n        const faceNormal = tempVec3g;\n        const barycoord = tempVec3h;\n        const uvA = tempVec2a;\n        const uvB = tempVec2b;\n        const uvC = tempVec2c;\n\n        for (let i = hits.length - 1; i >= 0; i--) {\n            const mesh = hits[i];\n            invWorldMat4.inverse(mesh.worldMatrix);\n\n            // Get max distance locally\n            let localMaxDistance;\n            if (maxDistance) {\n                direction.copy(this.direction).scaleRotateMatrix4(invWorldMat4);\n                localMaxDistance = maxDistance * direction.len();\n            }\n\n            // Take world space ray and make it object space to align with bounding box\n            origin.copy(this.origin).applyMatrix4(invWorldMat4);\n            direction.copy(this.direction).transformDirection(invWorldMat4);\n\n            let localDistance = 0;\n            let closestA, closestB, closestC;\n\n            const geometry = mesh.geometry;\n            const attributes = geometry.attributes;\n            const index = attributes.index;\n            const position = attributes.position;\n\n            const start = Math.max(0, geometry.drawRange.start);\n            const end = Math.min(index ? index.count : position.count, geometry.drawRange.start + geometry.drawRange.count);\n            // Data loaded shouldn't haave stride, only buffers\n            // const stride = position.stride ? position.stride / position.data.BYTES_PER_ELEMENT : position.size;\n            const stride = position.size;\n\n            for (let j = start; j < end; j += 3) {\n                // Position attribute indices for each triangle\n                const ai = index ? index.data[j] : j;\n                const bi = index ? index.data[j + 1] : j + 1;\n                const ci = index ? index.data[j + 2] : j + 2;\n\n                a.fromArray(position.data, ai * stride);\n                b.fromArray(position.data, bi * stride);\n                c.fromArray(position.data, ci * stride);\n\n                const distance = this.intersectTriangle(a, b, c, cullFace, origin, direction, faceNormal);\n                if (!distance) continue;\n\n                // Too far away\n                if (maxDistance && distance > localMaxDistance) continue;\n\n                if (!localDistance || distance < localDistance) {\n                    localDistance = distance;\n                    closestA = ai;\n                    closestB = bi;\n                    closestC = ci;\n                    closestFaceNormal.copy(faceNormal);\n                }\n            }\n\n            if (!localDistance) hits.splice(i, 1);\n\n            // Update hit values from bounds-test\n            mesh.hit.localPoint.copy(direction).multiply(localDistance).add(origin);\n            mesh.hit.point.copy(mesh.hit.localPoint).applyMatrix4(mesh.worldMatrix);\n            mesh.hit.distance = mesh.hit.point.distance(this.origin);\n\n            // Add unique hit objects on mesh to avoid generating lots of objects\n            if (!mesh.hit.faceNormal) {\n                mesh.hit.localFaceNormal = new Vec3();\n                mesh.hit.faceNormal = new Vec3();\n                mesh.hit.uv = new Vec2();\n                mesh.hit.localNormal = new Vec3();\n                mesh.hit.normal = new Vec3();\n            }\n\n            // Add face normal data which is already computed\n            mesh.hit.localFaceNormal.copy(closestFaceNormal);\n            mesh.hit.faceNormal.copy(mesh.hit.localFaceNormal).transformDirection(mesh.worldMatrix);\n\n            // Optional data, opt out to optimise a bit if necessary\n            if (includeUV || includeNormal) {\n                // Calculate barycoords to find uv values at hit point\n                a.fromArray(position.data, closestA * 3);\n                b.fromArray(position.data, closestB * 3);\n                c.fromArray(position.data, closestC * 3);\n                this.getBarycoord(mesh.hit.localPoint, a, b, c, barycoord);\n            }\n\n            if (includeUV && attributes.uv) {\n                uvA.fromArray(attributes.uv.data, closestA * 2);\n                uvB.fromArray(attributes.uv.data, closestB * 2);\n                uvC.fromArray(attributes.uv.data, closestC * 2);\n                mesh.hit.uv.set(\n                    uvA.x * barycoord.x + uvB.x * barycoord.y + uvC.x * barycoord.z,\n                    uvA.y * barycoord.x + uvB.y * barycoord.y + uvC.y * barycoord.z\n                );\n            }\n\n            if (includeNormal && attributes.normal) {\n                a.fromArray(attributes.normal.data, closestA * 3);\n                b.fromArray(attributes.normal.data, closestB * 3);\n                c.fromArray(attributes.normal.data, closestC * 3);\n                mesh.hit.localNormal.set(\n                    a.x * barycoord.x + b.x * barycoord.y + c.x * barycoord.z,\n                    a.y * barycoord.x + b.y * barycoord.y + c.y * barycoord.z,\n                    a.z * barycoord.x + b.z * barycoord.y + c.z * barycoord.z\n                );\n\n                mesh.hit.normal.copy(mesh.hit.localNormal).transformDirection(mesh.worldMatrix);\n            }\n        }\n\n        hits.sort((a, b) => a.hit.distance - b.hit.distance);\n        return hits;\n    }\n\n    intersectPlane(plane, origin = this.origin, direction = this.direction) {\n        const xminp = tempVec3a;\n        xminp.sub(plane.origin, origin);\n\n        const a = xminp.dot(plane.normal);\n        const b = direction.dot(plane.normal);\n        // Assuming we don't want to count a ray parallel to the plane as intersecting\n        if (b == 0) return 0;\n        const delta = a / b;\n        if (delta <= 0) return 0;\n        return origin.add(direction.scale(delta));\n    }\n\n    intersectSphere(sphere, origin = this.origin, direction = this.direction) {\n        const ray = tempVec3c;\n        ray.sub(sphere.center, origin);\n        const tca = ray.dot(direction);\n        const d2 = ray.dot(ray) - tca * tca;\n        const radius2 = sphere.radius * sphere.radius;\n        if (d2 > radius2) return 0;\n        const thc = Math.sqrt(radius2 - d2);\n        const t0 = tca - thc;\n        const t1 = tca + thc;\n        if (t0 < 0 && t1 < 0) return 0;\n        if (t0 < 0) return t1;\n        return t0;\n    }\n\n    // Ray AABB - Ray Axis aligned bounding box testing\n    intersectBox(box, origin = this.origin, direction = this.direction) {\n        let tmin, tmax, tYmin, tYmax, tZmin, tZmax;\n        const invdirx = 1 / direction.x;\n        const invdiry = 1 / direction.y;\n        const invdirz = 1 / direction.z;\n        const min = box.min;\n        const max = box.max;\n        tmin = ((invdirx >= 0 ? min.x : max.x) - origin.x) * invdirx;\n        tmax = ((invdirx >= 0 ? max.x : min.x) - origin.x) * invdirx;\n        tYmin = ((invdiry >= 0 ? min.y : max.y) - origin.y) * invdiry;\n        tYmax = ((invdiry >= 0 ? max.y : min.y) - origin.y) * invdiry;\n        if (tmin > tYmax || tYmin > tmax) return 0;\n        if (tYmin > tmin) tmin = tYmin;\n        if (tYmax < tmax) tmax = tYmax;\n        tZmin = ((invdirz >= 0 ? min.z : max.z) - origin.z) * invdirz;\n        tZmax = ((invdirz >= 0 ? max.z : min.z) - origin.z) * invdirz;\n        if (tmin > tZmax || tZmin > tmax) return 0;\n        if (tZmin > tmin) tmin = tZmin;\n        if (tZmax < tmax) tmax = tZmax;\n        if (tmax < 0) return 0;\n        return tmin >= 0 ? tmin : tmax;\n    }\n\n    intersectTriangle(a, b, c, backfaceCulling = true, origin = this.origin, direction = this.direction, normal = tempVec3g) {\n        // from https://github.com/mrdoob/three.js/blob/master/src/math/Ray.js\n        // which is from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n        const edge1 = tempVec3h;\n        const edge2 = tempVec3i;\n        const diff = tempVec3j;\n        edge1.sub(b, a);\n        edge2.sub(c, a);\n        normal.cross(edge1, edge2);\n        let DdN = direction.dot(normal);\n        if (!DdN) return 0;\n        let sign;\n        if (DdN > 0) {\n            if (backfaceCulling) return 0;\n            sign = 1;\n        } else {\n            sign = -1;\n            DdN = -DdN;\n        }\n        diff.sub(origin, a);\n        let DdQxE2 = sign * direction.dot(edge2.cross(diff, edge2));\n        if (DdQxE2 < 0) return 0;\n        let DdE1xQ = sign * direction.dot(edge1.cross(diff));\n        if (DdE1xQ < 0) return 0;\n        if (DdQxE2 + DdE1xQ > DdN) return 0;\n        let QdN = -sign * diff.dot(normal);\n        if (QdN < 0) return 0;\n        return QdN / DdN;\n    }\n\n    getBarycoord(point, a, b, c, target = tempVec3h) {\n        // From https://github.com/mrdoob/three.js/blob/master/src/math/Triangle.js\n        // static/instance method to calculate barycentric coordinates\n        // based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n        const v0 = tempVec3i;\n        const v1 = tempVec3j;\n        const v2 = tempVec3k;\n        v0.sub(c, a);\n        v1.sub(b, a);\n        v2.sub(point, a);\n        const dot00 = v0.dot(v0);\n        const dot01 = v0.dot(v1);\n        const dot02 = v0.dot(v2);\n        const dot11 = v1.dot(v1);\n        const dot12 = v1.dot(v2);\n        const denom = dot00 * dot11 - dot01 * dot01;\n        if (denom === 0) return target.set(-2, -1, -1);\n        const invDenom = 1 / denom;\n        const u = (dot11 * dot02 - dot01 * dot12) * invDenom;\n        const v = (dot00 * dot12 - dot01 * dot02) * invDenom;\n        return target.set(1 - u - v, v, u);\n    }\n}\n","import { Vec3 } from '../math/Vec3.js';\n\nconst CATMULLROM = 'catmullrom';\nconst CUBICBEZIER = 'cubicbezier';\nconst QUADRATICBEZIER = 'quadraticbezier';\n\n// temp\nconst _a0 = /* @__PURE__ */ new Vec3(),\n    _a1 = /* @__PURE__ */ new Vec3(),\n    _a2 = /* @__PURE__ */ new Vec3(),\n    _a3 = /* @__PURE__ */ new Vec3();\n\n/**\n * Get the control points of cubic bezier curve.\n * @param {*} i\n * @param {*} a\n * @param {*} b\n */\nfunction getCtrlPoint(points, i, a = 0.168, b = 0.168) {\n    if (i < 1) {\n        _a0.sub(points[1], points[0]).scale(a).add(points[0]);\n    } else {\n        _a0.sub(points[i + 1], points[i - 1])\n            .scale(a)\n            .add(points[i]);\n    }\n    if (i > points.length - 3) {\n        const last = points.length - 1;\n        _a1.sub(points[last - 1], points[last])\n            .scale(b)\n            .add(points[last]);\n    } else {\n        _a1.sub(points[i], points[i + 2])\n            .scale(b)\n            .add(points[i + 1]);\n    }\n    return [_a0.clone(), _a1.clone()];\n}\n\nfunction getQuadraticBezierPoint(t, p0, c0, p1) {\n    const k = 1 - t;\n    _a0.copy(p0).scale(k ** 2);\n    _a1.copy(c0).scale(2 * k * t);\n    _a2.copy(p1).scale(t ** 2);\n    const ret = new Vec3();\n    ret.add(_a0, _a1).add(_a2);\n    return ret;\n}\n\nfunction getCubicBezierPoint(t, p0, c0, c1, p1) {\n    const k = 1 - t;\n    _a0.copy(p0).scale(k ** 3);\n    _a1.copy(c0).scale(3 * k ** 2 * t);\n    _a2.copy(c1).scale(3 * k * t ** 2);\n    _a3.copy(p1).scale(t ** 3);\n    const ret = new Vec3();\n    ret.add(_a0, _a1).add(_a2).add(_a3);\n    return ret;\n}\n\nexport class Curve {\n    constructor({ points = [new Vec3(0, 0, 0), new Vec3(0, 1, 0), new Vec3(1, 1, 0), new Vec3(1, 0, 0)], divisions = 12, type = CATMULLROM } = {}) {\n        this.points = points;\n        this.divisions = divisions;\n        this.type = type;\n    }\n\n    _getQuadraticBezierPoints(divisions = this.divisions) {\n        const points = [];\n        const count = this.points.length;\n\n        if (count < 3) {\n            console.warn('Not enough points provided.');\n            return [];\n        }\n\n        const p0 = this.points[0];\n        let c0 = this.points[1],\n            p1 = this.points[2];\n\n        for (let i = 0; i <= divisions; i++) {\n            const p = getQuadraticBezierPoint(i / divisions, p0, c0, p1);\n            points.push(p);\n        }\n\n        let offset = 3;\n        while (count - offset > 0) {\n            p0.copy(p1);\n            c0 = p1.scale(2).sub(c0);\n            p1 = this.points[offset];\n            for (let i = 1; i <= divisions; i++) {\n                const p = getQuadraticBezierPoint(i / divisions, p0, c0, p1);\n                points.push(p);\n            }\n            offset++;\n        }\n\n        return points;\n    }\n\n    _getCubicBezierPoints(divisions = this.divisions) {\n        const points = [];\n        const count = this.points.length;\n\n        if (count < 4) {\n            console.warn('Not enough points provided.');\n            return [];\n        }\n\n        let p0 = this.points[0],\n            c0 = this.points[1],\n            c1 = this.points[2],\n            p1 = this.points[3];\n\n        for (let i = 0; i <= divisions; i++) {\n            const p = getCubicBezierPoint(i / divisions, p0, c0, c1, p1);\n            points.push(p);\n        }\n\n        let offset = 4;\n        while (count - offset > 1) {\n            p0.copy(p1);\n            c0 = p1.scale(2).sub(c1);\n            c1 = this.points[offset];\n            p1 = this.points[offset + 1];\n            for (let i = 1; i <= divisions; i++) {\n                const p = getCubicBezierPoint(i / divisions, p0, c0, c1, p1);\n                points.push(p);\n            }\n            offset += 2;\n        }\n\n        return points;\n    }\n\n    _getCatmullRomPoints(divisions = this.divisions, a = 0.168, b = 0.168) {\n        const points = [];\n        const count = this.points.length;\n\n        if (count <= 2) {\n            return this.points;\n        }\n\n        let p0;\n        this.points.forEach((p, i) => {\n            if (i === 0) {\n                p0 = p;\n            } else {\n                const [c0, c1] = getCtrlPoint(this.points, i - 1, a, b);\n                const c = new Curve({\n                    points: [p0, c0, c1, p],\n                    type: CUBICBEZIER,\n                });\n                points.pop();\n                points.push(...c.getPoints(divisions));\n                p0 = p;\n            }\n        });\n\n        return points;\n    }\n\n    getPoints(divisions = this.divisions, a = 0.168, b = 0.168) {\n        const type = this.type;\n\n        if (type === QUADRATICBEZIER) {\n            return this._getQuadraticBezierPoints(divisions);\n        }\n\n        if (type === CUBICBEZIER) {\n            return this._getCubicBezierPoints(divisions);\n        }\n\n        if (type === CATMULLROM) {\n            return this._getCatmullRomPoints(divisions, a, b);\n        }\n\n        return this.points;\n    }\n}\n\nCurve.CATMULLROM = CATMULLROM;\nCurve.CUBICBEZIER = CUBICBEZIER;\nCurve.QUADRATICBEZIER = QUADRATICBEZIER;\n","import BaseSegment from './BaseSegment.js';\nimport { Vec3 } from '../../math/Vec3.js';\nimport { T_VALUES, C_VALUES } from './utils.js';\n\nconst tempVec3 = /* @__PURE__ */ new Vec3();\n\nfunction cubicBezier(t, p0, p1, p2, p3) {\n    const k = 1 - t;\n    // prettier-ignore\n    return (\n        (k * k * k * p0) +\n        (3 * k * k * t * p1) +\n        (3 * k * t * t * p2) +\n        (t * t * t * p3)\n    );\n}\n\nfunction cubicBezierDeriv(t, p0, p1, p2, p3) {\n    const k = 1 - t;\n    // prettier-ignore\n    return (\n        (3 * k * k * (p1 - p0)) +\n        (6 * k * t * (p2 - p1)) +\n        (3 * t * t * (p3 - p2))\n    );\n}\n\nexport default class CubicBezierSegment extends BaseSegment {\n    constructor(p0, p1, p2, p3, tiltStart = 0, tiltEnd = 0) {\n        super();\n        this.p0 = p0;\n        this.p1 = p1;\n        this.p2 = p2;\n        this.p3 = p3;\n\n        this.tiltStart = tiltStart;\n        this.tiltEnd = tiltEnd;\n\n        this._len = -1;\n    }\n\n    /**\n     * Updates the segment length. You must call this method every time you change the curve's control points.\n     */\n    updateLength() {\n        // from https://github.com/Pomax/bezierjs/blob/d19695f3cc3ce383cf38ce4643f467deca7edb92/src/utils.js#L265\n        const z = 0.5;\n        const len = T_VALUES.length;\n\n        let sum = 0;\n        for (let i = 0, t; i < len; i++) {\n            t = z * T_VALUES[i] + z;\n            sum += C_VALUES[i] * this.getDerivativeAt(t, tempVec3).len();\n        }\n\n        this._len = z * sum;\n    }\n\n    /**\n     * Get point at relative position in curve according to segment length.\n     * @param {number} t Distance at time t in range [0 .. 1]\n     * @param {Vec3} out Optional Vec3 to output\n     * @returns {Vec3} Point at relative position\n     */\n    getPointAt(t, out = new Vec3()) {\n        out.x = cubicBezier(t, this.p0.x, this.p1.x, this.p2.x, this.p3.x);\n        out.y = cubicBezier(t, this.p0.y, this.p1.y, this.p2.y, this.p3.y);\n        out.z = cubicBezier(t, this.p0.z, this.p1.z, this.p2.z, this.p3.z);\n        return out;\n    }\n\n    getDerivativeAt(t, out = new Vec3()) {\n        out.x = cubicBezierDeriv(t, this.p0.x, this.p1.x, this.p2.x, this.p3.x);\n        out.y = cubicBezierDeriv(t, this.p0.y, this.p1.y, this.p2.y, this.p3.y);\n        out.z = cubicBezierDeriv(t, this.p0.z, this.p1.z, this.p2.z, this.p3.z);\n        return out;\n    }\n\n    /**\n     * Returns a unit vector tangent at t\n     * @param {number} t Distance at time t in range [0 .. 1]\n     * @param {Vec3} out Optional Vec3 to output\n     * @returns {Vec3} A unit vector\n     */\n    getTangentAt(t, out = new Vec3()) {\n        return this.getDerivativeAt(t, out).normalize();\n    }\n\n    lastPoint() {\n        return this.p3;\n    }\n}\n","import BaseSegment from './BaseSegment.js';\nimport { Vec3 } from '../../math/Vec3.js';\nimport { T_VALUES, C_VALUES } from './utils.js';\n\nconst tempVec3 = /* @__PURE__ */ new Vec3();\n\nfunction quadraticBezier(t, p0, p1, p2) {\n    const k = 1 - t;\n    return k * k * p0 + 2 * k * t * p1 + t * t * p2;\n}\n\nfunction quadraticBezierDeriv(t, p0, p1, p2) {\n    const k = 1 - t;\n    return 2 * k * (p1 - p0) + 2 * t * (p2 - p1);\n}\n\nexport default class QuadraticBezierSegment extends BaseSegment {\n    constructor(p0, p1, p2, tiltStart = 0, tiltEnd = 0) {\n        super();\n        this.p0 = p0;\n        this.p1 = p1;\n        this.p2 = p2;\n\n        this.tiltStart = tiltStart;\n        this.tiltEnd = tiltEnd;\n\n        this._len = -1;\n    }\n\n    /**\n     * Updates the segment length. You must call this method every time you change the curve's control points.\n     */\n    updateLength() {\n        // from https://github.com/Pomax/bezierjs/blob/d19695f3cc3ce383cf38ce4643f467deca7edb92/src/utils.js#L265\n        const z = 0.5;\n        const len = T_VALUES.length;\n\n        let sum = 0;\n        for (let i = 0, t; i < len; i++) {\n            t = z * T_VALUES[i] + z;\n            sum += C_VALUES[i] * this.getDerivativeAt(t, tempVec3).len();\n        }\n\n        this._len = z * sum;\n    }\n\n    /**\n     * Get point at relative position in curve according to segment length.\n     * @param {number} t Distance at time t in range [0 .. 1]\n     * @param {Vec3} out Optional Vec3 to output\n     * @returns {Vec3} Point at relative position\n     */\n    getPointAt(t, out = new Vec3()) {\n        out.x = quadraticBezier(t, this.p0.x, this.p1.x, this.p2.x);\n        out.y = quadraticBezier(t, this.p0.y, this.p1.y, this.p2.y);\n        out.z = quadraticBezier(t, this.p0.z, this.p1.z, this.p2.z);\n        return out;\n    }\n\n    getDerivativeAt(t, out = new Vec3()) {\n        out.x = quadraticBezierDeriv(t, this.p0.x, this.p1.x, this.p2.x);\n        out.y = quadraticBezierDeriv(t, this.p0.y, this.p1.y, this.p2.y);\n        out.z = quadraticBezierDeriv(t, this.p0.z, this.p1.z, this.p2.z);\n        return out;\n    }\n\n    /**\n     * Returns a unit vector tangent at t\n     * @param {number} t Distance at time t in range [0 .. 1]\n     * @param {Vec3} out Optional Vec3 to output\n     * @returns {Vec3} A unit vector\n     */\n    getTangentAt(t, out = new Vec3()) {\n        return this.getDerivativeAt(t, out).normalize();\n    }\n\n    lastPoint() {\n        return this.p2;\n    }\n}\n","import BaseSegment from './BaseSegment.js';\nimport { Vec3 } from '../../math/Vec3.js';\nimport { lerp as lerp3 } from '../../math/functions/Vec3Func.js';\n\nconst tempVec3 = /* @__PURE__ */ new Vec3();\n\nexport default class LineSegment extends BaseSegment {\n    constructor(p0, p1, tiltStart = 0, tiltEnd = 0) {\n        super();\n        this.p0 = p0;\n        this.p1 = p1;\n\n        this.tiltStart = tiltStart;\n        this.tiltEnd = tiltEnd;\n\n        this._len = -1;\n    }\n\n    /**\n     * Updates the segment length. You must call this method every time you change the curve's control points.\n     */\n    updateLength() {\n        this._len = tempVec3.sub(this.p1, this.p0).len();\n    }\n\n    /**\n     * Get point at relative position in curve according to segment length.\n     * @param {number} t Distance at time t in range [0 .. 1]\n     * @param {Vec3} out Optional Vec3 to output\n     * @returns {Vec3} Point at relative position\n     */\n    getPointAt(t, out = new Vec3()) {\n        lerp3(out, this.p0, this.p1, t);\n        return out;\n    }\n\n    /**\n     * Returns a unit vector tangent at t\n     * @param {number} t Distance at time t in range [0 .. 1]\n     * @param {Vec3} out Optional Vec3 to output\n     * @returns {Vec3} A unit vector\n     */\n    getTangentAt(t, out = new Vec3()) {\n        return out.sub(this.p1, this.p0).normalize();\n    }\n\n    lastPoint() {\n        return this.p1;\n    }\n}\n","import { Vec3 } from '../../math/Vec3.js';\nimport { Mat4 } from '../../math/Mat4.js';\nimport CubicBezierSegment from './CubicBezierSegment.js';\nimport QuadraticBezierSegment from './QuadraticBezierSegment.js';\nimport LineSegment from './LineSegment.js';\nimport { clamp, toDegrees, toRadian, mat4fromRotationSinCos, rotateNormalBinormal } from './utils.js';\n\nconst tempVec3 = /* @__PURE__ */ new Vec3();\nconst tempMat4 = /* @__PURE__ */ new Mat4();\n\nfunction throwIfNullProperty(property, message) {\n    if (this[property] == null) throw new Error(message);\n}\n\nexport class Path {\n    constructor() {\n        this._segments = [];\n        this._lengthOffsets = null;\n        this._totalLength = -1;\n        this._lastPoint = null;\n        this._lastTilt = 0;\n\n        this._assertLastPoint = throwIfNullProperty.bind(this, '_lastPoint', 'Can`t get previous point of curve. Did you forget moveTo command?');\n\n        this.tiltFunction = null;\n    }\n\n    moveTo(p, tilt = 0) {\n        this._totalLength = -1;\n        this._lastPoint = p;\n        this._lastTilt = tilt;\n    }\n\n    bezierCurveTo(cp1, cp2, p, tilt = 0) {\n        this._assertLastPoint();\n        const seg = new CubicBezierSegment(this._lastPoint, cp1, cp2, p, this._lastTilt, tilt);\n        this.addSegment(seg);\n        return this;\n    }\n\n    quadraticCurveTo(cp, p, tilt = 0) {\n        this._assertLastPoint();\n        const seg = new QuadraticBezierSegment(this._lastPoint, cp, p, this._lastTilt, tilt);\n        this.addSegment(seg);\n        return this;\n    }\n\n    lineTo(p, tilt = 0) {\n        this._assertLastPoint();\n        const seg = new LineSegment(this._lastPoint, p, this._lastTilt, tilt);\n        this.addSegment(seg);\n        return this;\n    }\n\n    addSegment(segment) {\n        this._totalLength = -1;\n        this._lastPoint = segment.lastPoint();\n        this._lastTilt = segment.tiltEnd;\n        this._segments.push(segment);\n        return this;\n    }\n\n    getSegments() {\n        return this._segments;\n    }\n\n    updateLength() {\n        const n = this._segments.length;\n        this._lengthOffsets = new Array(n);\n\n        let offset = 0;\n        for (let i = 0; i < n; i++) {\n            this._lengthOffsets[i] = offset;\n            offset += this._segments[i].getLength();\n        }\n\n        this._totalLength = offset;\n    }\n\n    getLength() {\n        if (this._totalLength < 0) {\n            this.updateLength();\n        }\n\n        return this._totalLength;\n    }\n\n    /**\n     * Finding a path segment at a given absolute length distance\n     * @param {number} len absolute length distance\n     * @returns {[number, number]} [_segment index_, _relative segment distance_]\n     */\n    findSegmentIndexAtLength(len) {\n        const totalLength = this.getLength();\n\n        if (len <= 0) {\n            return [0, 0];\n        }\n\n        if (len >= totalLength) {\n            return [this._segments.length - 1, 1];\n        }\n\n        let start = 0;\n        let end = this._lengthOffsets.length - 1;\n        let index = -1;\n        let mid;\n\n        while (start <= end) {\n            mid = Math.ceil((start + end) / 2);\n\n            if (mid === 0 || mid === this._lengthOffsets.length - 1 || (len >= this._lengthOffsets[mid] && len < this._lengthOffsets[mid + 1])) {\n                index = mid;\n                break;\n            } else if (len < this._lengthOffsets[mid]) {\n                end = mid - 1;\n            } else {\n                start = mid + 1;\n            }\n        }\n\n        const seg = this._segments[index];\n        const segLen = seg.getLength();\n        const t = (len - this._lengthOffsets[index]) / segLen;\n\n        return [index, t];\n    }\n\n    getPointAtLength(len, out = new Vec3()) {\n        const [i, t] = this.findSegmentIndexAtLength(len);\n        return this._segments[i].getPointAt(t, out);\n    }\n\n    getPointAt(t, out = new Vec3()) {\n        const totalLength = this.getLength();\n        return this.getPointAtLength(t * totalLength, out);\n    }\n\n    getTangentAtLength(len, out = new Vec3()) {\n        const [i, t] = this.findSegmentIndexAtLength(len);\n        return this._segments[i].getTangentAt(t, out);\n    }\n\n    getTangentAt(t, out = new Vec3()) {\n        const totalLength = this.getLength();\n        return this.getTangentAtLength(t * totalLength, out);\n    }\n\n    getTiltAtLength(len) {\n        const [i, t] = this.findSegmentIndexAtLength(len);\n        return this._segments[i].getTiltAt(t);\n    }\n\n    getTiltAt(t) {\n        const totalLength = this.getLength();\n        return this.getTiltAtLength(t * totalLength);\n    }\n\n    /**\n     * Get sequence of points using `getPointAt(t)`\n     * @param {number} divisions number of subdivisions\n     * @returns {Vec3[]} array of points\n     */\n    getPoints(divisions = 64) {\n        const points = new Array(divisions + 1);\n        for (let i = 0; i <= divisions; i++) {\n            points[i] = this.getPointAt(i / divisions);\n        }\n        return points;\n    }\n\n    /**\n     * Generates the Frenet Frames.\n     * See http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n     * @param {number} divisions number of subdivisions\n     * @returns {{tangents: Vec3[], normals: Vec3[], binormals: Vec3[]}} Object with tangents, normals and binormals arrays\n     */\n    computeFrenetFrames(divisions = 64, closed = false) {\n        const tangents = new Array(divisions + 1);\n        const tilts = new Array(divisions + 1);\n\n        const tiltFunction = this.tiltFunction ?? ((a) => a);\n\n        // compute the tangent vectors and tilt for each segment on the curve\n        const totalLength = this.getLength();\n        for (let i = 0; i <= divisions; i++) {\n            const [si, st] = this.findSegmentIndexAtLength((totalLength * i) / divisions);\n            const segment = this._segments[si];\n            tangents[i] = segment.getTangentAt(st);\n            tilts[i] = tiltFunction(segment.getTiltAt(st), i / divisions, this);\n        }\n\n        const tx = Math.abs(tangents[0].x);\n        const ty = Math.abs(tangents[0].y);\n        const tz = Math.abs(tangents[0].z);\n\n        const normal = new Vec3();\n        if (tx < ty && tx < tz) {\n            normal.set(1, 0, 0);\n        } else if (ty < tx && ty < tz) {\n            normal.set(0, 1, 0);\n        } else {\n            normal.set(0, 0, 1);\n        }\n\n        // select an initial normal vector perpendicular to the first tangent vector,\n        // and in the direction of the minimum tangent xyz component\n        const normals = new Array(divisions + 1);\n        const binormals = new Array(divisions + 1);\n        normals[0] = new Vec3();\n        binormals[0] = new Vec3();\n\n        tempVec3.cross(tangents[0], normal).normalize();\n        normals[0].cross(tangents[0], tempVec3);\n        binormals[0].cross(tangents[0], normals[0]);\n\n        // compute the slowly-varying normal vector for each segment on the curve\n        for (let i = 1; i < tangents.length; i++) {\n            normals[i] = normals[i - 1].clone();\n            binormals[i] = new Vec3();\n\n            tempVec3.cross(tangents[i - 1], tangents[i]);\n            const crossLen = tempVec3.len();\n\n            if (crossLen > Number.EPSILON) {\n                tempVec3.scale(1 / crossLen); // nomalize\n                const cosTheta = clamp(tangents[i - 1].dot(tangents[i]), -1, 1); // clamp for floating pt errors\n                const sinTheta = clamp(crossLen, -1, 1);\n\n                mat4fromRotationSinCos(tempMat4, tempVec3, sinTheta, cosTheta);\n                normals[i].applyMatrix4(tempMat4);\n            }\n\n            binormals[i].cross(tangents[i], normals[i]);\n        }\n\n        // add tilt twisting\n        for (let i = 0; i < tilts.length; i++) {\n            rotateNormalBinormal(toRadian(tilts[i]), normals[i], binormals[i]);\n        }\n\n        // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n        if (closed === true) {\n            const normalLast = normals[normals.length - 1];\n            let step = Math.acos(clamp(normals[0].dot(normalLast), -1, 1)) / (normals.length - 1);\n\n            if (tangents[0].dot(tempVec3.cross(normals[0], normalLast)) > 0) {\n                step = -step;\n            }\n\n            for (let i = 1; i < normals.length - 1; i++) {\n                const angle = step * i;\n                rotateNormalBinormal(angle, normals[i], binormals[i]);\n                tilts[i] += toDegrees(angle);\n            }\n\n            normals[normals.length - 1] = normals[0].clone();\n            binormals[binormals.length - 1] = binormals[0].clone();\n        }\n\n        return { tangents, normals, binormals, tilts };\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\nimport { Vec3 } from '../math/Vec3.js';\nimport { Vec2 } from '../math/Vec2.js';\n\n// helper variables\nconst vertex = /* @__PURE__ */ new Vec3();\nconst normal = /* @__PURE__ */ new Vec3();\nconst uv = /* @__PURE__ */ new Vec2();\nconst point = /* @__PURE__ */ new Vec3();\n\nexport class Tube extends Geometry {\n    constructor(gl, { path, radius = 1, tubularSegments = 64, radialSegments = 8, closed = false, attributes = {} } = {}) {\n        super(gl, attributes);\n\n        this.path = path;\n        this.radius = radius;\n        this.tubularSegments = tubularSegments;\n        this.radialSegments = radialSegments;\n        this.closed = closed;\n\n        this.frenetFrames = path.computeFrenetFrames(tubularSegments, closed);\n\n        const numVertices = (tubularSegments + 1) * (radialSegments + 1);\n        const numIndices = tubularSegments * radialSegments * 6;\n        this.positions = new Float32Array(numVertices * 3);\n        this.normals = new Float32Array(numVertices * 3);\n        this.uvs = new Float32Array(numVertices * 2);\n        this.indices = numVertices > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices);\n\n        // create buffer data\n        this._generateAttributes();\n        this._generateIndices();\n\n        this.addAttribute('position', { size: 3, data: this.positions });\n        this.addAttribute('normal', { size: 3, data: this.normals });\n        this.addAttribute('uv', { size: 2, data: this.uvs });\n        this.setIndex({ data: this.indices });\n    }\n\n    _generateAttributes() {\n        for (let i = 0; i <= this.tubularSegments; i++) {\n            let ci = i;\n            if (i === this.tubularSegments) {\n                // if the geometry is not closed, generate the last row of vertices and normals\n                // at the regular position on the given path\n                // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n                ci = this.closed ? 0 : this.tubularSegments;\n            }\n\n            this.path.getPointAt(ci / this.tubularSegments, point);\n            // retrieve corresponding normal and binormal\n            const N = this.frenetFrames.normals[ci];\n            const B = this.frenetFrames.binormals[ci];\n\n            // generate normals and vertices for the current segment\n            for (let j = 0; j <= this.radialSegments; j++) {\n                const v = (j / this.radialSegments) * Math.PI * 2;\n                const sin = Math.sin(v);\n                const cos = -Math.cos(v);\n\n                const idx = i * (this.radialSegments + 1) + j;\n\n                // normal\n                normal.x = cos * N.x + sin * B.x;\n                normal.y = cos * N.y + sin * B.y;\n                normal.z = cos * N.z + sin * B.z;\n                // normal.normalize(); // ???\n                this.normals.set(normal, idx * 3);\n\n                // vertex\n                vertex.x = point.x + this.radius * normal.x;\n                vertex.y = point.y + this.radius * normal.y;\n                vertex.z = point.z + this.radius * normal.z;\n                this.positions.set(vertex, idx * 3);\n\n                // uv\n                uv.x = i / this.tubularSegments;\n                uv.y = j / this.radialSegments;\n                this.uvs.set(uv, idx * 2);\n            }\n        }\n    }\n\n    _generateIndices() {\n        for (let j = 1; j <= this.tubularSegments; j++) {\n            for (let i = 1; i <= this.radialSegments; i++) {\n                const a = (this.radialSegments + 1) * (j - 1) + (i - 1);\n                const b = (this.radialSegments + 1) * j + (i - 1);\n                const c = (this.radialSegments + 1) * j + i;\n                const d = (this.radialSegments + 1) * (j - 1) + i;\n\n                const idx = (j - 1) * this.radialSegments + (i - 1);\n                this.indices.set([a, b, d, b, c, d], idx * 6);\n            }\n        }\n    }\n}\n","import { Program } from '../core/Program.js';\nimport { Mesh } from '../core/Mesh.js';\nimport { RenderTarget } from '../core/RenderTarget.js';\nimport { Triangle } from './Triangle.js';\n\nexport class Post {\n    constructor(\n        gl,\n        {\n            width,\n            height,\n            dpr,\n            wrapS = gl.CLAMP_TO_EDGE,\n            wrapT = gl.CLAMP_TO_EDGE,\n            minFilter = gl.LINEAR,\n            magFilter = gl.LINEAR,\n            geometry = new Triangle(gl),\n            targetOnly = null,\n            depth = true,\n        } = {}\n    ) {\n        this.gl = gl;\n\n        this.passes = [];\n\n        this.geometry = geometry;\n\n        this.uniform = { value: null };\n        this.targetOnly = targetOnly;\n\n        if (dpr) this.dpr = dpr;\n        if (width) this.width = width;\n        if (height) this.height = height;\n\n        dpr = this.dpr || this.gl.renderer.dpr;\n        this.resolutionWidth = Math.floor(this.width || this.gl.renderer.width * dpr);\n        this.resolutionHeight = Math.floor(this.height || this.gl.renderer.height * dpr);\n\n        let options = {\n            dpr: this.dpr,\n            width: this.resolutionWidth,\n            height: this.resolutionHeight,\n            wrapS,\n            wrapT,\n            minFilter,\n            magFilter,\n            depth,\n        };\n\n        const fbo = (this.fbo = {\n            read: new RenderTarget(this.gl, options),\n            write: new RenderTarget(this.gl, options),\n            swap: () => {\n                let temp = fbo.read;\n                fbo.read = fbo.write;\n                fbo.write = temp;\n            },\n        });\n    }\n\n    addPass({ vertex = defaultVertex, fragment = defaultFragment, uniforms = {}, textureUniform = 'tMap', enabled = true } = {}) {\n        uniforms[textureUniform] = { value: this.fbo.read.texture };\n\n        const program = new Program(this.gl, { vertex, fragment, uniforms });\n        const mesh = new Mesh(this.gl, { geometry: this.geometry, program });\n\n        const pass = {\n            mesh,\n            program,\n            uniforms,\n            enabled,\n            textureUniform,\n        };\n\n        this.passes.push(pass);\n        return pass;\n    }\n\n    resize({ width, height, dpr } = {}) {\n        if (dpr) this.dpr = dpr;\n        if (width) this.width = width;\n        if (height) this.height = height;\n\n        dpr = this.dpr || this.gl.renderer.dpr;\n        this.resolutionWidth = Math.floor(this.width || this.gl.renderer.width * dpr);\n        this.resolutionHeight = Math.floor(this.height || this.gl.renderer.height * dpr);\n\n        this.fbo.read.setSize(this.resolutionWidth, this.resolutionHeight);\n        this.fbo.write.setSize(this.resolutionWidth, this.resolutionHeight);\n    }\n\n    // Uses same arguments as renderer.render, with addition of optional texture passed in to avoid scene render\n    render({ scene, camera, texture, target = null, update = true, sort = true, frustumCull = true, beforePostCallbacks }) {\n        const enabledPasses = this.passes.filter((pass) => pass.enabled);\n\n        if (!texture) {\n            this.gl.renderer.render({\n                scene,\n                camera,\n                target: enabledPasses.length || (!target && this.targetOnly) ? this.fbo.write : target,\n                update,\n                sort,\n                frustumCull,\n            });\n            this.fbo.swap();\n\n            // Callback after rendering scene, but before post effects\n            if (beforePostCallbacks) beforePostCallbacks.forEach((f) => f && f());\n        }\n\n        enabledPasses.forEach((pass, i) => {\n            pass.mesh.program.uniforms[pass.textureUniform].value = !i && texture ? texture : this.fbo.read.texture;\n            this.gl.renderer.render({\n                scene: pass.mesh,\n                target: i === enabledPasses.length - 1 && (target || !this.targetOnly) ? target : this.fbo.write,\n                clear: true,\n            });\n            this.fbo.swap();\n        });\n\n        this.uniform.value = this.fbo.read.texture;\n    }\n}\n\nconst defaultVertex = /* glsl */ `\n    attribute vec2 uv;\n    attribute vec2 position;\n\n    varying vec2 vUv;\n\n    void main() {\n        vUv = uv;\n        gl_Position = vec4(position, 0, 1);\n    }\n`;\n\nconst defaultFragment = /* glsl */ `\n    precision highp float;\n\n    uniform sampler2D tMap;\n    varying vec2 vUv;\n\n    void main() {\n        gl_FragColor = texture2D(tMap, vUv);\n    }\n`;\n","import { Vec3 } from '../math/Vec3.js';\nimport { Quat } from '../math/Quat.js';\n\nconst prevPos = /* @__PURE__ */ new Vec3();\nconst prevRot = /* @__PURE__ */ new Quat();\nconst prevScl = /* @__PURE__ */ new Vec3();\n\nconst nextPos = /* @__PURE__ */ new Vec3();\nconst nextRot = /* @__PURE__ */ new Quat();\nconst nextScl = /* @__PURE__ */ new Vec3();\n\nexport class Animation {\n    constructor({ objects, data }) {\n        this.objects = objects;\n        this.data = data;\n        this.elapsed = 0;\n        this.weight = 1;\n        this.duration = data.frames.length - 1;\n    }\n\n    update(totalWeight = 1, isSet) {\n        const weight = isSet ? 1 : this.weight / totalWeight;\n        const elapsed = this.elapsed % this.duration;\n\n        const floorFrame = Math.floor(elapsed);\n        const blend = elapsed - floorFrame;\n        const prevKey = this.data.frames[floorFrame];\n        const nextKey = this.data.frames[(floorFrame + 1) % this.duration];\n\n        this.objects.forEach((object, i) => {\n            prevPos.fromArray(prevKey.position, i * 3);\n            prevRot.fromArray(prevKey.quaternion, i * 4);\n            prevScl.fromArray(prevKey.scale, i * 3);\n\n            nextPos.fromArray(nextKey.position, i * 3);\n            nextRot.fromArray(nextKey.quaternion, i * 4);\n            nextScl.fromArray(nextKey.scale, i * 3);\n\n            prevPos.lerp(nextPos, blend);\n            prevRot.slerp(nextRot, blend);\n            prevScl.lerp(nextScl, blend);\n\n            object.position.lerp(prevPos, weight);\n            object.quaternion.slerp(prevRot, weight);\n            object.scale.lerp(prevScl, weight);\n        });\n    }\n}\n","import { Mesh } from '../core/Mesh.js';\nimport { Transform } from '../core/Transform.js';\nimport { Mat4 } from '../math/Mat4.js';\nimport { Texture } from '../core/Texture.js';\nimport { Animation } from './Animation.js';\n\nconst tempMat4 = /* @__PURE__ */ new Mat4();\n\nexport class Skin extends Mesh {\n    constructor(gl, { rig, geometry, program, mode = gl.TRIANGLES } = {}) {\n        super(gl, { geometry, program, mode });\n\n        this.createBones(rig);\n        this.createBoneTexture();\n        this.animations = [];\n\n        Object.assign(this.program.uniforms, {\n            boneTexture: { value: this.boneTexture },\n            boneTextureSize: { value: this.boneTextureSize },\n        });\n    }\n\n    createBones(rig) {\n        // Create root so that can simply update world matrix of whole skeleton\n        this.root = new Transform();\n\n        // Create bones\n        this.bones = [];\n        if (!rig.bones || !rig.bones.length) return;\n        for (let i = 0; i < rig.bones.length; i++) {\n            const bone = new Transform();\n\n            // Set initial values (bind pose)\n            bone.position.fromArray(rig.bindPose.position, i * 3);\n            bone.quaternion.fromArray(rig.bindPose.quaternion, i * 4);\n            bone.scale.fromArray(rig.bindPose.scale, i * 3);\n\n            this.bones.push(bone);\n        }\n\n        // Once created, set the hierarchy\n        rig.bones.forEach((data, i) => {\n            this.bones[i].name = data.name;\n            if (data.parent === -1) return this.bones[i].setParent(this.root);\n            this.bones[i].setParent(this.bones[data.parent]);\n        });\n\n        // Then update to calculate world matrices\n        this.root.updateMatrixWorld(true);\n\n        // Store inverse of bind pose to calculate differences\n        this.bones.forEach((bone) => {\n            bone.bindInverse = new Mat4(...bone.worldMatrix).inverse();\n        });\n    }\n\n    createBoneTexture() {\n        if (!this.bones.length) return;\n        const size = Math.max(4, Math.pow(2, Math.ceil(Math.log(Math.sqrt(this.bones.length * 4)) / Math.LN2)));\n        this.boneMatrices = new Float32Array(size * size * 4);\n        this.boneTextureSize = size;\n        this.boneTexture = new Texture(this.gl, {\n            image: this.boneMatrices,\n            generateMipmaps: false,\n            type: this.gl.FLOAT,\n            internalFormat: this.gl.renderer.isWebgl2 ? this.gl.RGBA32F : this.gl.RGBA,\n            minFilter: this.gl.NEAREST,\n            magFilter: this.gl.NEAREST,\n            flipY: false,\n            width: size,\n        });\n    }\n\n    addAnimation(data) {\n        const animation = new Animation({ objects: this.bones, data });\n        this.animations.push(animation);\n        return animation;\n    }\n\n    update() {\n        // Calculate combined animation weight\n        let total = 0;\n        this.animations.forEach((animation) => (total += animation.weight));\n\n        this.animations.forEach((animation, i) => {\n            // force first animation to set in order to reset frame\n            animation.update(total, i === 0);\n        });\n    }\n\n    draw({ camera } = {}) {\n        // Update world matrices manually, as not part of scene graph\n        this.root.updateMatrixWorld(true);\n\n        // Update bone texture\n        this.bones.forEach((bone, i) => {\n            // Find difference between current and bind pose\n            tempMat4.multiply(bone.worldMatrix, bone.bindInverse);\n            this.boneMatrices.set(tempMat4, i * 16);\n        });\n        if (this.boneTexture) this.boneTexture.needsUpdate = true;\n\n        super.draw({ camera });\n    }\n}\n","import { RenderTarget } from '../core/RenderTarget.js';\nimport { Program } from '../core/Program.js';\nimport { Mesh } from '../core/Mesh.js';\nimport { Vec2 } from '../math/Vec2.js';\nimport { Triangle } from './Triangle.js';\n\nexport class Flowmap {\n    constructor(\n        gl,\n        {\n            size = 128, // default size of the render targets\n            falloff = 0.3, // size of the stamp, percentage of the size\n            alpha = 1, // opacity of the stamp\n            dissipation = 0.98, // affects the speed that the stamp fades. Closer to 1 is slower\n            type, // Pass in gl.FLOAT to force it, defaults to gl.HALF_FLOAT\n        } = {}\n    ) {\n        const _this = this;\n        this.gl = gl;\n\n        // output uniform containing render target textures\n        this.uniform = { value: null };\n\n        this.mask = {\n            read: null,\n            write: null,\n\n            // Helper function to ping pong the render targets and update the uniform\n            swap: () => {\n                let temp = _this.mask.read;\n                _this.mask.read = _this.mask.write;\n                _this.mask.write = temp;\n                _this.uniform.value = _this.mask.read.texture;\n            },\n        };\n\n        {\n            createFBOs();\n\n            this.aspect = 1;\n            this.mouse = new Vec2();\n            this.velocity = new Vec2();\n\n            this.mesh = initProgram();\n        }\n\n        function createFBOs() {\n            // Requested type not supported, fall back to half float\n            if (!type) type = gl.HALF_FLOAT || gl.renderer.extensions['OES_texture_half_float'].HALF_FLOAT_OES;\n\n            let minFilter = (() => {\n                if (gl.renderer.isWebgl2) return gl.LINEAR;\n                if (gl.renderer.extensions[`OES_texture_${type === gl.FLOAT ? '' : 'half_'}float_linear`]) return gl.LINEAR;\n                return gl.NEAREST;\n            })();\n\n            const options = {\n                width: size,\n                height: size,\n                type,\n                format: gl.RGBA,\n                internalFormat: gl.renderer.isWebgl2 ? (type === gl.FLOAT ? gl.RGBA32F : gl.RGBA16F) : gl.RGBA,\n                minFilter,\n                depth: false,\n            };\n\n            _this.mask.read = new RenderTarget(gl, options);\n            _this.mask.write = new RenderTarget(gl, options);\n            _this.mask.swap();\n        }\n\n        function initProgram() {\n            return new Mesh(gl, {\n                // Triangle that includes -1 to 1 range for 'position', and 0 to 1 range for 'uv'.\n                geometry: new Triangle(gl),\n\n                program: new Program(gl, {\n                    vertex,\n                    fragment,\n                    uniforms: {\n                        tMap: _this.uniform,\n\n                        uFalloff: { value: falloff * 0.5 },\n                        uAlpha: { value: alpha },\n                        uDissipation: { value: dissipation },\n\n                        // User needs to update these\n                        uAspect: { value: 1 },\n                        uMouse: { value: _this.mouse },\n                        uVelocity: { value: _this.velocity },\n                    },\n                    depthTest: false,\n                }),\n            });\n        }\n    }\n\n    update() {\n        this.mesh.program.uniforms.uAspect.value = this.aspect;\n\n        this.gl.renderer.render({\n            scene: this.mesh,\n            target: this.mask.write,\n            clear: false,\n        });\n        this.mask.swap();\n    }\n}\n\nconst vertex = /* glsl */ `\n    attribute vec2 uv;\n    attribute vec2 position;\n\n    varying vec2 vUv;\n\n    void main() {\n        vUv = uv;\n        gl_Position = vec4(position, 0, 1);\n    }\n`;\n\nconst fragment = /* glsl */ `\n    precision highp float;\n\n    uniform sampler2D tMap;\n\n    uniform float uFalloff;\n    uniform float uAlpha;\n    uniform float uDissipation;\n    \n    uniform float uAspect;\n    uniform vec2 uMouse;\n    uniform vec2 uVelocity;\n\n    varying vec2 vUv;\n\n    void main() {\n        vec4 color = texture2D(tMap, vUv) * uDissipation;\n\n        vec2 cursor = vUv - uMouse;\n        cursor.x *= uAspect;\n\n        vec3 stamp = vec3(uVelocity * vec2(1, -1), 1.0 - pow(1.0 - min(1.0, length(uVelocity)), 3.0));\n        float falloff = smoothstep(uFalloff, 0.0, length(cursor)) * uAlpha;\n\n        color.rgb = mix(color.rgb, stamp, vec3(falloff));\n\n        gl_FragColor = color;\n    }\n`;\n","import { Program } from '../core/Program.js';\nimport { Mesh } from '../core/Mesh.js';\nimport { Texture } from '../core/Texture.js';\nimport { RenderTarget } from '../core/RenderTarget.js';\nimport { Triangle } from './Triangle.js';\n\nexport class GPGPU {\n    constructor(\n        gl,\n        {\n            // Always pass in array of vec4s (RGBA values within texture)\n            data = new Float32Array(16),\n            geometry = new Triangle(gl),\n            type, // Pass in gl.FLOAT to force it, defaults to gl.HALF_FLOAT\n        }\n    ) {\n        this.gl = gl;\n        const initialData = data;\n        this.passes = [];\n        this.geometry = geometry;\n        this.dataLength = initialData.length / 4;\n\n        // Windows and iOS only like power of 2 textures\n        // Find smallest PO2 that fits data\n        this.size = Math.pow(2, Math.ceil(Math.log(Math.ceil(Math.sqrt(this.dataLength))) / Math.LN2));\n\n        // Create coords for output texture\n        this.coords = new Float32Array(this.dataLength * 2);\n        for (let i = 0; i < this.dataLength; i++) {\n            const x = (i % this.size) / this.size; // to add 0.5 to be center pixel ?\n            const y = Math.floor(i / this.size) / this.size;\n            this.coords.set([x, y], i * 2);\n        }\n\n        // Use original data if already correct length of PO2 texture, else copy to new array of correct length\n        const floatArray = (() => {\n            if (initialData.length === this.size * this.size * 4) {\n                return initialData;\n            } else {\n                const a = new Float32Array(this.size * this.size * 4);\n                a.set(initialData);\n                return a;\n            }\n        })();\n\n        // Create output texture uniform using input float texture with initial data\n        this.uniform = {\n            value: new Texture(gl, {\n                image: floatArray,\n                target: gl.TEXTURE_2D,\n                type: gl.FLOAT,\n                format: gl.RGBA,\n                internalFormat: gl.renderer.isWebgl2 ? gl.RGBA32F : gl.RGBA,\n                wrapS: gl.CLAMP_TO_EDGE,\n                wrapT: gl.CLAMP_TO_EDGE,\n                generateMipmaps: false,\n                minFilter: gl.NEAREST,\n                magFilter: gl.NEAREST,\n                width: this.size,\n                flipY: false,\n            }),\n        };\n\n        // Create FBOs\n        const options = {\n            width: this.size,\n            height: this.size,\n            type: type || gl.HALF_FLOAT || gl.renderer.extensions['OES_texture_half_float'].HALF_FLOAT_OES,\n            format: gl.RGBA,\n            internalFormat: gl.renderer.isWebgl2 ? (type === gl.FLOAT ? gl.RGBA32F : gl.RGBA16F) : gl.RGBA,\n            minFilter: gl.NEAREST,\n            depth: false,\n            unpackAlignment: 1,\n        };\n\n        this.fbo = {\n            read: new RenderTarget(gl, options),\n            write: new RenderTarget(gl, options),\n            swap: () => {\n                let temp = this.fbo.read;\n                this.fbo.read = this.fbo.write;\n                this.fbo.write = temp;\n                this.uniform.value = this.fbo.read.texture;\n            },\n        };\n    }\n\n    addPass({ vertex = defaultVertex, fragment = defaultFragment, uniforms = {}, textureUniform = 'tMap', enabled = true } = {}) {\n        uniforms[textureUniform] = this.uniform;\n        const program = new Program(this.gl, { vertex, fragment, uniforms });\n        const mesh = new Mesh(this.gl, { geometry: this.geometry, program });\n\n        const pass = {\n            mesh,\n            program,\n            uniforms,\n            enabled,\n            textureUniform,\n        };\n\n        this.passes.push(pass);\n        return pass;\n    }\n\n    render() {\n        const enabledPasses = this.passes.filter((pass) => pass.enabled);\n\n        enabledPasses.forEach((pass, i) => {\n            this.gl.renderer.render({\n                scene: pass.mesh,\n                target: this.fbo.write,\n                clear: false,\n            });\n            this.fbo.swap();\n        });\n    }\n}\n\nconst defaultVertex = /* glsl */ `\n    attribute vec2 uv;\n    attribute vec2 position;\n\n    varying vec2 vUv;\n\n    void main() {\n        vUv = uv;\n        gl_Position = vec4(position, 0, 1);\n    }\n`;\n\nconst defaultFragment = /* glsl */ `\n    precision highp float;\n\n    uniform sampler2D tMap;\n    varying vec2 vUv;\n\n    void main() {\n        gl_FragColor = texture2D(tMap, vUv);\n    }\n`;\n","import { Geometry } from '../core/Geometry.js';\nimport { Program } from '../core/Program.js';\nimport { Mesh } from '../core/Mesh.js';\nimport { Vec2 } from '../math/Vec2.js';\nimport { Vec3 } from '../math/Vec3.js';\nimport { Color } from '../math/Color.js';\n\nconst tmp = /* @__PURE__ */ new Vec3();\n\nexport class Polyline {\n    constructor(\n        gl,\n        {\n            points, // Array of Vec3s\n            vertex = defaultVertex,\n            fragment = defaultFragment,\n            uniforms = {},\n            attributes = {}, // For passing in custom attribs\n        }\n    ) {\n        this.gl = gl;\n        this.points = points;\n        this.count = points.length;\n\n        // Create buffers\n        this.position = new Float32Array(this.count * 3 * 2);\n        this.prev = new Float32Array(this.count * 3 * 2);\n        this.next = new Float32Array(this.count * 3 * 2);\n        const side = new Float32Array(this.count * 1 * 2);\n        const uv = new Float32Array(this.count * 2 * 2);\n        const index = new Uint16Array((this.count - 1) * 3 * 2);\n\n        // Set static buffers\n        for (let i = 0; i < this.count; i++) {\n            side.set([-1, 1], i * 2);\n            const v = i / (this.count - 1);\n            uv.set([0, v, 1, v], i * 4);\n\n            if (i === this.count - 1) continue;\n            const ind = i * 2;\n            index.set([ind + 0, ind + 1, ind + 2], (ind + 0) * 3);\n            index.set([ind + 2, ind + 1, ind + 3], (ind + 1) * 3);\n        }\n\n        const geometry = (this.geometry = new Geometry(\n            gl,\n            Object.assign(attributes, {\n                position: { size: 3, data: this.position },\n                prev: { size: 3, data: this.prev },\n                next: { size: 3, data: this.next },\n                side: { size: 1, data: side },\n                uv: { size: 2, data: uv },\n                index: { size: 1, data: index },\n            })\n        ));\n\n        // Populate dynamic buffers\n        this.updateGeometry();\n\n        if (!uniforms.uResolution) this.resolution = uniforms.uResolution = { value: new Vec2() };\n        if (!uniforms.uDPR) this.dpr = uniforms.uDPR = { value: 1 };\n        if (!uniforms.uThickness) this.thickness = uniforms.uThickness = { value: 1 };\n        if (!uniforms.uColor) this.color = uniforms.uColor = { value: new Color('#000') };\n        if (!uniforms.uMiter) this.miter = uniforms.uMiter = { value: 1 };\n\n        // Set size uniforms' values\n        this.resize();\n\n        const program = (this.program = new Program(gl, {\n            vertex,\n            fragment,\n            uniforms,\n        }));\n\n        this.mesh = new Mesh(gl, { geometry, program });\n    }\n\n    updateGeometry() {\n        this.points.forEach((p, i) => {\n            p.toArray(this.position, i * 3 * 2);\n            p.toArray(this.position, i * 3 * 2 + 3);\n\n            if (!i) {\n                // If first point, calculate prev using the distance to 2nd point\n                tmp.copy(p)\n                    .sub(this.points[i + 1])\n                    .add(p);\n                tmp.toArray(this.prev, i * 3 * 2);\n                tmp.toArray(this.prev, i * 3 * 2 + 3);\n            } else {\n                p.toArray(this.next, (i - 1) * 3 * 2);\n                p.toArray(this.next, (i - 1) * 3 * 2 + 3);\n            }\n\n            if (i === this.points.length - 1) {\n                // If last point, calculate next using distance to 2nd last point\n                tmp.copy(p)\n                    .sub(this.points[i - 1])\n                    .add(p);\n                tmp.toArray(this.next, i * 3 * 2);\n                tmp.toArray(this.next, i * 3 * 2 + 3);\n            } else {\n                p.toArray(this.prev, (i + 1) * 3 * 2);\n                p.toArray(this.prev, (i + 1) * 3 * 2 + 3);\n            }\n        });\n\n        this.geometry.attributes.position.needsUpdate = true;\n        this.geometry.attributes.prev.needsUpdate = true;\n        this.geometry.attributes.next.needsUpdate = true;\n    }\n\n    // Only need to call if not handling resolution uniforms manually\n    resize() {\n        // Update automatic uniforms if not overridden\n        if (this.resolution) this.resolution.value.set(this.gl.canvas.width, this.gl.canvas.height);\n        if (this.dpr) this.dpr.value = this.gl.renderer.dpr;\n    }\n}\n\nconst defaultVertex = /* glsl */ `\n    precision highp float;\n\n    attribute vec3 position;\n    attribute vec3 next;\n    attribute vec3 prev;\n    attribute vec2 uv;\n    attribute float side;\n\n    uniform mat4 modelViewMatrix;\n    uniform mat4 projectionMatrix;\n    uniform vec2 uResolution;\n    uniform float uDPR;\n    uniform float uThickness;\n    uniform float uMiter;\n\n    varying vec2 vUv;\n\n    vec4 getPosition() {\n        mat4 mvp = projectionMatrix * modelViewMatrix;\n        vec4 current = mvp * vec4(position, 1);\n        vec4 nextPos = mvp * vec4(next, 1);\n        vec4 prevPos = mvp * vec4(prev, 1);\n\n        vec2 aspect = vec2(uResolution.x / uResolution.y, 1);    \n        vec2 currentScreen = current.xy / current.w * aspect;\n        vec2 nextScreen = nextPos.xy / nextPos.w * aspect;\n        vec2 prevScreen = prevPos.xy / prevPos.w * aspect;\n    \n        vec2 dir1 = normalize(currentScreen - prevScreen);\n        vec2 dir2 = normalize(nextScreen - currentScreen);\n        vec2 dir = normalize(dir1 + dir2);\n    \n        vec2 normal = vec2(-dir.y, dir.x);\n        normal /= mix(1.0, max(0.3, dot(normal, vec2(-dir1.y, dir1.x))), uMiter);\n        normal /= aspect;\n\n        float pixelWidthRatio = 1.0 / (uResolution.y / uDPR);\n        float pixelWidth = current.w * pixelWidthRatio;\n        normal *= pixelWidth * uThickness;\n        current.xy -= normal * side;\n    \n        return current;\n    }\n\n    void main() {\n        vUv = uv;\n        gl_Position = getPosition();\n    }\n`;\n\nconst defaultFragment = /* glsl */ `\n    precision highp float;\n\n    uniform vec3 uColor;\n    \n    varying vec2 vUv;\n\n    void main() {\n        gl_FragColor.rgb = uColor;\n        gl_FragColor.a = 1.0;\n    }\n`;\n","import { Camera } from '../core/Camera.js';\nimport { Program } from '../core/Program.js';\nimport { RenderTarget } from '../core/RenderTarget.js';\n\nexport class Shadow {\n    constructor(gl, { light = new Camera(gl), width = 1024, height = width }) {\n        this.gl = gl;\n\n        this.light = light;\n\n        this.target = new RenderTarget(gl, { width, height });\n        this.targetUniform = { value: this.target.texture };\n\n        this.depthProgram = new Program(gl, {\n            vertex: defaultVertex,\n            fragment: defaultFragment,\n            cullFace: false,\n        });\n\n        this.castMeshes = [];\n    }\n\n    add({\n        mesh,\n        receive = true,\n        cast = true,\n        vertex = defaultVertex,\n        fragment = defaultFragment,\n        uniformProjection = 'shadowProjectionMatrix',\n        uniformView = 'shadowViewMatrix',\n        uniformTexture = 'tShadow',\n    }) {\n        // Add uniforms to existing program\n        if (receive && !mesh.program.uniforms[uniformProjection]) {\n            mesh.program.uniforms[uniformProjection] = { value: this.light.projectionMatrix };\n            mesh.program.uniforms[uniformView] = { value: this.light.viewMatrix };\n            mesh.program.uniforms[uniformTexture] = this.targetUniform;\n        }\n\n        if (!cast) return;\n        this.castMeshes.push(mesh);\n\n        // Store program for when switching between depth override\n        mesh.colorProgram = mesh.program;\n\n        // Check if depth program already attached\n        if (mesh.depthProgram) return;\n\n        // Use global depth override if nothing custom passed in\n        if (vertex === defaultVertex && fragment === defaultFragment) {\n            mesh.depthProgram = this.depthProgram;\n            return;\n        }\n\n        // Create custom override program\n        mesh.depthProgram = new Program(this.gl, {\n            vertex,\n            fragment,\n            cullFace: false,\n        });\n    }\n\n    setSize({ width = 1024, height = width }) {\n        this.target = new RenderTarget(this.gl, { width, height });\n        this.targetUniform.value = this.target.texture;\n    }\n\n    render({ scene }) {\n        // For depth render, replace program with depth override.\n        // Hide meshes not casting shadows.\n        scene.traverse((node) => {\n            if (!node.draw) return;\n            if (!!~this.castMeshes.indexOf(node)) {\n                node.program = node.depthProgram;\n            } else {\n                node.isForceVisibility = node.visible;\n                node.visible = false;\n            }\n        });\n\n        // Render the depth shadow map using the light as the camera\n        this.gl.renderer.render({\n            scene,\n            camera: this.light,\n            target: this.target,\n        });\n\n        // Then switch the program back to the normal one\n        scene.traverse((node) => {\n            if (!node.draw) return;\n            if (!!~this.castMeshes.indexOf(node)) {\n                node.program = node.colorProgram;\n            } else {\n                node.visible = node.isForceVisibility;\n            }\n        });\n    }\n}\n\nconst defaultVertex = /* glsl */ `\n    attribute vec3 position;\n    attribute vec2 uv;\n\n    uniform mat4 modelViewMatrix;\n    uniform mat4 projectionMatrix;\n\n    void main() {\n        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n    }\n`;\n\nconst defaultFragment = /* glsl */ `\n    precision highp float;\n\n    vec4 packRGBA (float v) {\n        vec4 pack = fract(vec4(1.0, 255.0, 65025.0, 16581375.0) * v);\n        pack -= pack.yzww * vec2(1.0 / 255.0, 0.0).xxxy;\n        return pack;\n    }\n\n    void main() {\n        gl_FragColor = packRGBA(gl_FragCoord.z);\n    }\n`;\n","import { Texture } from '../core/Texture.js';\n\n// TODO: Support cubemaps\n// Generate textures using https://github.com/TimvanScherpenzeel/texture-compressor\n\nexport class KTXTexture extends Texture {\n    constructor(gl, { buffer, wrapS = gl.CLAMP_TO_EDGE, wrapT = gl.CLAMP_TO_EDGE, anisotropy = 0, minFilter, magFilter } = {}) {\n        super(gl, {\n            generateMipmaps: false,\n            wrapS,\n            wrapT,\n            anisotropy,\n            minFilter,\n            magFilter,\n        });\n\n        if (buffer) return this.parseBuffer(buffer);\n    }\n\n    parseBuffer(buffer) {\n        const ktx = new KhronosTextureContainer(buffer);\n        ktx.mipmaps.isCompressedTexture = true;\n\n        // Update texture\n        this.image = ktx.mipmaps;\n        this.internalFormat = ktx.glInternalFormat;\n        if (ktx.numberOfMipmapLevels > 1) {\n            if (this.minFilter === this.gl.LINEAR) this.minFilter = this.gl.NEAREST_MIPMAP_LINEAR;\n        } else {\n            if (this.minFilter === this.gl.NEAREST_MIPMAP_LINEAR) this.minFilter = this.gl.LINEAR;\n        }\n\n        // TODO: support cube maps\n        // ktx.numberOfFaces\n    }\n}\n\nfunction KhronosTextureContainer(buffer) {\n    const idCheck = [0xab, 0x4b, 0x54, 0x58, 0x20, 0x31, 0x31, 0xbb, 0x0d, 0x0a, 0x1a, 0x0a];\n    const id = new Uint8Array(buffer, 0, 12);\n    for (let i = 0; i < id.length; i++) if (id[i] !== idCheck[i]) return console.error('File missing KTX identifier');\n\n    // TODO: Is this always 4? Tested: [android, macos]\n    const size = Uint32Array.BYTES_PER_ELEMENT;\n    const head = new DataView(buffer, 12, 13 * size);\n    const littleEndian = head.getUint32(0, true) === 0x04030201;\n    const glType = head.getUint32(1 * size, littleEndian);\n    if (glType !== 0) return console.warn('only compressed formats currently supported');\n    this.glInternalFormat = head.getUint32(4 * size, littleEndian);\n    let width = head.getUint32(6 * size, littleEndian);\n    let height = head.getUint32(7 * size, littleEndian);\n    this.numberOfFaces = head.getUint32(10 * size, littleEndian);\n    this.numberOfMipmapLevels = Math.max(1, head.getUint32(11 * size, littleEndian));\n    const bytesOfKeyValueData = head.getUint32(12 * size, littleEndian);\n\n    this.mipmaps = [];\n    let offset = 12 + 13 * 4 + bytesOfKeyValueData;\n    for (let level = 0; level < this.numberOfMipmapLevels; level++) {\n        const levelSize = new Int32Array(buffer, offset, 1)[0]; // size per face, since not supporting array cubemaps\n        offset += 4; // levelSize field\n        for (let face = 0; face < this.numberOfFaces; face++) {\n            const data = new Uint8Array(buffer, offset, levelSize);\n            this.mipmaps.push({ data, width, height });\n            offset += levelSize;\n            offset += 3 - ((levelSize + 3) % 4); // add padding for odd sized image\n        }\n        width = width >> 1;\n        height = height >> 1;\n    }\n}\n","import { Texture } from '../core/Texture.js';\nimport { KTXTexture } from './KTXTexture.js';\n\n// For compressed textures, generate using https://github.com/TimvanScherpenzeel/texture-compressor\n\nlet cache = {};\nconst supportedExtensions = [];\n\nexport class TextureLoader {\n    static load(\n        gl,\n        {\n            src, // string or object of extension:src key-values\n            // {\n            //     pvrtc: '...ktx',\n            //     s3tc: '...ktx',\n            //     etc: '...ktx',\n            //     etc1: '...ktx',\n            //     astc: '...ktx',\n            //     webp: '...webp',\n            //     jpg: '...jpg',\n            //     png: '...png',\n            // }\n\n            // Only props relevant to KTXTexture\n            wrapS = gl.CLAMP_TO_EDGE,\n            wrapT = gl.CLAMP_TO_EDGE,\n            anisotropy = 0,\n\n            // For regular images\n            format = gl.RGBA,\n            internalFormat = format,\n            generateMipmaps = true,\n            minFilter = generateMipmaps ? gl.NEAREST_MIPMAP_LINEAR : gl.LINEAR,\n            magFilter = gl.LINEAR,\n            premultiplyAlpha = false,\n            unpackAlignment = 4,\n            flipY = true,\n        } = {}\n    ) {\n        const support = this.getSupportedExtensions(gl);\n        let ext = 'none';\n\n        // If src is string, determine which format from the extension\n        if (typeof src === 'string') {\n            ext = src.split('.').pop().split('?')[0].toLowerCase();\n        }\n\n        // If src is object, use supported extensions and provided list to choose best option\n        // Get first supported match, so put in order of preference\n        if (typeof src === 'object') {\n            for (const prop in src) {\n                if (support.includes(prop.toLowerCase())) {\n                    ext = prop.toLowerCase();\n                    src = src[prop];\n                    break;\n                }\n            }\n        }\n\n        // Stringify props\n        const cacheID = src + wrapS + wrapT + anisotropy + format + internalFormat + generateMipmaps + minFilter + magFilter + premultiplyAlpha + unpackAlignment + flipY + gl.renderer.id;\n\n        // Check cache for existing texture\n        if (cache[cacheID]) return cache[cacheID];\n\n        let texture;\n        switch (ext) {\n            case 'ktx':\n            case 'pvrtc':\n            case 's3tc':\n            case 'etc':\n            case 'etc1':\n            case 'astc':\n                // Load compressed texture using KTX format\n                texture = new KTXTexture(gl, {\n                    src,\n                    wrapS,\n                    wrapT,\n                    anisotropy,\n                    minFilter,\n                    magFilter,\n                });\n                texture.loaded = this.loadKTX(src, texture);\n                break;\n            case 'webp':\n            case 'jpg':\n            case 'jpeg':\n            case 'png':\n                texture = new Texture(gl, {\n                    wrapS,\n                    wrapT,\n                    anisotropy,\n                    format,\n                    internalFormat,\n                    generateMipmaps,\n                    minFilter,\n                    magFilter,\n                    premultiplyAlpha,\n                    unpackAlignment,\n                    flipY,\n                });\n                texture.loaded = this.loadImage(gl, src, texture, flipY);\n                break;\n            default:\n                console.warn('No supported format supplied');\n                texture = new Texture(gl);\n        }\n\n        texture.ext = ext;\n        cache[cacheID] = texture;\n        return texture;\n    }\n\n    static getSupportedExtensions(gl) {\n        if (supportedExtensions.length) return supportedExtensions;\n\n        const extensions = {\n            pvrtc: gl.renderer.getExtension('WEBGL_compressed_texture_pvrtc') || gl.renderer.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'),\n            s3tc: gl.renderer.getExtension('WEBGL_compressed_texture_s3tc'),\n            // etc: gl.renderer.getExtension('WEBGL_compressed_texture_etc'),\n            etc1: gl.renderer.getExtension('WEBGL_compressed_texture_etc1'),\n            astc: gl.renderer.getExtension('WEBGL_compressed_texture_astc'),\n            bc7: gl.renderer.getExtension('EXT_texture_compression_bptc'),\n        };\n\n        for (const ext in extensions) if (extensions[ext]) supportedExtensions.push(ext);\n\n        // Formats supported by all\n        supportedExtensions.push('png', 'jpg', 'webp');\n\n        return supportedExtensions;\n    }\n\n    static loadKTX(src, texture) {\n        return fetch(src)\n            .then((res) => res.arrayBuffer())\n            .then((buffer) => texture.parseBuffer(buffer));\n    }\n\n    static loadImage(gl, src, texture, flipY) {\n        return decodeImage(src, flipY).then((imgBmp) => {\n            // Catch non POT textures for WebGL1 and update params to avoid errors\n            if (!gl.renderer.isWebgl2 && (!powerOfTwo(imgBmp.width) || !powerOfTwo(imgBmp.height))) {\n                if (texture.generateMipmaps) texture.generateMipmaps = false;\n                if (texture.minFilter === gl.NEAREST_MIPMAP_LINEAR) texture.minFilter = gl.LINEAR;\n                if (texture.wrapS === gl.REPEAT) texture.wrapS = texture.wrapT = gl.CLAMP_TO_EDGE;\n            }\n\n            texture.image = imgBmp;\n\n            // For createImageBitmap, close once uploaded\n            texture.onUpdate = () => {\n                if (imgBmp.close) imgBmp.close();\n                texture.onUpdate = null;\n            };\n\n            return imgBmp;\n        });\n    }\n\n    static clearCache() {\n        cache = {};\n    }\n}\n\nfunction powerOfTwo(value) {\n    // (width & (width - 1)) !== 0\n    return Math.log2(value) % 1 === 0;\n}\n\nfunction decodeImage(src, flipY) {\n    return new Promise((resolve, reject) => {\n        if (isCreateImageBitmap()) {\n            fetch(src, { mode: 'cors' })\n                .then((r) => r.blob())\n                .then((b) => createImageBitmap(b, { imageOrientation: flipY ? 'flipY' : 'none', premultiplyAlpha: 'none' }))\n                .then(resolve)\n                .catch((err) => reject(err));\n        } else {\n            const img = new Image();\n\n            img.crossOrigin = '';\n            img.src = src;\n            img.onerror = ({ type }) => reject(`${type}: Loading image`);\n            img.onload = () => resolve(img);\n        }\n    });\n}\n\nfunction isCreateImageBitmap() {\n    const isChrome = navigator.userAgent.toLowerCase().includes('chrome');\n    if (!isChrome) return false;\n    try {\n        createImageBitmap;\n    } catch (e) {\n        return false;\n    }\n    return true;\n}\n","import { Vec3 } from '../math/Vec3.js';\nimport { Quat } from '../math/Quat.js';\n\nconst tmpVec3A = /* @__PURE__ */ new Vec3();\nconst tmpVec3B = /* @__PURE__ */ new Vec3();\nconst tmpVec3C = /* @__PURE__ */ new Vec3();\nconst tmpVec3D = /* @__PURE__ */ new Vec3();\n\nconst tmpQuatA = /* @__PURE__ */ new Quat();\nconst tmpQuatB = /* @__PURE__ */ new Quat();\nconst tmpQuatC = /* @__PURE__ */ new Quat();\nconst tmpQuatD = /* @__PURE__ */ new Quat();\n\nexport class GLTFAnimation {\n    constructor(data, weight = 1) {\n        this.data = data;\n        this.elapsed = 0;\n        this.weight = weight;\n\n        // Set to false to not apply modulo to elapsed against duration\n        this.loop = true;\n\n        // Find starting time as exports from blender (perhaps others too) don't always start from 0\n        this.startTime = data.reduce((a, { times }) => Math.min(a, times[0]), Infinity);\n        // Get largest final time in all channels to calculate duration\n        this.endTime = data.reduce((a, { times }) => Math.max(a, times[times.length - 1]), 0);\n        this.duration = this.endTime - this.startTime;\n    }\n\n    update(totalWeight = 1, isSet) {\n        const weight = isSet ? 1 : this.weight / totalWeight;\n        const elapsed = !this.duration\n            ? 0\n            : (this.loop ? this.elapsed % this.duration : Math.min(this.elapsed, this.duration - 0.001)) + this.startTime;\n\n        this.data.forEach(({ node, transform, interpolation, times, values }) => {\n            if (!this.duration) {\n                let val = tmpVec3A;\n                let size = 3;\n                if (transform === 'quaternion') {\n                    val = tmpQuatA;\n                    size = 4;\n                }\n                val.fromArray(values, 0);\n                if (size === 4) node[transform].slerp(val, weight);\n                else node[transform].lerp(val, weight);\n                return;\n            }\n\n            // Get index of two time values elapsed is between\n            const prevIndex =\n                Math.max(\n                    1,\n                    times.findIndex((t) => t > elapsed)\n                ) - 1;\n            const nextIndex = prevIndex + 1;\n\n            // Get linear blend/alpha between the two\n            let alpha = (elapsed - times[prevIndex]) / (times[nextIndex] - times[prevIndex]);\n            if (interpolation === 'STEP') alpha = 0;\n\n            let prevVal = tmpVec3A;\n            let prevTan = tmpVec3B;\n            let nextTan = tmpVec3C;\n            let nextVal = tmpVec3D;\n            let size = 3;\n\n            if (transform === 'quaternion') {\n                prevVal = tmpQuatA;\n                prevTan = tmpQuatB;\n                nextTan = tmpQuatC;\n                nextVal = tmpQuatD;\n                size = 4;\n            }\n\n            if (interpolation === 'CUBICSPLINE') {\n                // Get the prev and next values from the indices\n                prevVal.fromArray(values, prevIndex * size * 3 + size * 1);\n                prevTan.fromArray(values, prevIndex * size * 3 + size * 2);\n                nextTan.fromArray(values, nextIndex * size * 3 + size * 0);\n                nextVal.fromArray(values, nextIndex * size * 3 + size * 1);\n\n                // interpolate for final value\n                prevVal = this.cubicSplineInterpolate(alpha, prevVal, prevTan, nextTan, nextVal);\n                if (size === 4) prevVal.normalize();\n            } else {\n                // Get the prev and next values from the indices\n                prevVal.fromArray(values, prevIndex * size);\n                nextVal.fromArray(values, nextIndex * size);\n\n                // interpolate for final value\n                if (size === 4) prevVal.slerp(nextVal, alpha);\n                else prevVal.lerp(nextVal, alpha);\n            }\n\n            // interpolate between multiple possible animations\n            if (size === 4) node[transform].slerp(prevVal, weight);\n            else node[transform].lerp(prevVal, weight);\n        });\n    }\n\n    cubicSplineInterpolate(t, prevVal, prevTan, nextTan, nextVal) {\n        const t2 = t * t;\n        const t3 = t2 * t;\n\n        const s2 = 3 * t2 - 2 * t3;\n        const s3 = t3 - t2;\n        const s0 = 1 - s2;\n        const s1 = s3 - t2 + t;\n\n        for (let i = 0; i < prevVal.length; i++) {\n            prevVal[i] = s0 * prevVal[i] + s1 * (1 - t) * prevTan[i] + s2 * nextVal[i] + s3 * t * nextTan[i];\n        }\n\n        return prevVal;\n    }\n}\n","import { Mesh } from '../core/Mesh.js';\nimport { Mat4 } from '../math/Mat4.js';\nimport { Texture } from '../core/Texture.js';\n\nconst tempMat4 = /* @__PURE__ */ new Mat4();\nconst identity = /* @__PURE__ */ new Mat4();\n\nexport class GLTFSkin extends Mesh {\n    constructor(gl, { skeleton, geometry, program, mode = gl.TRIANGLES } = {}) {\n        super(gl, { geometry, program, mode });\n        this.skeleton = skeleton;\n        this.program = program;\n        this.createBoneTexture();\n    }\n\n    createBoneTexture() {\n        if (!this.skeleton.joints.length) return;\n        const size = Math.max(4, Math.pow(2, Math.ceil(Math.log(Math.sqrt(this.skeleton.joints.length * 4)) / Math.LN2)));\n        this.boneMatrices = new Float32Array(size * size * 4);\n        this.boneTextureSize = size;\n        this.boneTexture = new Texture(this.gl, {\n            image: this.boneMatrices,\n            generateMipmaps: false,\n            type: this.gl.FLOAT,\n            internalFormat: this.gl.renderer.isWebgl2 ? this.gl.RGBA32F : this.gl.RGBA,\n            minFilter: this.gl.NEAREST,\n            magFilter: this.gl.NEAREST,\n            flipY: false,\n            width: size,\n        });\n    }\n\n    updateUniforms() {\n        // Update bone texture\n        this.skeleton.joints.forEach((bone, i) => {\n            // Find difference between current and bind pose\n            tempMat4.multiply(bone.worldMatrix, bone.bindInverse);\n            this.boneMatrices.set(tempMat4, i * 16);\n        });\n        this.boneTexture.needsUpdate = true;\n        // Reset for programs shared between multiple skins\n        this.program.uniforms.boneTexture.value = this.boneTexture;\n        this.program.uniforms.boneTextureSize.value = this.boneTextureSize;\n    }\n\n    draw({ camera } = {}) {\n        if (!this.program.uniforms.boneTexture) {\n            Object.assign(this.program.uniforms, {\n                boneTexture: { value: this.boneTexture },\n                boneTextureSize: { value: this.boneTextureSize },\n            });\n        }\n\n        this.updateUniforms();\n\n        // Switch the world matrix with identity to ignore any transforms\n        // on the mesh itself - only use skeleton's transforms\n        const _worldMatrix = this.worldMatrix;\n        this.worldMatrix = identity;\n\n        super.draw({ camera });\n\n        // Switch back to leave identity untouched\n        this.worldMatrix = _worldMatrix;\n    }\n}\n","import { Transform } from '../core/Transform.js';\nimport { Mesh } from '../core/Mesh.js';\nimport { Vec4 } from '../math/Vec4.js';\n\nexport class InstancedMesh extends Mesh {\n    constructor(...args) {\n        super(...args);\n\n        // Skip renderer frustum culling\n        this.frustumCulled = false;\n        this.isInstancedMesh = true;\n    }\n\n    addFrustumCull() {\n        this.instanceTransforms = null;\n        this.instanceLightmapScaleOffset = null;\n        this.totalInstanceCount = 0;\n        this.frustumCullFunction = null;\n        this.instanceRenderList = null;\n\n        // Get instanced mesh\n        if (!this.geometry.attributes.instanceMatrix)\n            console.error(`mesh ${this.name ? `\"${this.name}\" ` : ``}missing instanceMatrix attribute; unable to frustum cull`);\n\n        // Make list of transforms from instanceMatrix\n        const matrixData = this.geometry.attributes.instanceMatrix.data;\n        this.instanceTransforms = [];\n        for (let i = 0, j = 0; i < matrixData.length; i += 16, j++) {\n            const transform = new Transform();\n            transform.index = j;\n            transform.matrix.fromArray(matrixData, i);\n            transform.decompose();\n            this.instanceTransforms.push(transform);\n            // Add transforms to parent to update world matrices\n            transform.setParent(this.parent);\n        }\n        this.totalInstanceCount = this.instanceTransforms.length;\n\n        // Check for lightmap attributes - attach to transform\n        if (!!this.geometry.attributes.lightmapScaleOffset) {\n            const lightmapData = this.geometry.attributes.lightmapScaleOffset.data;\n            for (let i = 0, j = 0; i < lightmapData.length; i += 4, j++) {\n                this.instanceTransforms[j].lightmapData = new Vec4().fromArray(lightmapData, i);\n            }\n        }\n\n        this.frustumCullFunction = ({ camera }) => {\n            // frustum cull transforms each frame - pass world matrix\n            this.instanceRenderList = [];\n            this.instanceTransforms.forEach((transform) => {\n                if (!camera.frustumIntersectsMesh(this, transform.worldMatrix)) return;\n                this.instanceRenderList.push(transform);\n            });\n\n            // update instanceMatrix and instancedCount with visible\n            this.instanceRenderList.forEach((transform, i) => {\n                transform.matrix.toArray(this.geometry.attributes.instanceMatrix.data, i * 16);\n\n                // Update lightmap attr\n                if (transform.lightmapData) {\n                    transform.lightmapData.toArray(this.geometry.attributes.lightmapScaleOffset.data, i * 4);\n                    this.geometry.attributes.lightmapScaleOffset.needsUpdate = true;\n                }\n            });\n            this.geometry.instancedCount = this.instanceRenderList.length;\n            this.geometry.attributes.instanceMatrix.needsUpdate = true;\n        };\n\n        this.onBeforeRender(this.frustumCullFunction);\n    }\n\n    removeFrustumCull() {\n        this.offBeforeRender(this.frustumCullFunction);\n        this.geometry.instancedCount = this.totalInstanceCount;\n        this.instanceTransforms.forEach((transform, i) => {\n            transform.matrix.toArray(this.geometry.attributes.instanceMatrix.data, i * 16);\n\n            // Update lightmap attr\n            if (transform.lightmapData) {\n                transform.lightmapData.toArray(this.geometry.attributes.lightmapScaleOffset.data, i * 4);\n                this.geometry.attributes.lightmapScaleOffset.needsUpdate = true;\n            }\n        });\n        this.geometry.attributes.instanceMatrix.needsUpdate = true;\n    }\n}\n","import { Geometry } from '../core/Geometry.js';\nimport { Transform } from '../core/Transform.js';\nimport { Texture } from '../core/Texture.js';\nimport { Mesh } from '../core/Mesh.js';\nimport { Camera } from '../core/Camera.js';\nimport { GLTFAnimation } from './GLTFAnimation.js';\nimport { GLTFSkin } from './GLTFSkin.js';\nimport { Mat4 } from '../math/Mat4.js';\nimport { Vec3 } from '../math/Vec3.js';\nimport { NormalProgram } from './NormalProgram.js';\nimport { InstancedMesh } from './InstancedMesh.js';\n\n// TODO\n// [ ] Morph targets\n// [ ] Materials\n// [ ] Sparse accessor packing? For morph targets basically\n// [ ] Option to turn off GPU instancing?\n// [ ] Spot lights\n\nconst TYPE_ARRAY = {\n    5120: Int8Array,\n    5121: Uint8Array,\n    5122: Int16Array,\n    5123: Uint16Array,\n    5125: Uint32Array,\n    5126: Float32Array,\n    'image/jpeg': Uint8Array,\n    'image/png': Uint8Array,\n    'image/webp': Uint8Array,\n};\n\nconst TYPE_SIZE = {\n    SCALAR: 1,\n    VEC2: 2,\n    VEC3: 3,\n    VEC4: 4,\n    MAT2: 4,\n    MAT3: 9,\n    MAT4: 16,\n};\n\nconst ATTRIBUTES = {\n    POSITION: 'position',\n    NORMAL: 'normal',\n    TANGENT: 'tangent',\n    TEXCOORD_0: 'uv',\n    TEXCOORD_1: 'uv2',\n    COLOR_0: 'color',\n    WEIGHTS_0: 'skinWeight',\n    JOINTS_0: 'skinIndex',\n};\n\nconst TRANSFORMS = {\n    translation: 'position',\n    rotation: 'quaternion',\n    scale: 'scale',\n};\n\nexport class GLTFLoader {\n    static setDracoManager(manager) {\n        this.dracoManager = manager;\n    }\n\n    static setBasisManager(manager) {\n        this.basisManager = manager;\n    }\n\n    static async load(gl, src) {\n        const dir = src.split('/').slice(0, -1).join('/') + '/';\n\n        // Load main description json\n        const desc = await this.parseDesc(src);\n\n        return this.parse(gl, desc, dir);\n    }\n\n    static async parse(gl, desc, dir) {\n        if (desc.asset === undefined || desc.asset.version[0] < 2)\n            console.warn('Only GLTF >=2.0 supported. Attempting to parse.');\n\n        if (desc.extensionsRequired?.includes('KHR_draco_mesh_compression') && !this.dracoManager)\n            console.warn('KHR_draco_mesh_compression extension required but no manager supplied. Use .setDracoManager()');\n\n        if (desc.extensionsRequired?.includes('KHR_texture_basisu') && !this.basisManager)\n            console.warn('KHR_texture_basisu extension required but no manager supplied. Use .setBasisManager()');\n\n        // Load buffers async\n        const buffers = await this.loadBuffers(desc, dir);\n\n        // Unbind current VAO so that new buffers don't get added to active mesh\n        gl.renderer.bindVertexArray(null);\n\n        // Create gl buffers from bufferViews\n        const bufferViews = this.parseBufferViews(gl, desc, buffers);\n\n        // Create images from either bufferViews or separate image files\n        const images = await this.parseImages(gl, desc, dir, bufferViews);\n\n        const textures = this.parseTextures(gl, desc, images);\n\n        // Just pass through material data for now\n        const materials = this.parseMaterials(gl, desc, textures);\n\n        // Fetch the inverse bind matrices for skeleton joints\n        const skins = this.parseSkins(gl, desc, bufferViews);\n\n        // Create geometries for each mesh primitive\n        const meshes = await this.parseMeshes(gl, desc, bufferViews, materials, skins);\n\n        // Create transforms, meshes and hierarchy\n        const [nodes, cameras] = this.parseNodes(gl, desc, meshes, skins, images);\n\n        // Place nodes in skeletons\n        this.populateSkins(skins, nodes);\n\n        // Create animation handlers\n        const animations = this.parseAnimations(gl, desc, nodes, bufferViews);\n\n        // Get top level nodes for each scene\n        const scenes = this.parseScenes(desc, nodes);\n        const scene = scenes[desc.scene];\n\n        // Create uniforms for scene lights (TODO: light linking?)\n        const lights = this.parseLights(gl, desc, nodes, scenes);\n\n        // Remove null nodes (instanced transforms)\n        for (let i = nodes.length; i >= 0; i--) if (!nodes[i]) nodes.splice(i, 1);\n\n        return {\n            json: desc,\n            buffers,\n            bufferViews,\n            cameras,\n            images,\n            textures,\n            materials,\n            meshes,\n            nodes,\n            lights,\n            animations,\n            scenes,\n            scene,\n        };\n    }\n\n    static parseDesc(src) {\n        return fetch(src, { mode: 'cors' })\n            .then((res) => res.arrayBuffer())\n            .then((data) => {\n                const textDecoder = new TextDecoder();\n                if (textDecoder.decode(new Uint8Array(data, 0, 4)) === 'glTF') {\n                    return this.unpackGLB(data);\n                } else {\n                    return JSON.parse(textDecoder.decode(data));\n                }\n            });\n    }\n\n    // From https://github.com/donmccurdy/glTF-Transform/blob/e4108cc/packages/core/src/io/io.ts#L32\n    static unpackGLB(glb) {\n        // Decode and verify GLB header\n        const header = new Uint32Array(glb, 0, 3);\n        if (header[0] !== 0x46546c67) {\n            throw new Error('Invalid glTF asset.');\n        } else if (header[1] !== 2) {\n            throw new Error(`Unsupported glTF binary version, \"${header[1]}\".`);\n        }\n        // Decode and verify chunk headers\n        const jsonChunkHeader = new Uint32Array(glb, 12, 2);\n        const jsonByteOffset = 20;\n        const jsonByteLength = jsonChunkHeader[0];\n        if (jsonChunkHeader[1] !== 0x4e4f534a) {\n            throw new Error('Unexpected GLB layout.');\n        }\n\n        // Decode JSON\n        const jsonText = new TextDecoder().decode(glb.slice(jsonByteOffset, jsonByteOffset + jsonByteLength));\n        const json = JSON.parse(jsonText);\n        // JSON only\n        if (jsonByteOffset + jsonByteLength === glb.byteLength) return json;\n\n        const binaryChunkHeader = new Uint32Array(glb, jsonByteOffset + jsonByteLength, 2);\n        if (binaryChunkHeader[1] !== 0x004e4942) {\n            throw new Error('Unexpected GLB layout.');\n        }\n        // Decode content\n        const binaryByteOffset = jsonByteOffset + jsonByteLength + 8;\n        const binaryByteLength = binaryChunkHeader[0];\n        const binary = glb.slice(binaryByteOffset, binaryByteOffset + binaryByteLength);\n        // Attach binary to buffer\n        json.buffers[0].binary = binary;\n        return json;\n    }\n\n    // ThreeJS GLTF Loader https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/GLTFLoader.js#L1085\n    static resolveURI(uri, dir) {\n        // Invalid URI\n        if (typeof uri !== 'string' || uri === '') return '';\n\n        // Host Relative URI\n        if (/^https?:\\/\\//i.test(dir) && /^\\//.test(uri)) {\n            dir = dir.replace(/(^https?:\\/\\/[^\\/]+).*/i, '$1');\n        }\n\n        // Absolute URI http://, https://, //\n        if (/^(https?:)?\\/\\//i.test(uri)) return uri;\n\n        // Data URI\n        if (/^data:.*,.*$/i.test(uri)) return uri;\n\n        // Blob URI\n        if (/^blob:.*$/i.test(uri)) return uri;\n\n        // Relative URI\n        return dir + uri;\n    }\n\n    static loadBuffers(desc, dir) {\n        if (!desc.buffers) return null;\n        return Promise.all(\n            desc.buffers.map((buffer) => {\n                // For GLB, binary buffer ready to go\n                if (buffer.binary) return buffer.binary;\n                const uri = this.resolveURI(buffer.uri, dir);\n                return fetch(uri, { mode: 'cors' }).then((res) => res.arrayBuffer());\n            })\n        );\n    }\n\n    static parseBufferViews(gl, desc, buffers) {\n        if (!desc.bufferViews) return null;\n        const bufferViews = desc.bufferViews;\n\n        desc.meshes &&\n            desc.meshes.forEach(({ primitives }) => {\n                primitives.forEach(({ attributes, indices, extensions }) => {\n                    // Flag bufferView as an attribute, so it knows to create a gl buffer\n                    for (const attr in attributes) {\n                        const accessor = desc.accessors[attributes[attr]];\n                        if (accessor.bufferView === undefined && !!extensions) {\n                            // Draco extension buffer view\n                            if (extensions.KHR_draco_mesh_compression) {\n                                accessor.bufferView = extensions.KHR_draco_mesh_compression.bufferView;\n                                bufferViews[accessor.bufferView].isDraco = true;\n                            }\n                        }\n                        bufferViews[accessor.bufferView].isAttribute = true;\n                    }\n\n                    if (indices !== undefined) {\n                        const accessor = desc.accessors[indices];\n                        if (accessor.bufferView === undefined && !!extensions) {\n                            // Draco extension buffer view\n                            if (extensions.KHR_draco_mesh_compression) {\n                                accessor.bufferView = extensions.KHR_draco_mesh_compression.bufferView;\n                                bufferViews[accessor.bufferView].isDraco = true;\n                            }\n                        }\n                        bufferViews[accessor.bufferView].isAttribute = true;\n\n                        // Make sure indices bufferView have a target property for gl buffer binding\n                        bufferViews[accessor.bufferView].target = gl.ELEMENT_ARRAY_BUFFER;\n                    }\n                });\n            });\n\n        // Get componentType of each bufferView from the accessors\n        desc.accessors.forEach(({ bufferView: bufferViewIndex, componentType }) => {\n            if (bufferViewIndex === undefined) return;\n            bufferViews[bufferViewIndex].componentType = componentType;\n        });\n\n        // Get mimetype of bufferView from images\n        desc.images &&\n            desc.images.forEach(({ uri, bufferView: bufferViewIndex, mimeType }) => {\n                if (bufferViewIndex === undefined) return;\n                bufferViews[bufferViewIndex].mimeType = mimeType;\n            });\n\n        // Push each bufferView to the GPU as a separate buffer\n        bufferViews.forEach(\n            (\n                {\n                    buffer: bufferIndex, // required\n                    byteOffset = 0, // optional\n                    byteLength, // required\n                    byteStride, // optional\n                    target = gl.ARRAY_BUFFER, // optional, added above for elements\n                    name, // optional\n                    extensions, // optional\n                    extras, // optional\n\n                    componentType, // optional, added from accessor above\n                    mimeType, // optional, added from images above\n                    isAttribute,\n                    isDraco,\n                },\n                i\n            ) => {\n                bufferViews[i].data = buffers[bufferIndex].slice(byteOffset, byteOffset + byteLength);\n\n                if (!isAttribute || isDraco) return;\n                // Create gl buffers for the bufferView, pushing it to the GPU\n                const buffer = gl.createBuffer();\n                gl.bindBuffer(target, buffer);\n                gl.renderer.state.boundBuffer = buffer;\n                gl.bufferData(target, bufferViews[i].data, gl.STATIC_DRAW);\n                bufferViews[i].buffer = buffer;\n            }\n        );\n\n        return bufferViews;\n    }\n\n    static parseImages(gl, desc, dir, bufferViews) {\n        if (!desc.images) return null;\n        return Promise.all(\n            desc.images.map(async ({ uri, bufferView: bufferViewIndex, mimeType, name }) => {\n                if (mimeType === 'image/ktx2') {\n                    const { data } = bufferViews[bufferViewIndex];\n                    const image = await this.basisManager.parseTexture(data);\n                    return image;\n                }\n\n                // jpg / png / webp\n                const image = new Image();\n                image.name = name;\n                if (uri) {\n                    image.src = this.resolveURI(uri, dir);\n                } else if (bufferViewIndex !== undefined) {\n                    const { data } = bufferViews[bufferViewIndex];\n                    const blob = new Blob([data], { type: mimeType });\n                    image.src = URL.createObjectURL(blob);\n                }\n                image.ready = new Promise((res) => {\n                    image.onload = () => res();\n                });\n                return image;\n            })\n        );\n    }\n\n    static parseTextures(gl, desc, images) {\n        if (!desc.textures) return null;\n        return desc.textures.map((textureInfo) => this.createTexture(gl, desc, images, textureInfo));\n    }\n\n    static createTexture(gl, desc, images, { sampler: samplerIndex, source: sourceIndex, name, extensions, extras }) {\n        if (sourceIndex === undefined && !!extensions) {\n            // WebP extension source index\n            if (extensions.EXT_texture_webp) sourceIndex = extensions.EXT_texture_webp.source;\n\n            // Basis extension source index\n            if (extensions.KHR_texture_basisu) sourceIndex = extensions.KHR_texture_basisu.source;\n        }\n\n        const image = images[sourceIndex];\n        if (image.texture) return image.texture;\n\n        const options = {\n            flipY: false,\n            wrapS: gl.REPEAT, // Repeat by default, opposed to OGL's clamp by default\n            wrapT: gl.REPEAT,\n        };\n        const sampler = samplerIndex !== undefined ? desc.samplers[samplerIndex] : null;\n        if (sampler) {\n            ['magFilter', 'minFilter', 'wrapS', 'wrapT'].forEach((prop) => {\n                if (sampler[prop]) options[prop] = sampler[prop];\n            });\n        }\n\n        // For compressed textures\n        if (image.isBasis) {\n            options.image = image;\n            options.internalFormat = image.internalFormat;\n            if (image.isCompressedTexture) {\n                options.generateMipmaps = false;\n                if (image.length > 1) this.minFilter = gl.NEAREST_MIPMAP_LINEAR;\n            }\n            const texture = new Texture(gl, options);\n            texture.name = name;\n            image.texture = texture;\n            return texture;\n        }\n\n        const texture = new Texture(gl, options);\n        texture.name = name;\n        image.texture = texture;\n        image.ready.then(() => {\n            texture.image = image;\n        });\n\n        return texture;\n    }\n\n    static parseMaterials(gl, desc, textures) {\n        if (!desc.materials) return null;\n        return desc.materials.map(\n            ({\n                name,\n                extensions,\n                extras,\n                pbrMetallicRoughness = {},\n                normalTexture,\n                occlusionTexture,\n                emissiveTexture,\n                emissiveFactor = [0, 0, 0],\n                alphaMode = 'OPAQUE',\n                alphaCutoff = 0.5,\n                doubleSided = false,\n            }) => {\n                const {\n                    baseColorFactor = [1, 1, 1, 1],\n                    baseColorTexture,\n                    metallicFactor = 1,\n                    roughnessFactor = 1,\n                    metallicRoughnessTexture,\n                    //   extensions,\n                    //   extras,\n                } = pbrMetallicRoughness;\n\n                if (baseColorTexture) {\n                    baseColorTexture.texture = textures[baseColorTexture.index];\n                    // texCoord\n                }\n                if (normalTexture) {\n                    normalTexture.texture = textures[normalTexture.index];\n                    // scale: 1\n                    // texCoord\n                }\n                if (metallicRoughnessTexture) {\n                    metallicRoughnessTexture.texture = textures[metallicRoughnessTexture.index];\n                    // texCoord\n                }\n                if (occlusionTexture) {\n                    occlusionTexture.texture = textures[occlusionTexture.index];\n                    // strength 1\n                    // texCoord\n                }\n                if (emissiveTexture) {\n                    emissiveTexture.texture = textures[emissiveTexture.index];\n                    // texCoord\n                }\n\n                return {\n                    name,\n                    extensions,\n                    extras,\n                    baseColorFactor,\n                    baseColorTexture,\n                    metallicFactor,\n                    roughnessFactor,\n                    metallicRoughnessTexture,\n                    normalTexture,\n                    occlusionTexture,\n                    emissiveTexture,\n                    emissiveFactor,\n                    alphaMode,\n                    alphaCutoff,\n                    doubleSided,\n                };\n            }\n        );\n    }\n\n    static parseSkins(gl, desc, bufferViews) {\n        if (!desc.skins) return null;\n        return desc.skins.map(\n            ({\n                inverseBindMatrices, // optional\n                skeleton, // optional\n                joints, // required\n                // name,\n                // extensions,\n                // extras,\n            }) => {\n                return {\n                    inverseBindMatrices: this.parseAccessor(inverseBindMatrices, desc, bufferViews),\n                    skeleton,\n                    joints,\n                };\n            }\n        );\n    }\n\n    static parseMeshes(gl, desc, bufferViews, materials, skins) {\n        if (!desc.meshes) return null;\n        return Promise.all(\n            desc.meshes.map(\n                async (\n                    {\n                        primitives, // required\n                        weights, // optional\n                        name, // optional\n                        extensions, // optional\n                        extras = {}, // optional - will get merged with node extras\n                    },\n                    meshIndex\n                ) => {\n                    // TODO: weights stuff?\n                    // Parse through nodes to see how many instances there are and if there is a skin attached\n                    // If multiple instances of a skin, need to create each\n                    let numInstances = 0;\n                    let skinIndices = [];\n                    let isLightmap = false;\n                    desc.nodes &&\n                        desc.nodes.forEach(({ mesh, skin, extras }) => {\n                            if (mesh === meshIndex) {\n                                numInstances++;\n                                if (skin !== undefined) skinIndices.push(skin);\n                                if (extras && extras.lightmap_scale_offset) isLightmap = true;\n                            }\n                        });\n                    let isSkin = !!skinIndices.length;\n\n                    // For skins, return array of skin meshes to account for multiple instances\n                    if (isSkin) {\n                        primitives = await Promise.all(\n                            skinIndices.map(async (skinIndex) => {\n                                return (await this.parsePrimitives(gl, primitives, desc, bufferViews, materials, 1, isLightmap)).map(({ geometry, program, mode }) => {\n                                    const mesh = new GLTFSkin(gl, { skeleton: skins[skinIndex], geometry, program, mode });\n                                    mesh.name = name;\n                                    mesh.extras = extras;\n                                    if (extensions) mesh.extensions = extensions;\n                                    // TODO: support skin frustum culling\n                                    mesh.frustumCulled = false;\n                                    return mesh;\n                                });\n                            })\n                        );\n                        // For retrieval to add to node\n                        primitives.instanceCount = 0;\n                        primitives.numInstances = numInstances;\n                    } else {\n                        primitives = (await this.parsePrimitives(gl, primitives, desc, bufferViews, materials, numInstances, isLightmap)).map(({ geometry, program, mode }) => {\n                            // InstancedMesh class has custom frustum culling for instances\n                            const meshConstructor = geometry.attributes.instanceMatrix ? InstancedMesh : Mesh;\n                            const mesh = new meshConstructor(gl, { geometry, program, mode });\n                            mesh.name = name;\n                            mesh.extras = extras;\n                            if (extensions) mesh.extensions = extensions;\n                            // Tag mesh so that nodes can add their transforms to the instance attribute\n                            mesh.numInstances = numInstances;\n                            return mesh;\n                        });\n                    }\n\n                    return {\n                        primitives,\n                        weights,\n                        name,\n                    };\n                }\n            )\n        );\n    }\n\n    static parsePrimitives(gl, primitives, desc, bufferViews, materials, numInstances, isLightmap) {\n        return Promise.all(\n            primitives.map(\n                async ({\n                    attributes, // required\n                    indices, // optional\n                    material: materialIndex, // optional\n                    mode = 4, // optional\n                    targets, // optional\n                    extensions, // optional\n                    extras, // optional\n                }) => {\n                    // TODO: materials\n                    const program = new NormalProgram(gl);\n                    if (materialIndex !== undefined) {\n                        program.gltfMaterial = materials[materialIndex];\n                    }\n\n                    const geometry = new Geometry(gl);\n                    if (extras) geometry.extras = extras;\n                    if (extensions) geometry.extensions = extensions;\n\n                    // For compressed geometry data\n                    if (extensions && extensions.KHR_draco_mesh_compression) {\n                        const bufferViewIndex = extensions.KHR_draco_mesh_compression.bufferView;\n                        const gltfAttributeMap = extensions.KHR_draco_mesh_compression.attributes;\n                        const attributeMap = {};\n                        const attributeTypeMap = {};\n                        const attributeTypeNameMap = {};\n                        const attributeNormalizedMap = {};\n\n                        for (const attr in attributes) {\n                            const accessor = desc.accessors[attributes[attr]];\n                            const attributeName = ATTRIBUTES[attr];\n                            attributeMap[attributeName] = gltfAttributeMap[attr];\n                            attributeTypeMap[attributeName] = accessor.componentType;\n                            attributeTypeNameMap[attributeName] = TYPE_ARRAY[accessor.componentType].name;\n                            attributeNormalizedMap[attributeName] = accessor.normalized === true;\n                        }\n\n                        const { data } = bufferViews[bufferViewIndex];\n                        const geometryData = await this.dracoManager.decodeGeometry(data, {\n                            attributeIds: attributeMap,\n                            attributeTypes: attributeTypeNameMap,\n                        });\n\n                        // Add each attribute result\n                        for (let i = 0; i < geometryData.attributes.length; i++) {\n                            const result = geometryData.attributes[i];\n                            const name = result.name;\n                            const data = result.array;\n                            const size = result.itemSize;\n                            const type = attributeTypeMap[name];\n                            const normalized = attributeNormalizedMap[name];\n\n                            // Create gl buffers for the attribute data, pushing it to the GPU\n                            const buffer = gl.createBuffer();\n                            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n                            gl.renderer.state.boundBuffer = buffer;\n                            gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);\n\n                            geometry.addAttribute(name, {\n                                data,\n                                size,\n                                type,\n                                normalized,\n                                buffer,\n                            });\n                        }\n\n                        // Add index attribute if found\n                        if (geometryData.index) {\n                            const data = geometryData.index.array;\n                            const size = geometryData.index.itemSize;\n\n                            // Create gl buffers for the index attribute data, pushing it to the GPU\n                            const buffer = gl.createBuffer();\n                            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n                            gl.renderer.state.boundBuffer = buffer;\n                            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, gl.STATIC_DRAW);\n\n                            geometry.addAttribute('index', {\n                                data,\n                                size,\n                                type: 5125, // Uint32Array\n                                normalized: false,\n                                buffer,\n                            });\n                        }\n                    } else {\n                        // Add each attribute found in primitive\n                        for (const attr in attributes) {\n                            geometry.addAttribute(ATTRIBUTES[attr], this.parseAccessor(attributes[attr], desc, bufferViews));\n                        }\n\n                        // Add index attribute if found\n                        if (indices !== undefined) {\n                            geometry.addAttribute('index', this.parseAccessor(indices, desc, bufferViews));\n                        }\n                    }\n\n                    // Add instanced transform attribute if multiple instances\n                    // Ignore if skin as we don't support instanced skins out of the box\n                    if (numInstances > 1) {\n                        geometry.addAttribute('instanceMatrix', {\n                            instanced: 1,\n                            size: 16,\n                            data: new Float32Array(numInstances * 16),\n                        });\n                    }\n\n                    // Always supply lightmapScaleOffset as an instanced attribute\n                    // Instanced skin lightmaps not supported\n                    if (isLightmap) {\n                        geometry.addAttribute('lightmapScaleOffset', {\n                            instanced: 1,\n                            size: 4,\n                            data: new Float32Array(numInstances * 4),\n                        });\n                    }\n\n                    return {\n                        geometry,\n                        program,\n                        mode,\n                    };\n                }\n            )\n        );\n    }\n\n    static parseAccessor(index, desc, bufferViews) {\n        // TODO: init missing bufferView with 0s\n        // TODO: support sparse\n\n        const {\n            bufferView: bufferViewIndex, // optional\n            byteOffset = 0, // optional\n            componentType, // required\n            normalized = false, // optional\n            count, // required\n            type, // required\n            min, // optional\n            max, // optional\n            sparse, // optional\n            // name, // optional\n            // extensions, // optional\n            // extras, // optional\n        } = desc.accessors[index];\n\n        const {\n            data, // attached in parseBufferViews\n            buffer, // replaced to be the actual GL buffer\n            byteOffset: bufferByteOffset = 0,\n            // byteLength, // applied in parseBufferViews\n            byteStride = 0,\n            target,\n            // name,\n            // extensions,\n            // extras,\n        } = bufferViews[bufferViewIndex];\n\n        const size = TYPE_SIZE[type];\n\n        // Parse data from joined buffers\n        const TypeArray = TYPE_ARRAY[componentType];\n        const elementBytes = TypeArray.BYTES_PER_ELEMENT;\n        const componentStride = byteStride / elementBytes;\n        const isInterleaved = !!byteStride && componentStride !== size;\n\n        let filteredData;\n\n        // Convert data to typed array for various uses (bounding boxes, raycasting, animation, merging etc)\n        if (isInterleaved) {\n            // First convert entire buffer to type\n            const typedData = new TypeArray(data, byteOffset);\n            // TODO: add length to not copy entire buffer if can help it\n            // const typedData = new TypeArray(data, byteOffset, (count - 1) * componentStride)\n\n            // Create output with length\n            filteredData = new TypeArray(count * size);\n\n            // Add element by element\n            for (let i = 0; i < count; i++) {\n                const start = componentStride * i;\n                const end = start + size;\n                filteredData.set(typedData.slice(start, end), i * size);\n            }\n        } else {\n            // Simply a slice\n            filteredData = new TypeArray(data, byteOffset, count * size);\n        }\n\n        // Return attribute data\n        return {\n            data: filteredData,\n            size,\n            type: componentType,\n            normalized,\n            buffer,\n            stride: byteStride,\n            offset: byteOffset,\n            count,\n            min,\n            max,\n        };\n    }\n\n    static parseNodes(gl, desc, meshes, skins, images) {\n        if (!desc.nodes) return null;\n        const cameras = [];\n        const nodes = desc.nodes.map(\n            ({\n                camera, // optional\n                children, // optional\n                skin: skinIndex, // optional\n                matrix, // optional\n                mesh: meshIndex, // optional\n                rotation, // optional\n                scale, // optional\n                translation, // optional\n                weights, // optional\n                name, // optional\n                extensions, // optional\n                extras, // optional\n            }) => {\n                const isCamera = camera !== undefined;\n\n                const node = isCamera ? new Camera(gl) : new Transform();\n\n                if (isCamera) {\n                    // NOTE: chose to use node's name and extras/extensions over camera\n                    const cameraOpts = desc.cameras[camera];\n                    if (cameraOpts.type === 'perspective') {\n                        const { yfov: fov, znear: near, zfar: far } = cameraOpts.perspective;\n                        node.perspective({ fov: fov * (180 / Math.PI), near, far });\n                    } else {\n                        const { xmag, ymag, znear: near, zfar: far } = cameraOpts.orthographic;\n                        node.orthographic({ near, far, left: -xmag, right: xmag, top: -ymag, bottom: ymag });\n                    }\n                    cameras.push(node);\n                }\n\n                if (name) node.name = name;\n                if (extras) node.extras = extras;\n                if (extensions) node.extensions = extensions;\n\n                // Need to attach to node as may have same material but different lightmap\n                if (extras && extras.lightmapTexture !== undefined) {\n                    extras.lightmapTexture.texture = this.createTexture(gl, desc, images, { source: extras.lightmapTexture.index });\n                }\n\n                // Apply transformations\n                if (matrix) {\n                    node.matrix.copy(matrix);\n                    node.decompose();\n                } else {\n                    if (rotation) node.quaternion.copy(rotation);\n                    if (scale) node.scale.copy(scale);\n                    if (translation) node.position.copy(translation);\n                    node.updateMatrix();\n                }\n\n                // Flags for avoiding duplicate transforms and removing unused instance nodes\n                let isInstanced = false;\n                let isFirstInstance = true;\n                let isInstancedMatrix = false;\n                let isSkin = skinIndex !== undefined;\n\n                // Add mesh if included\n                if (meshIndex !== undefined) {\n                    if (isSkin) {\n                        meshes[meshIndex].primitives[meshes[meshIndex].primitives.instanceCount].forEach((mesh) => {\n                            if (extras) Object.assign(mesh.extras, extras);\n                            mesh.setParent(node);\n                        });\n                        meshes[meshIndex].primitives.instanceCount++;\n                        // Remove properties once all instances added\n                        if (meshes[meshIndex].primitives.instanceCount === meshes[meshIndex].primitives.numInstances) {\n                            delete meshes[meshIndex].primitives.numInstances;\n                            delete meshes[meshIndex].primitives.instanceCount;\n                        }\n                    } else {\n                        meshes[meshIndex].primitives.forEach((mesh) => {\n                            if (extras) Object.assign(mesh.extras, extras);\n\n                            // Instanced mesh might only have 1\n                            if (mesh.geometry.isInstanced) {\n                                isInstanced = true;\n                                if (!mesh.instanceCount) {\n                                    mesh.instanceCount = 0;\n                                } else {\n                                    isFirstInstance = false;\n                                }\n                                if (mesh.geometry.attributes.instanceMatrix) {\n                                    isInstancedMatrix = true;\n                                    node.matrix.toArray(mesh.geometry.attributes.instanceMatrix.data, mesh.instanceCount * 16);\n                                }\n\n                                if (mesh.geometry.attributes.lightmapScaleOffset) {\n                                    mesh.geometry.attributes.lightmapScaleOffset.data.set(extras.lightmap_scale_offset, mesh.instanceCount * 4);\n                                }\n\n                                mesh.instanceCount++;\n\n                                if (mesh.instanceCount === mesh.numInstances) {\n                                    // Remove properties once all instances added\n                                    delete mesh.numInstances;\n                                    delete mesh.instanceCount;\n                                    // Flag attribute as dirty\n                                    if (mesh.geometry.attributes.instanceMatrix) {\n                                        mesh.geometry.attributes.instanceMatrix.needsUpdate = true;\n                                    }\n                                    if (mesh.geometry.attributes.lightmapScaleOffset) {\n                                        mesh.geometry.attributes.lightmapScaleOffset.needsUpdate = true;\n                                    }\n                                }\n                            }\n\n                            // For instances, only the first node will actually have the mesh\n                            if (isInstanced) {\n                                if (isFirstInstance) mesh.setParent(node);\n                            } else {\n                                mesh.setParent(node);\n                            }\n                        });\n                    }\n                }\n\n                // Reset node if instanced to not duplicate transforms\n                if (isInstancedMatrix) {\n                    // Remove unused nodes just providing an instance transform\n                    if (!isFirstInstance) return null;\n                    // Avoid duplicate transform for node containing the instanced mesh\n                    node.matrix.identity();\n                    node.decompose();\n                }\n\n                return node;\n            }\n        );\n\n        desc.nodes.forEach(({ children = [] }, i) => {\n            // Set hierarchy now all nodes created\n            children.forEach((childIndex) => {\n                if (!nodes[childIndex]) return;\n                nodes[childIndex].setParent(nodes[i]);\n            });\n        });\n\n        // Add frustum culling for instances now that instanceMatrix attribute is populated\n        meshes.forEach(({ primitives }, i) => {\n            primitives.forEach((primitive, i) => {\n                if (primitive.isInstancedMesh) primitive.addFrustumCull();\n            });\n        });\n\n        return [nodes, cameras];\n    }\n\n    static populateSkins(skins, nodes) {\n        if (!skins) return;\n        skins.forEach((skin) => {\n            skin.joints = skin.joints.map((i, index) => {\n                const joint = nodes[i];\n                joint.skin = skin;\n                joint.bindInverse = new Mat4(...skin.inverseBindMatrices.data.slice(index * 16, (index + 1) * 16));\n                return joint;\n            });\n            if (skin.skeleton) skin.skeleton = nodes[skin.skeleton];\n        });\n    }\n\n    static parseAnimations(gl, desc, nodes, bufferViews) {\n        if (!desc.animations) return null;\n        return desc.animations.map(\n            (\n                {\n                    channels, // required\n                    samplers, // required\n                    name, // optional\n                    // extensions, // optional\n                    // extras,  // optional\n                },\n                animationIndex\n            ) => {\n                const data = channels.map(\n                    ({\n                        sampler: samplerIndex, // required\n                        target, // required\n                        // extensions, // optional\n                        // extras, // optional\n                    }) => {\n                        const {\n                            input: inputIndex, // required\n                            interpolation = 'LINEAR',\n                            output: outputIndex, // required\n                            // extensions, // optional\n                            // extras, // optional\n                        } = samplers[samplerIndex];\n\n                        const {\n                            node: nodeIndex, // optional - TODO: when is it not included?\n                            path, // required\n                            // extensions, // optional\n                            // extras, // optional\n                        } = target;\n\n                        const node = nodes[nodeIndex];\n                        const transform = TRANSFORMS[path];\n                        const times = this.parseAccessor(inputIndex, desc, bufferViews).data;\n                        const values = this.parseAccessor(outputIndex, desc, bufferViews).data;\n\n                        // Store reference on node for cyclical retrieval\n                        if (!node.animations) node.animations = [];\n                        if (!node.animations.includes(animationIndex)) node.animations.push(animationIndex);\n\n                        return {\n                            node,\n                            transform,\n                            interpolation,\n                            times,\n                            values,\n                        };\n                    }\n                );\n\n                return {\n                    name,\n                    animation: new GLTFAnimation(data),\n                };\n            }\n        );\n    }\n\n    static parseScenes(desc, nodes) {\n        if (!desc.scenes) return null;\n        return desc.scenes.map(\n            ({\n                nodes: nodesIndices = [],\n                name, // optional\n                extensions,\n                extras,\n            }) => {\n                const scene = nodesIndices.reduce((map, i) => {\n                    // Don't add null nodes (instanced transforms)\n                    if (nodes[i]) map.push(nodes[i]);\n                    return map;\n                }, []);\n                scene.extras = extras;\n                return scene;\n            }\n        );\n    }\n\n    static parseLights(gl, desc, nodes, scenes) {\n        const lights = {\n            directional: [],\n            point: [],\n            spot: [],\n        };\n\n        // Update matrices on root nodes\n        scenes.forEach((scene) => scene.forEach((node) => node.updateMatrixWorld()));\n\n        // Uses KHR_lights_punctual extension\n        const lightsDescArray = desc.extensions?.KHR_lights_punctual?.lights || [];\n\n        // Need nodes for transforms\n        nodes.forEach((node) => {\n            if (!node?.extensions?.KHR_lights_punctual) return;\n            const lightIndex = node.extensions.KHR_lights_punctual.light;\n            const lightDesc = lightsDescArray[lightIndex];\n            const light = {\n                name: lightDesc.name || '',\n                color: { value: new Vec3().set(lightDesc.color || 1) },\n            };\n            // Apply intensity directly to color\n            if (lightDesc.intensity !== undefined) light.color.value.multiply(lightDesc.intensity);\n\n            switch (lightDesc.type) {\n                case 'directional':\n                    light.direction = { value: new Vec3(0, 0, 1).transformDirection(node.worldMatrix) };\n                    break;\n                case 'point':\n                    light.position = { value: new Vec3().applyMatrix4(node.worldMatrix) };\n                    light.distance = { value: lightDesc.range };\n                    light.decay = { value: 2 };\n                    break;\n                case 'spot':\n                    // TODO: support spot uniforms\n                    Object.assign(light, lightDesc);\n                    break;\n            }\n\n            lights[lightDesc.type].push(light);\n        });\n\n        return lights;\n    }\n}\n","import { Mesh } from '../core/Mesh.js';\nimport { Program } from '../core/Program.js';\nimport { Geometry } from '../core/Geometry.js';\nimport { Color } from '../math/Color.js';\n\nexport class WireMesh extends Mesh {\n    constructor(gl, { geometry, wireColor = new Color(0, 0.75, 0.5), ...meshProps } = {}) {\n        const wireProgram = new Program(gl, {\n            vertex,\n            fragment,\n            uniforms: { wireColor: { value: wireColor } },\n        });\n\n        const positionArray = geometry.attributes.position.data;\n        const indices = [];\n        const hashSet = new Set();\n\n        function addUniqueIndices(idx) {\n            for (let i = 0; i < idx.length; i += 2) {\n                if (isUniqueEdgePosition(idx[i] * 3, idx[i + 1] * 3, positionArray, hashSet)) {\n                    indices.push(idx[i], idx[i + 1]);\n                }\n            }\n        }\n\n        if (geometry.attributes.index) {\n            const idata = geometry.attributes.index.data;\n\n            for (let i = 0; i < idata.length; i += 3) {\n                // For every triangle, make three line pairs (start, end)\n                // prettier-ignore\n                addUniqueIndices([\n                    idata[i], idata[i + 1],\n                    idata[i + 1], idata[i + 2],\n                    idata[i + 2], idata[i]\n                ]);\n            }\n        } else {\n            const numVertices = Math.floor(positionArray.length / 3);\n\n            for (let i = 0; i < numVertices; i += 3) {\n                addUniqueIndices([i, i + 1, i + 1, i + 2, i + 2, i]);\n            }\n        }\n\n        const indicesTyped = indices.length > 65536 ? new Uint32Array(indices) : new Uint16Array(indices);\n        const wireGeometry = new Geometry(gl, {\n            position: { ...geometry.attributes.position },\n            index: { data: indicesTyped },\n        });\n\n        super(gl, { ...meshProps, mode: gl.LINES, geometry: wireGeometry, program: wireProgram });\n    }\n}\n\n// from https://github.com/mrdoob/three.js/blob/0c26bb4bb8220126447c8373154ac045588441de/src/geometries/WireframeGeometry.js#L116\nfunction isUniqueEdgePosition(start, end, pos, hashSet) {\n    // prettier-ignore\n    const hash1 = [\n        pos[start], pos[start + 1], pos[start + 2],\n        pos[end], pos[end + 1], pos[end + 2]\n    ].join('#');\n\n    // coincident edge\n    // prettier-ignore\n    const hash2 = [\n        pos[end], pos[end + 1], pos[end + 2],\n        pos[start], pos[start + 1], pos[start + 2]\n    ].join('#');\n\n    const oldSize = hashSet.size;\n    hashSet.add(hash1);\n    hashSet.add(hash2);\n    return hashSet.size - oldSize === 2;\n}\n\nconst vertex = /* glsl */ `\nattribute vec3 position;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nvoid main() {    \n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst fragment = /* glsl */ `\nprecision highp float;\nuniform vec3 wireColor;\n\nvoid main() {    \n    gl_FragColor = vec4(wireColor, 1.0);\n}\n`;\n","import { Mesh } from '../../core/Mesh.js';\nimport { Program } from '../../core/Program.js';\nimport { Geometry } from '../../core/Geometry.js';\nimport { Vec3 } from '../../math/Vec3.js';\n\nexport class AxesHelper extends Mesh {\n    constructor(\n        gl,\n        {\n            size = 1,\n            symmetric = false,\n            xColor = new Vec3(0.96, 0.21, 0.32),\n            yColor = new Vec3(0.44, 0.64, 0.11),\n            zColor = new Vec3(0.18, 0.52, 0.89),\n            ...meshProps\n        } = {}\n    ) {\n        const a = symmetric ? -size : 0;\n        const b = size;\n\n        // prettier-ignore\n        const vertices = new Float32Array([\n\t\t\ta, 0, 0,  b, 0, 0,\n\t\t\t0, a, 0,  0, b, 0,\n\t\t\t0, 0, a,  0, 0, b\n\t\t]);\n\n        // prettier-ignore\n        const colors = new Float32Array([\n\t\t\t...xColor,  ...xColor,\n\t\t\t...yColor,  ...yColor,\n\t\t\t...zColor,  ...zColor\n\t\t]);\n\n        const geometry = new Geometry(gl, {\n            position: { size: 3, data: vertices },\n            color: { size: 3, data: colors },\n        });\n\n        const program = new Program(gl, { vertex, fragment });\n\n        super(gl, { ...meshProps, mode: gl.LINES, geometry, program });\n    }\n}\n\nconst vertex = /* glsl */ `\nattribute vec3 position;\nattribute vec3 color;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nvarying vec3 vColor;\n\nvoid main() {    \n    vColor = color;\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst fragment = /* glsl */ `\nprecision highp float;\nvarying vec3 vColor;\n\nvoid main() {    \n    gl_FragColor = vec4(vColor, 1.0);\n}\n`;\n","import { Mesh } from '../../core/Mesh.js';\nimport { Program } from '../../core/Program.js';\nimport { Geometry } from '../../core/Geometry.js';\nimport { Vec3 } from '../../math/Vec3.js';\n\nexport class GridHelper extends Mesh {\n    constructor(gl, { size = 10, divisions = 10, color = new Vec3(0.75, 0.75, 0.75), ...meshProps } = {}) {\n        const numVertices = (size + 1) * 2 * 2;\n        const vertices = new Float32Array(numVertices * 3);\n\n        const hs = size / 2;\n        for (let i = 0; i <= divisions; i++) {\n            const t = i / divisions;\n            const o = t * size - hs;\n\n            vertices.set([o, 0, -hs, o, 0, hs], i * 12);\n            vertices.set([-hs, 0, o, hs, 0, o], i * 12 + 6);\n        }\n\n        const geometry = new Geometry(gl, {\n            position: { size: 3, data: vertices },\n        });\n\n        const program = new Program(gl, {\n            vertex,\n            fragment,\n            uniforms: {\n                color: { value: color },\n            },\n        });\n        super(gl, { ...meshProps, mode: gl.LINES, geometry, program });\n    }\n}\n\nconst vertex = /* glsl */ `\nattribute vec3 position;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nvoid main() {    \n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst fragment = /* glsl */ `\nprecision highp float;\nuniform vec3 color;\n\nvoid main() {    \n    gl_FragColor = vec4(color, 1.0);\n}\n`;\n","import { Mesh } from '../../core/Mesh.js';\nimport { Program } from '../../core/Program.js';\nimport { Geometry } from '../../core/Geometry.js';\nimport { Vec3 } from '../../math/Vec3.js';\nimport { Mat3 } from '../../math/Mat3.js';\n\nexport class VertexNormalsHelper extends Mesh {\n    constructor(object, { size = 0.1, color = new Vec3(0.86, 0.16, 0.86), ...meshProps } = {}) {\n        const gl = object.gl;\n        const nNormals = object.geometry.attributes.normal.count;\n        const positionsArray = new Float32Array(nNormals * 2 * 3);\n        const normalsArray = new Float32Array(nNormals * 2 * 3);\n        const sizeArray = new Float32Array(nNormals * 2);\n\n        const normalData = object.geometry.attributes.normal.data;\n        const positionData = object.geometry.attributes.position.data;\n        const sizeData = new Float32Array([0, size]);\n\n        for (let i = 0; i < nNormals; i++) {\n            const i6 = i * 6;\n            const i3 = i * 3;\n\n            // duplicate position and normal for line start and end point\n            const pSub = positionData.subarray(i3, i3 + 3);\n            positionsArray.set(pSub, i6);\n            positionsArray.set(pSub, i6 + 3);\n\n            const nSub = normalData.subarray(i3, i3 + 3);\n            normalsArray.set(nSub, i6);\n            normalsArray.set(nSub, i6 + 3);\n\n            sizeArray.set(sizeData, i * 2);\n        }\n\n        const geometry = new Geometry(gl, {\n            position: { size: 3, data: positionsArray },\n            normal: { size: 3, data: normalsArray },\n            size: { size: 1, data: sizeArray },\n        });\n\n        const program = new Program(gl, {\n            vertex,\n            fragment,\n            uniforms: {\n                color: { value: color },\n                worldNormalMatrix: { value: new Mat3() },\n                objectWorldMatrix: { value: object.worldMatrix },\n            },\n        });\n\n        super(gl, { ...meshProps, mode: gl.LINES, geometry, program });\n\n        this.object = object;\n    }\n\n    draw(arg) {\n        this.program.uniforms.worldNormalMatrix.value.getNormalMatrix(this.object.worldMatrix);\n        super.draw(arg);\n    }\n}\n\nconst vertex = /* glsl */ `\nattribute vec3 position;\nattribute vec3 normal;\nattribute float size;\n\nuniform mat4 viewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 objectWorldMatrix;\nuniform mat3 worldNormalMatrix;\n\nvoid main() {\n    vec3 n = normalize(worldNormalMatrix * normal) * size;\n    vec3 p = (objectWorldMatrix * vec4(position, 1.0)).xyz;\n    gl_Position = projectionMatrix * viewMatrix * vec4(p + n, 1.0);\n}\n`;\n\nconst fragment = /* glsl */ `\nprecision highp float;\nuniform vec3 color;\n\nvoid main() {    \n    gl_FragColor = vec4(color, 1.0);\n}\n`;\n","import { Mesh } from '../../core/Mesh.js';\nimport { Program } from '../../core/Program.js';\nimport { Geometry } from '../../core/Geometry.js';\nimport { Vec3 } from '../../math/Vec3.js';\nimport { Mat3 } from '../../math/Mat3.js';\n\nconst vA = /* @__PURE__ */ new Vec3();\nconst vB = /* @__PURE__ */ new Vec3();\nconst vC = /* @__PURE__ */ new Vec3();\nconst vCenter = /* @__PURE__ */ new Vec3();\nconst vNormal = /* @__PURE__ */ new Vec3();\n\nexport class FaceNormalsHelper extends Mesh {\n    constructor(object, { size = 0.1, color = new Vec3(0.15, 0.86, 0.86), ...meshProps } = {}) {\n        const gl = object.gl;\n\n        const positionData = object.geometry.attributes.position.data;\n        const sizeData = new Float32Array([0, size]);\n\n        const indexAttr = object.geometry.attributes.index;\n        const getIndex = indexAttr ? (i) => indexAttr.data[i] : (i) => i;\n        const numVertices = indexAttr ? indexAttr.data.length : Math.floor(positionData.length / 3);\n\n        const nNormals = Math.floor(numVertices / 3);\n        const positionsArray = new Float32Array(nNormals * 2 * 3);\n        const normalsArray = new Float32Array(nNormals * 2 * 3);\n        const sizeArray = new Float32Array(nNormals * 2);\n\n        for (let i = 0; i < numVertices; i += 3) {\n            vA.fromArray(positionData, getIndex(i + 0) * 3);\n            vB.fromArray(positionData, getIndex(i + 1) * 3);\n            vC.fromArray(positionData, getIndex(i + 2) * 3);\n\n            vCenter\n                .add(vA, vB)\n                .add(vC)\n                .multiply(1 / 3);\n\n            vA.sub(vA, vB);\n            vC.sub(vC, vB);\n            vNormal.cross(vC, vA).normalize();\n\n            // duplicate position and normal for line start and end point\n            const i2 = i * 2;\n            positionsArray.set(vCenter, i2);\n            positionsArray.set(vCenter, i2 + 3);\n\n            normalsArray.set(vNormal, i2);\n            normalsArray.set(vNormal, i2 + 3);\n            sizeArray.set(sizeData, (i / 3) * 2);\n        }\n\n        const geometry = new Geometry(gl, {\n            position: { size: 3, data: positionsArray },\n            normal: { size: 3, data: normalsArray },\n            size: { size: 1, data: sizeArray },\n        });\n\n        const program = new Program(gl, {\n            vertex,\n            fragment,\n            uniforms: {\n                color: { value: color },\n                worldNormalMatrix: { value: new Mat3() },\n                objectWorldMatrix: { value: object.worldMatrix },\n            },\n        });\n\n        super(gl, { ...meshProps, mode: gl.LINES, geometry, program });\n\n        this.object = object;\n    }\n\n    draw(arg) {\n        this.program.uniforms.worldNormalMatrix.value.getNormalMatrix(this.object.worldMatrix);\n        super.draw(arg);\n    }\n}\n\nconst vertex = /* glsl */ `\nattribute vec3 position;\nattribute vec3 normal;\nattribute float size;\n\nuniform mat4 viewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 objectWorldMatrix;\nuniform mat3 worldNormalMatrix;\n\nvoid main() {\n    vec3 n = normalize(worldNormalMatrix * normal) * size;\n    vec3 p = (objectWorldMatrix * vec4(position, 1.0)).xyz;\n    gl_Position = projectionMatrix * viewMatrix * vec4(p + n, 1.0);\n}\n`;\n\nconst fragment = /* glsl */ `\nprecision highp float;\nuniform vec3 color;\n\nvoid main() {    \n    gl_FragColor = vec4(color, 1.0);\n}\n`;\n","import { Texture } from '../core/Texture.js';\n\nexport class Texture3D extends Texture {\n    constructor(gl, args) {\n        super(gl, {\n            ...args,\n            target: gl.TEXTURE_3D,\n            width: args.width ? args.width : 2,\n            height: args.height ? args.height : 2,\n        });\n\n        const image = new Image();\n        image.crossOrigin = '*';\n        image.src = args.src;\n\n        image.onload = () => {\n            let canvas = document.createElement('canvas');\n            canvas.width = image.width;\n            canvas.height = image.height;\n\n            let ctx = canvas.getContext('2d');\n            ctx.scale(1, -1);\n            ctx.translate(0, -image.height);\n            ctx.drawImage(image, 0, 0);\n            const imageData = ctx.getImageData(0, 0, image.width, image.height).data;\n\n            canvas = null;\n            ctx = null;\n            let elementCount;\n\n            switch (this.format) {\n                case gl.RED:\n                    elementCount = 1;\n                    break;\n                case gl.RG:\n                    elementCount = 2;\n                    break;\n                case gl.RGB:\n                    elementCount = 3;\n                    break;\n                default:\n                    elementCount = 4;\n                    break;\n            }\n\n            const dataCount = this.width * this.height * this.length * elementCount;\n            const data = this.type === gl.UNSIGNED_BYTE ? new Uint8Array(dataCount) : new Float32Array(dataCount);\n\n            let dataIterator = 0;\n\n            for (let z = 0; z < this.length; z++) {\n                for (let y = 0; y < this.height; y++) {\n                    for (let x = 0; x < this.width; x++) {\n                        let zOffsetX = (z % args.tileCountX) * this.width;\n                        let zOffsetY = Math.floor(z / args.tileCountX) * (this.width * this.height * args.tileCountX);\n                        let index = x + zOffsetX + (y * image.width + zOffsetY);\n\n                        const r = imageData[index * 4];\n                        const g = imageData[index * 4 + 1];\n                        const b = imageData[index * 4 + 2];\n                        const a = imageData[index * 4 + 3];\n\n                        let texel = [r, g, b, a];\n\n                        for (let i = 0; i < elementCount; i++) {\n                            if (this.type === this.gl.UNSIGNED_BYTE) {\n                                data[dataIterator++] = texel[i];\n                            } else {\n                                data[dataIterator++] = texel[i] / 255;\n                            }\n                        }\n                    }\n                }\n            }\n\n            this.image = data;\n            this.needsUpdate = true;\n        };\n    }\n}\n","// Core\nexport { Geometry } from './core/Geometry.js';\nexport { Program } from './core/Program.js';\nexport { Renderer } from './core/Renderer.js';\nexport { Camera } from './core/Camera.js';\nexport { Transform } from './core/Transform.js';\nexport { Mesh } from './core/Mesh.js';\nexport { Texture } from './core/Texture.js';\nexport { RenderTarget } from './core/RenderTarget.js';\n\n// Maths\nexport { Color } from './math/Color.js';\nexport { Euler } from './math/Euler.js';\nexport { Mat3 } from './math/Mat3.js';\nexport { Mat4 } from './math/Mat4.js';\nexport { Quat } from './math/Quat.js';\nexport { Vec2 } from './math/Vec2.js';\nexport { Vec3 } from './math/Vec3.js';\nexport { Vec4 } from './math/Vec4.js';\n\n// Extras\nexport { Plane } from './extras/Plane.js';\nexport { Box } from './extras/Box.js';\nexport { Sphere } from './extras/Sphere.js';\nexport { Cylinder } from './extras/Cylinder.js';\nexport { Triangle } from './extras/Triangle.js';\nexport { Torus } from './extras/Torus.js';\nexport { Orbit } from './extras/Orbit.js';\nexport { Raycast } from './extras/Raycast.js';\nexport { Curve } from './extras/Curve.js';\nexport { Path } from './extras/path/Path.js';\nexport { Tube } from './extras/Tube.js';\nexport { Post } from './extras/Post.js';\nexport { Skin } from './extras/Skin.js';\nexport { Animation } from './extras/Animation.js';\nexport { Text } from './extras/Text.js';\nexport { NormalProgram } from './extras/NormalProgram.js';\nexport { Flowmap } from './extras/Flowmap.js';\nexport { GPGPU } from './extras/GPGPU.js';\nexport { Polyline } from './extras/Polyline.js';\nexport { Shadow } from './extras/Shadow.js';\nexport { KTXTexture } from './extras/KTXTexture.js';\nexport { TextureLoader } from './extras/TextureLoader.js';\nexport { GLTFLoader } from './extras/GLTFLoader.js';\nexport { GLTFSkin } from './extras/GLTFSkin.js';\nexport { GLTFAnimation } from './extras/GLTFAnimation.js';\nexport { DracoManager } from './extras/DracoManager.js';\nexport { BasisManager } from './extras/BasisManager.js';\nexport { WireMesh } from './extras/WireMesh.js';\nexport { AxesHelper } from './extras/helpers/AxesHelper.js';\nexport { GridHelper } from './extras/helpers/GridHelper.js';\nexport { VertexNormalsHelper } from './extras/helpers/VertexNormalsHelper.js';\nexport { FaceNormalsHelper } from './extras/helpers/FaceNormalsHelper.js';\nexport { InstancedMesh } from './extras/InstancedMesh.js';\nexport { Texture3D } from './extras/Texture3D.js';\n","import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef,useState,useCallback}from\"react\";import{Renderer,Camera,Transform,Plane,Program,Mesh,Texture}from\"https://unpkg.com/ogl\";import{defaultFragmentShader,defaultVertexShader}from\"https://framerusercontent.com/modules/MpdGPgep8CrmVuG8IclI/3flka5fkGcFUNVW00KRS/OGLUtils.js\";export default function OGLScene(props){return /*#__PURE__*/_jsx(\"div\",{});}export function useOGLScene(mountRef,media,dimensions,mediaType,options={}){const sceneRef=useRef({});const[containerSize,setContainerSize]=useState({width:0,height:0});const[isReady,setIsReady]=useState(false);const isInitializedRef=useRef(false);const initialUniformsRef=useRef(null);const resizeObserverRef=useRef(null);const{vertexShader,fragmentShader,objectFit=\"cover\",uniforms={},accessibilityOptions={}}=options;// 默认的 canvas 配置\nconst defaultAccessibilityOptions={ariaLabel:null,role:null,tabIndex:null,...accessibilityOptions};// 保存初始 uniforms，避免重复创建场景\nif(!initialUniformsRef.current){initialUniformsRef.current=JSON.parse(JSON.stringify(uniforms));}// 应用 canvas 属性的辅助函数\nconst applyCanvasAttributes=useCallback((canvas,options)=>{// 设置 aria 属性\nif(options.ariaLabel){canvas.setAttribute(\"aria-label\",options.ariaLabel);}if(options.role){canvas.setAttribute(\"role\",options.role);}if(options.tabIndex!==null&&options.tabIndex!==undefined){canvas.tabIndex=options.tabIndex;}},[]);// 手动渲染函数 - 提前定义避免循环依赖\nconst renderFrame=useCallback(()=>{const{renderer,camera,scene,texture}=sceneRef.current;texture.needsUpdate=true;renderer.render({scene,camera});},[mediaType]);// 计算平面尺寸\nconst calculatePlaneSize=useCallback((mediaWidth,mediaHeight,containerWidth,containerHeight,fitMode)=>{const mediaAspect=mediaWidth/mediaHeight;const containerAspect=containerWidth/containerHeight;let planeWidth,planeHeight;if(fitMode===\"cover\"){planeHeight=containerHeight;planeWidth=containerWidth;}else if(fitMode===\"contain\"){if(mediaAspect>containerAspect){planeWidth=containerWidth;planeHeight=containerWidth/mediaAspect;}else{planeHeight=containerHeight;planeWidth=containerHeight*mediaAspect;}}return{width:planeWidth,height:planeHeight};},[]);// 更新场景尺寸相关参数（优化：避免不必要的重建）\nconst updateSceneSize=useCallback((width,height,fitMode)=>{const{renderer,camera,mesh,program}=sceneRef.current;if(!renderer||!camera||!mesh||!program)return;// 检查尺寸是否真的发生了变化\nconst currentCanvas=renderer.gl.canvas;if(currentCanvas.width===width*renderer.dpr&&currentCanvas.height===height*renderer.dpr){return;// 尺寸没有变化，跳过更新\n}// 更新渲染器尺寸\nrenderer.setSize(width,height);// 更新相机参数\nconst distance=1e3;const fov=2*Math.atan(height/2/distance)*(180/Math.PI);camera.fov=fov;camera.aspect=width/height;camera.updateProjectionMatrix();// 更新默认 uniforms\nif(program.uniforms){if(program.uniforms.uMediaSize&&dimensions.width&&dimensions.height){program.uniforms.uMediaSize.value=[dimensions.width,dimensions.height];}if(program.uniforms.uPanelSize){program.uniforms.uPanelSize.value=[width,height];}if(program.uniforms.uFitMode){program.uniforms.uFitMode.value=fitMode===\"cover\"?1:0;console.log(program.uniforms.uFitMode.value);}}// 重新计算平面尺寸并更新几何体\nif(dimensions.width&&dimensions.height){const planeSize=calculatePlaneSize(dimensions.width,dimensions.height,width,height,objectFit);// 只有当尺寸真的不同时才更新几何体\nconst gl=renderer.gl;const newGeometry=new Plane(gl,{width:planeSize.width,height:planeSize.height});// 更新mesh的几何体\nconst oldGeometry=mesh.geometry;mesh.geometry=newGeometry;sceneRef.current.geometry=newGeometry;// 清理旧几何体（如果需要）\nif(oldGeometry&&oldGeometry!==newGeometry&&oldGeometry.dispose){oldGeometry.dispose();}}},[dimensions,calculatePlaneSize,objectFit]);// 获取容器尺寸 - 优化以避免不必要的更新\nconst updateContainerSize=useCallback(()=>{if(!mountRef.current)return;const newWidth=mountRef.current.clientWidth;const newHeight=mountRef.current.clientHeight;// 只有当尺寸真的发生变化时才更新状态\nsetContainerSize(prevSize=>{if(prevSize.width!==newWidth||prevSize.height!==newHeight){return{width:newWidth,height:newHeight};}return prevSize;});},[mountRef]);// 监听容器尺寸变化 - 优化ResizeObserver\nuseEffect(()=>{updateContainerSize();// 清理之前的观察器\nif(resizeObserverRef.current){resizeObserverRef.current.disconnect();}if(mountRef.current){resizeObserverRef.current=new ResizeObserver(entries=>{// 使用entries直接获取尺寸，避免重复测量\nfor(const entry of entries){const{width,height}=entry.contentRect;setContainerSize(prevSize=>{if(prevSize.width!==width||prevSize.height!==height){return{width,height};}return prevSize;});}});resizeObserverRef.current.observe(mountRef.current);}return()=>{if(resizeObserverRef.current){resizeObserverRef.current.disconnect();}};},[mountRef]);// 初始化场景（只执行一次）\nuseEffect(()=>{if(!mountRef.current||containerSize.width===0||containerSize.height===0||isInitializedRef.current)return;let renderer,camera,scene,program,mesh,texture,geometry;const init=async()=>{const{width,height}=containerSize;// 创建渲染器\nrenderer=new Renderer({width,height,dpr:Math.min(window.devicePixelRatio,2),alpha:true,premultipliedAlpha:false});const gl=renderer.gl;// 清空容器并添加canvas\nmountRef.current.innerHTML=\"\";mountRef.current.appendChild(gl.canvas);// 设置canvas样式\ngl.canvas.style.width=\"100%\";gl.canvas.style.height=\"100%\";gl.canvas.style.display=\"block\";applyCanvasAttributes(gl.canvas,defaultAccessibilityOptions);gl.clearColor(0,0,0,0);gl.enable(gl.BLEND);gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);// 计算相机参数\nconst distance=1e3;const fov=2*Math.atan(height/2/distance)*(180/Math.PI);// 创建相机\ncamera=new Camera(gl,{fov:fov,aspect:width/height,near:1,far:2e3});camera.position.set(0,0,distance);// 创建场景\nscene=new Transform;// 创建纹理\nconst generateMipmaps=mediaType===\"video\"?false:true;texture=new Texture(gl,{minFilter:generateMipmaps?gl.LINEAR_MIPMAP_LINEAR:gl.LINEAR,magFilter:gl.LINEAR,generateMipmaps:generateMipmaps,premultiplyAlpha:false,unpackAlignment:1,wrapS:gl.CLAMP_TO_EDGE,wrapT:gl.CLAMP_TO_EDGE,format:gl.RGBA,internalFormat:gl.RGBA});// 如果有初始媒体，设置到纹理\nif(media){texture.image=media;}// 计算平面尺寸\nconst planeSize=calculatePlaneSize(dimensions.width||width,dimensions.height||height,width,height,objectFit);// 创建着色器程序\nprogram=new Program(gl,{vertex:vertexShader||defaultVertexShader,fragment:fragmentShader||defaultFragmentShader,uniforms:{uTexture:{value:texture},uMediaSize:{value:[dimensions.width||width,dimensions.height||height]},uPanelSize:{value:[width,height]},uFitMode:{value:objectFit===\"cover\"?1:0},...initialUniformsRef.current},transparent:true,cullFace:null});// 创建几何体\ngeometry=new Plane(gl,{width:planeSize.width,height:planeSize.height});// 创建网格\nmesh=new Mesh(gl,{geometry,program});mesh.setParent(scene);// 存储场景对象\nsceneRef.current={renderer,camera,scene,program,mesh,texture,geometry,gl,updateUniforms:newUniforms=>{Object.keys(newUniforms).forEach(key=>{if(program.uniforms[key]){program.uniforms[key].value=newUniforms[key];}});}};isInitializedRef.current=true;setIsReady(true);};init();// 清理函数\nreturn()=>{// 清理事件监听器\nif(renderer){const gl=renderer.gl;if(gl.canvas&&gl.canvas.parentNode){gl.canvas.parentNode.removeChild(gl.canvas);}const loseContext=gl.getExtension(\"WEBGL_lose_context\");if(loseContext){loseContext.loseContext();}}// 清理引用\nsceneRef.current={};isInitializedRef.current=false;setIsReady(false);};},[media,vertexShader,fragmentShader,objectFit]);// 处理容器尺寸变化\nuseEffect(()=>{if(isInitializedRef.current&&containerSize.width>0&&containerSize.height>0){updateSceneSize(containerSize.width,containerSize.height,objectFit);}},[containerSize,updateSceneSize]);return{sceneRef:sceneRef.current,containerSize,renderFrame,isReady};}\nexport const __FramerMetadata__ = {\"exports\":{\"useOGLScene\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"reactComponent\",\"name\":\"OGLScene\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}","/*\n * UseOGLScene\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/Qdd3eGacdk0a7XalD9lO/LmjERPAe2BydyHLwJYQM/UseOGLScene.js\"\nexport { default } from \"https://framerusercontent.com/modules/Qdd3eGacdk0a7XalD9lO/LmjERPAe2BydyHLwJYQM/UseOGLScene.js\"\n","import{CompatibleMedia,degToRad,propertyControls,useDarkMode,useMediaSource}from\"https://framer.com/m/GLUtils-cYf4.js\";import{calculatePlaneSize,defaultFragmentShader,defaultVertexShader}from\"https://framer.com/m/OGLUtils-LEvG.js\";import{useVariantValues}from\"https://framer.com/m/UseVariantValue-mxjI.js\";import{useAnimatedProgress,useAnimatedValues}from\"https://framer.com/m/UseAnimatedValue-6Bkx.js\";import{useMedia}from\"https://framer.com/m/UseMedia-AW14.js\";import{useOGLScene}from\"https://framer.com/m/UseOGLScene-gg2G.js\";/**\n * GLUtils Tool\n *\n */export{CompatibleMedia,degToRad,propertyControls,useDarkMode,useMediaSource,};/**\n * OGLUtils Tools\n *\n */export{calculatePlaneSize,defaultFragmentShader,defaultVertexShader};/**\n * Variant Value Tools\n *\n */export{useVariantValues};/**\n * Animated Value Tools\n *\n */export{useAnimatedProgress,useAnimatedValues};/**\n * Media Tools\n *\n */export{useMedia};/**\n * Main OGLScene Setup\n *\n */export{useOGLScene};\nexport const __FramerMetadata__ = {\"exports\":{\"propertyControls\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"degToRad\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"CompatibleMedia\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useAnimatedValues\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useMediaSource\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useDarkMode\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useOGLScene\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useMedia\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultFragmentShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"calculatePlaneSize\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useVariantValues\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultVertexShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useAnimatedProgress\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./UseSetup.map","export const vertexShader=`\n    precision mediump float;\n    attribute vec3 position;\n    attribute vec2 uv;\n    uniform mat4 modelViewMatrix;\n    uniform mat4 projectionMatrix;\n    uniform vec2 uMediaSize;\n    uniform vec2 uPanelSize;\n    uniform int uFitMode; // 0: contain, 1: cover\n    varying vec2 vUv;\n    varying vec2 vTextureCoord; \n    \n    void main() {\n        vUv = uv;\n        \n        if (uFitMode == 1) {\n            vec2 ratio = vec2(\n                min((uPanelSize.x / uPanelSize.y) / (uMediaSize.x / uMediaSize.y), 1.0),\n                min((uPanelSize.y / uPanelSize.x) / (uMediaSize.y / uMediaSize.x), 1.0)\n            );\n            vTextureCoord = (uv - 0.5) * ratio + 0.5;\n        } else {\n            vTextureCoord = uv;\n        }\n        \n        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n    }\n`;export const fragmentShader=`\n    precision mediump float;\n    uniform sampler2D uTexture;\n    uniform vec2 uMediaSize;\n    uniform vec2 uPanelSize;\n    uniform float uTime;\n    \n    uniform float uBlur;           // 模糊强度 (0.0 - 500.0+)\n    uniform float uFalloff;        // 模糊衰减强度 (0.0 - 5.0)\n    uniform float uFalloffType;    // 衰减类型 (0.0:smoothstep, 1.0:二次, 2.0:三次, 3.0:平方根)\n    uniform float uAngle;          // 模糊方向角度 (弧度)\n    uniform vec2 uCenter;          // 参考中心点 (0.0 - 1.0)\n    uniform float uDispersion;     // 色散强度 (0.0 - 5.0)\n    uniform float uNoise;          // 噪点强度 (0.0 - 1.0)\n    uniform float uNoiseBlend;     // 噪点混合模式 (0:无混合, 1:亮色混合, 2:暗色混合, 3:亮暗混合)\n    uniform float uScale;          // 纹理缩放 (0.5 = 凹陷, 1.0 = 无变化, 2.0 = 凸起)\n    uniform vec2 uOrigin;          // falloff起点偏移 (0.0 - 1.0)\n\n    varying vec2 vUv;\n    varying vec2 vTextureCoord;\n    \n    // 常量优化\n    const float PI2 = 6.28318530718;\n    const int SAMPLES = 24; // 从32减少到24，性能提升约25%\n    const float INV_SAMPLES = 1.0 / float(SAMPLES);\n    const vec3 LUMA_WEIGHTS = vec3(0.299, 0.587, 0.114);\n    const float MAX_DIST = 0.70710678118; // sqrt(0.5)\n    \n    // 快速伪随机函数（优化版）\n    float rand(vec2 co) {\n        return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n    }\n    \n    // 优化的噪点函数\n    float noise(vec2 uv, float time) {\n        return rand(uv + time * 0.1) * 2.0 - 1.0;\n    }\n    \n    // 径向缩放变换（优化版）\n    vec2 applyRadialScale(vec2 uv, float scale) {\n        vec2 fromCenter = uv - 0.5;\n        float distance = length(fromCenter);\n        \n        if (distance < 0.001) return uv;\n        \n        float normalizedDistance = distance * 1.41421356237; // 1/MAX_DIST\n        float transformedDistance = pow(normalizedDistance, scale) * MAX_DIST;\n        \n        return 0.5 + normalize(fromCenter) * transformedDistance;\n    }\n    \n    // 噪点亮度因子计算（优化版）\n    float calculateNoiseLuminanceFactor(float luminance, int blendMode) {\n        if (blendMode == 0) return 1.0;\n        \n        float smoothLum = smoothstep(0.2, 0.8, luminance);\n        \n        if (blendMode == 1) {\n            return 1.0 - smoothLum * smoothLum;\n        } else if (blendMode == 2) {\n            return smoothLum * smoothLum;\n        } else if (blendMode == 3) {\n            float centerBias = 1.0 - abs(luminance - 0.5) * 2.0;\n            return max(pow(centerBias, 1.5), 0.1);\n        }\n        \n        return 1.0;\n    }\n    \n    // 衰减函数（优化版）\n    float applyFalloff(float t, int falloffType) {\n        if (falloffType == 1) return t * t;\n        if (falloffType == 2) return t * t * t;\n        if (falloffType == 3) return sqrt(t);\n        return smoothstep(0.0, 1.0, t);\n    }\n    \n    void main() {\n        // 早期退出检查\n        if (uBlur <= 0.0) {\n            gl_FragColor = texture2D(uTexture, vTextureCoord);\n            return;\n        }\n        \n        // 预计算常量\n        vec2 scaledTextureCoord = applyRadialScale(vTextureCoord, 1.0 + uScale * 0.2);\n        vec2 gradientDirection = vec2(cos(uAngle), sin(uAngle));\n        \n        // 衰减计算（优化版）\n        vec2 fromOrigin = vUv - uOrigin;\n        float projectionOnGradient = dot(fromOrigin, gradientDirection);\n        float falloffDistance = clamp(max(projectionOnGradient, 0.0) / 0.7, 0.0, 1.0);\n        \n        int falloffType = int(uFalloffType + 0.5);\n        float falloffCurve = applyFalloff(falloffDistance, falloffType);\n        float reversedFalloff = 1.0 - falloffCurve;\n        float blurStrength = mix(uBlur, reversedFalloff * uBlur, clamp(uFalloff, 0.0, 1.0));\n        \n        // 预计算采样参数\n        float dispersionFalloffStrength = mix(uDispersion, reversedFalloff * uDispersion, clamp(uFalloff, 0.0, 1.0));\n        float dispersionStrength = dispersionFalloffStrength * blurStrength * 0.5;\n        vec2 texelSize = 1.0 / uMediaSize;\n        vec2 panelTexelRatio = uPanelSize / uMediaSize;\n        float baseRadius = blurStrength * max(texelSize.x, texelSize.y) * max(panelTexelRatio.x, panelTexelRatio.y) * 0.5;\n        vec2 dispersionDirection = vec2(-sin(uAngle), cos(uAngle));\n        \n        // 预计算色散偏移\n        vec2 redOffset = dispersionDirection * dispersionStrength * texelSize * -0.7;\n        vec2 blueOffset = dispersionDirection * dispersionStrength * texelSize * 0.7;\n        \n        // 优化的采样循环\n        vec3 channelColors = vec3(0.0);\n        float totalWeight = 0.0;\n        \n        // 噪点参数预计算\n        bool hasNoise = uNoise > 0.0;\n        float noiseInfluence = uNoise * 0.3;\n        \n        for (int i = 0; i < SAMPLES; i++) {\n            float fi = float(i);\n            float angle = fi * INV_SAMPLES * PI2;\n            vec2 circleDir = vec2(cos(angle), sin(angle));\n            \n            // 随机偏移计算\n            float randomOffset = rand(vec2(fi, vUv.x + vUv.y)) * 0.5 + 0.5;\n            \n            if (hasNoise) {\n                float noiseValue = noise(vUv + vec2(fi * 0.1), uTime);\n                randomOffset += noiseValue * noiseInfluence;\n            }\n            randomOffset = clamp(randomOffset, 0.1, 1.0);\n            \n            vec2 baseSampleOffset = circleDir * baseRadius * randomOffset;\n            \n            // 权重计算\n            float baseWeight = 1.0 - smoothstep(0.0, 1.0, length(baseSampleOffset) / baseRadius);\n            \n            if (hasNoise) {\n                float weightNoise = noise(vUv + vec2(fi * 0.05), uTime * 0.5);\n                baseWeight *= (1.0 + weightNoise * uNoise * 0.2);\n            }\n            baseWeight = max(baseWeight, 0.0);\n            \n            // RGB通道采样（合并到单次计算）\n            vec2 sampleCoord = clamp(scaledTextureCoord + baseSampleOffset, 0.0, 1.0);\n            vec4 centerSample = texture2D(uTexture, sampleCoord);\n            vec4 redSample = texture2D(uTexture, clamp(sampleCoord + redOffset, 0.0, 1.0));\n            vec4 blueSample = texture2D(uTexture, clamp(sampleCoord + blueOffset, 0.0, 1.0));\n            \n            float weight = baseWeight;\n            channelColors.r += redSample.r * redSample.a * weight;\n            channelColors.g += centerSample.g * centerSample.a * weight;\n            channelColors.b += blueSample.b * blueSample.a * weight;\n            totalWeight += weight;\n        }\n        \n        // 归一化\n        vec4 fallbackColor = texture2D(uTexture, scaledTextureCoord);\n        channelColors = (totalWeight > 0.0) ? channelColors / totalWeight : fallbackColor.rgb * fallbackColor.a;\n        \n        // 噪点处理（优化版）\n        if (hasNoise) {\n            float finalNoise = noise(vUv * 10.0, uTime * 2.0);\n            float luminance = dot(channelColors, LUMA_WEIGHTS);\n            \n            float noiseStrength = uNoise;\n            int blendMode = int(uNoiseBlend + 0.5);\n            \n            if (blendMode > 0) {\n                float luminanceFactor = calculateNoiseLuminanceFactor(luminance, blendMode);\n                noiseStrength *= luminanceFactor;\n            }\n            \n            // 特殊处理亮暗混合模式\n            float adjustedNoise = finalNoise;\n            if (blendMode == 3) {\n                if (luminance > 0.8) {\n                    adjustedNoise = abs(finalNoise) * sign(finalNoise) * 0.3;\n                } else if (luminance < 0.2) {\n                    adjustedNoise *= 0.5;\n                }\n            }\n            \n            vec3 noiseContribution = vec3(adjustedNoise * noiseStrength * 0.1);\n            channelColors = clamp(channelColors + noiseContribution, 0.0, 1.0);\n        }\n        \n        float finalAlpha = max(fallbackColor.a, (blurStrength > 0.0) ? min(blurStrength * 0.01, 1.0) : 0.0);\n        gl_FragColor = vec4(channelColors, finalAlpha);\n    }\n`;\nexport const __FramerMetadata__ = {\"exports\":{\"vertexShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"fragmentShader\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Shaders.map","import{jsx as _jsx}from\"react/jsx-runtime\";import{useRef,useEffect,useMemo}from\"react\";import{useIsStaticRenderer}from\"framer\";import{useAnimationFrame}from\"framer-motion\";import{vertexShader,fragmentShader}from\"https://framerusercontent.com/modules/jypow408LDgPDnL677k2/Dg0auyGnIrsdg2LBcXmt/Shaders.js\";import{degToRad,useAnimatedProgress,useAnimatedValues,useMedia,useOGLScene,useVariantValues}from\"https://framerusercontent.com/modules/mSJ52dBkVivlfYMsRpwj/z319KePspYG0E1KkmAJd/UseSetup.js\";export const OGLScene=({imageAlt,mediaSrc,mediaType,loop,fit,blur,angle,falloff,advance,animateProp,transitionProp,accessibility,ariaLabel,onLoad,onError,onVideoEnd,onAnimationComplete})=>{const mountRef=useRef(null);const isStaticRenderer=useIsStaticRenderer();const{media,dimensions,isLoaded,isError,isVideoPlaying,playVideo,pauseVideo}=useMedia(mediaSrc,mediaType,loop,!isStaticRenderer);const{sceneRef,renderFrame,containerSize,isReady}=useOGLScene(mountRef,media,dimensions,mediaType,{autoStart:false,vertexShader,fragmentShader,objectFit:fit,uniforms:{uBlur:{value:blur},uAngle:{value:degToRad(angle)},uFalloff:{value:falloff},uFalloffType:{value:advance.falloffType},uScale:{value:advance.scale},uDispersion:{value:advance.dispersion},uNoise:{value:advance.noise},uNoiseBlend:{value:advance.noiseBlend},uOrigin:{value:[advance.originX,advance.originY]}},accessibilityOptions:{ariaLabel:accessibility.enableAria?ariaLabel:mediaType===\"video\"?\"\":imageAlt,role:mediaType===\"video\"?\"video\":\"img\",tabIndex:null}});// 在属性变化时，在 Framer Canvas 上进行一次渲染\nuseEffect(()=>{if(!isStaticRenderer||!isLoaded||!isReady)return;if(sceneRef.renderer){sceneRef.updateUniforms({uBlur:blur,uAngle:degToRad(angle),uFalloff:falloff,uFalloffType:advance.falloffType,uScale:advance.scale,uDispersion:advance.dispersion,uNoise:advance.noise,uNoiseBlend:advance.noiseBlend,uOrigin:[advance.originX,advance.originY]});renderFrame();}},[isLoaded,isReady,sceneRef,fit,blur,angle,falloff,advance,containerSize,isStaticRenderer]);// 在媒体类型和来源变化时，在 Framer Canvas 上进行一次渲染\nuseEffect(()=>{if(!isStaticRenderer||!isLoaded)return;if(sceneRef.renderer){renderFrame();const timeoutId=setTimeout(()=>{renderFrame();},300);return()=>{clearTimeout(timeoutId);};}},[isLoaded,isStaticRenderer]);// 配置自定义动画参数，只有当 animateProp.custom.enable 启用时才生效\nconst animationConfig=useMemo(()=>({blur:{from:blur,to:animateProp.custom.blur},angle:{from:angle,to:animateProp.custom.angle},falloff:{from:falloff,to:animateProp.custom.falloff},scale:{from:advance.scale,to:animateProp.custom.scale},dispersion:{from:advance.dispersion,to:animateProp.custom.dispersion},noise:{from:advance.noise,to:animateProp.custom.noise}}),[blur,angle,falloff,advance,animateProp.custom]);const customEnable=animateProp.custom.enable;const transition=useMemo(()=>({...transitionProp}),[transitionProp]);// 进度动画，适用于 appear\\enter\\transform\nconst{progress,isUpdatingProgress}=useAnimatedProgress(animateProp,transition,mountRef,!customEnable);// 自定义动画，适用于 appear\\enter\\transform\nconst{values,isUpdating}=useAnimatedValues(animationConfig,animateProp,transition,mountRef,customEnable);// 自定义动画，适用于 variant\nconst variantConfig=useMemo(()=>({blur:blur,angle:angle,falloff:falloff,dispersion:advance.dispersion,scale:advance.scale,noise:advance.noise,originX:advance.originX,originY:advance.originY}),[blur,angle,falloff,advance]);const{variantValue,isVariantUpdating}=useVariantValues(variantConfig,transition,animateProp.type===\"variant\");// 为 uniforms 选择更新模式\nconst calculateCustomUniforms=useMemo(()=>{// variant 模式：使用固定的基础值，但仍然是动画值\nif(animateProp.type===\"variant\"){return values=>({uBlur:variantValue.blur.get(),uAngle:degToRad(variantValue.angle.get()),uFalloff:variantValue.falloff.get(),uDispersion:variantValue.dispersion.get(),uScale:variantValue.scale.get(),uNoise:variantValue.noise.get(),uOrigin:[variantValue.originX.get(),variantValue.originY.get()]});}// 非 variant 时，根据 customEnable 决定\nif(customEnable){// custom 模式：使用 values 中的动画值\nreturn values=>({uBlur:values.blur,uAngle:degToRad(values.angle),uNoise:values.noise,uFalloff:values.falloff,uScale:values.scale,uDispersion:values.dispersion,uOrigin:[values.originX,values.originY]});}else{// progress 模式：使用基础值乘以进度\nreturn(_,progress)=>({uBlur:blur*progress,uScale:advance.scale*progress});}},[animateProp.type,customEnable,blur,angle,falloff,advance]);// 在最终页面上尺寸变化时、媒体载入时进行一次渲染\nuseEffect(()=>{if(isStaticRenderer||!isLoaded||!isReady)return;if(sceneRef.renderer){renderFrame();}if(onLoad&&typeof onLoad===\"function\"){onLoad();}},[isLoaded,isReady,sceneRef,containerSize,isStaticRenderer,onLoad]);// 在最终页面上尺寸变化时进行渲染\nuseAnimationFrame(time=>{if(isStaticRenderer||!isLoaded||!isReady)return;if(sceneRef.renderer){const shouldUpdate=advance.render===\"always\"||animateProp.type===\"variant\"||isUpdating||isUpdatingProgress||isVideoPlaying;if(shouldUpdate){sceneRef.updateUniforms(calculateCustomUniforms(values,progress));renderFrame();}}});// 在最终页面上触发事件\nconst prevStateRef=useRef({isError,isVideoPlaying,isUpdating,isUpdatingProgress,isVariantUpdating});useEffect(()=>{if(isStaticRenderer)return;if(isError&&!prevStateRef.current.isError&&onError&&typeof onError===\"function\"){onError();}prevStateRef.current.isError=isError;},[isStaticRenderer,isError,onError]);useEffect(()=>{if(isStaticRenderer)return;if(!isVideoPlaying&&prevStateRef.current.isVideoPlaying&&onVideoEnd&&typeof onVideoEnd===\"function\"){onVideoEnd();}prevStateRef.current.isVideoPlaying=isVideoPlaying;},[isStaticRenderer,isVideoPlaying,onVideoEnd]);useEffect(()=>{if(isStaticRenderer)return;const allCurrentlyFalse=!isUpdating&&!isUpdatingProgress&&!isVariantUpdating;const prevHadTrueValue=prevStateRef.current.isUpdating||prevStateRef.current.isUpdatingProgress||prevStateRef.current.isVariantUpdating;if(allCurrentlyFalse&&prevHadTrueValue&&onAnimationComplete&&typeof onAnimationComplete===\"function\"){onAnimationComplete();}prevStateRef.current.isUpdating=isUpdating;prevStateRef.current.isUpdatingProgress=isUpdatingProgress;prevStateRef.current.isVariantUpdating=isVariantUpdating;},[isStaticRenderer,isUpdating,isUpdatingProgress,isVariantUpdating,onAnimationComplete]);return /*#__PURE__*/_jsx(\"div\",{ref:mountRef,style:{width:\"100%\",height:\"100%\",position:\"relative\",overflow:\"hidden\"}});};\nexport const __FramerMetadata__ = {\"exports\":{\"OGLScene\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}","/*\n * Unfocused+ was created by Jayzhushi. Visit Reveals.cool to learn more.\n * For assistance, contact x.com/jayzhushi or email jayzhushi@gmail.com.\n * This component is licensed under the BSD License.\n */import{jsx as _jsx}from\"react/jsx-runtime\";import{ControlType,addPropertyControls,useReducedMotion}from\"framer\";import{CompatibleMedia,propertyControls,useMediaSource}from\"https://framerusercontent.com/modules/mSJ52dBkVivlfYMsRpwj/z319KePspYG0E1KkmAJd/UseSetup.js\";import{OGLScene}from\"https://framerusercontent.com/modules/7zxjrN9X6oe3IFas7UpS/imR8plZxz6TwO8xlwuod/OGL.js\";/**\n *\n * @framerIntrinsicWidth 600\n * @framerIntrinsicHeight 800\n *\n * @framerDisableUnlink\n *\n * @framerSupportedLayoutWidth fixed\n * @framerSupportedLayoutHeight fixed\n *\n */function Unfocused({type,file,upImage,urlVideo,upVideo,defaultImage,dark,darkImage,loop,fit,blur,angle,falloff,advance,animateProp,transition,accessibility,ariaLabel,onLoad,onError,onVideoEnd,onAnimationComplete}){const{imageAlt,mediaSrc,mediaType}=useMediaSource(type,file,urlVideo,upVideo,defaultImage,darkImage,dark,\"arch_dark\");const shouldReduceMotion=useReducedMotion();if(accessibility.compatibility||accessibility.reduce&&shouldReduceMotion){return /*#__PURE__*/_jsx(CompatibleMedia,{mediaType:mediaType,mediaSrc:mediaSrc,imageAlt:imageAlt,fit:fit,loop:loop});}return /*#__PURE__*/_jsx(OGLScene,{mediaType:mediaType,mediaSrc:mediaSrc,imageAlt:imageAlt,loop:loop,fit:fit,blur:blur,angle:angle,falloff:falloff,advance:advance,animateProp:animateProp,transitionProp:transition,accessibility:accessibility,ariaLabel:ariaLabel,onLoad:onLoad,onError:onError,onVideoEnd:onVideoEnd,onAnimationComplete:onAnimationComplete});}export default Unfocused;Unfocused.displayName=\"Unfocused+\";addPropertyControls(Unfocused,{...propertyControls.media,...propertyControls.size,blur:{type:ControlType.Number,title:\"Blur\",displayStepper:false,step:1,max:1e3,min:0,defaultValue:200},angle:{type:ControlType.Number,title:\"Angle\",displayStepper:false,step:1,max:360,min:0,unit:\"\\xb0\",defaultValue:45},falloff:{type:ControlType.Number,title:\"Falloff\",displayStepper:false,step:.1,max:1,min:0,defaultValue:1},advance:{type:ControlType.Object,title:\"Advance\",buttonTitle:\"Advance\",icon:\"effect\",controls:{falloffType:{type:ControlType.Enum,title:\"Type\",options:[0,1,2,3],optionTitles:[\"Linear\",\"Quadratic\",\"Cubic\",\"Square\"],defaultValue:0},originX:{type:ControlType.Number,title:\"Origin X\",displayStepper:true,step:.1,max:1,min:0,defaultValue:0},originY:{type:ControlType.Number,title:\"Origin Y\",displayStepper:true,step:.1,max:1,min:0,defaultValue:.5},scale:{type:ControlType.Number,title:\"Distortion\",displayStepper:true,step:.1,max:1,min:-1,defaultValue:0},dispersion:{type:ControlType.Number,title:\"Dispersion\",displayStepper:true,step:.1,max:1,min:0,defaultValue:.2,description:\"Affected by *Blur*.\"},noise:{type:ControlType.Number,title:\"Noise\",displayStepper:true,step:.1,max:1,min:0,defaultValue:1},noiseBlend:{type:ControlType.Enum,title:\"Blend\",options:[0,1,2,3],optionTitles:[\"None\",\"Lighter\",\"Darker\",\"Both\"],defaultValue:0,hidden(props){return props.noise===0;}}}},animateProp:{type:ControlType.Object,title:\"Animation\",buttonTitle:\"Animation\",icon:\"interaction\",controls:{...propertyControls.animateControls,custom:{type:ControlType.Object,title:\"Custom\",buttonTitle:\"Custom\",icon:\"effect\",hidden(props){return props.type===\"disable\"||props.type===\"variant\";},controls:{enable:{type:ControlType.Boolean,title:\"Enable\",defaultValue:false,description:\"Customize the animation target value for each property.\"},blur:{type:ControlType.Number,title:\"Blur\",displayStepper:false,step:1,max:1e3,min:0,defaultValue:40,hidden(props){return!props.enable;}},angle:{type:ControlType.Number,title:\"Angle\",displayStepper:false,step:1,max:360,min:0,unit:\"\\xb0\",defaultValue:0,hidden(props){return!props.enable;}},falloff:{type:ControlType.Number,title:\"Falloff\",displayStepper:false,step:.1,max:1,min:0,defaultValue:1,hidden(props){return!props.enable;}},scale:{type:ControlType.Number,title:\"Distortion\",displayStepper:true,step:.1,max:1,min:-1,defaultValue:0},dispersion:{type:ControlType.Number,title:\"Dispersion\",displayStepper:true,step:.1,max:1,min:0,defaultValue:.2,hidden(props){return!props.enable;}},noise:{type:ControlType.Number,title:\"Noise\",displayStepper:true,step:.1,max:1,min:0,defaultValue:1,hidden(props){return!props.enable;}}}}}},transition:{type:ControlType.Transition,title:\"Transition\",defaultValue:{ease:\"linear\",duration:2}},...propertyControls.accessibility,...propertyControls.eventHandler});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"Unfocused\",\"slots\":[],\"annotations\":{\"framerIntrinsicWidth\":\"600\",\"framerContractVersion\":\"1\",\"framerSupportedLayoutWidth\":\"fixed\",\"framerDisableUnlink\":\"*\",\"framerIntrinsicHeight\":\"800\",\"framerSupportedLayoutHeight\":\"fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Unfocused.map","import{jsx as _jsx}from\"react/jsx-runtime\";import{addPropertyControls,ControlType}from\"framer\";const DEFAULT_COLOR=\"#1570EF\";const DEFAULT_SVG=`<svg viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"m13.076 12.21 3.098 3.098a1.25 1.25 0 0 0 1.768 0l3.424-3.424a1.25 1.25 0 0 0 0-1.768l-3.424-3.424a1.25 1.25 0 0 0-1.768 0L13.076 9.79l4.902.903c.341.063.341.552 0 .614l-4.902.903Zm-3.206.786-3.178 3.178a1.25 1.25 0 0 0 0 1.768l3.424 3.424a1.25 1.25 0 0 0 1.768 0l3.424-3.424a1.25 1.25 0 0 0 0-1.768l-3.043-3.043-.878 4.768c-.063.34-.552.34-.615 0l-.902-4.903ZM6.692 4.058a1.25 1.25 0 0 0 0 1.768l3.177 3.178.903-4.903c.063-.34.552-.34.615 0l.878 4.768 3.043-3.043a1.25 1.25 0 0 0 0-1.768L11.884.634a1.25 1.25 0 0 0-1.768 0L6.692 4.058ZM.634 10.116a1.25 1.25 0 0 0 0 1.768l3.424 3.424a1.25 1.25 0 0 0 1.768 0l3.123-3.122-4.768-.879c-.341-.063-.341-.552 0-.614l4.768-.879-3.123-3.122a1.25 1.25 0 0 0-1.768 0L.634 10.116Z\" fill=\"#1570EF\"/></svg>`;const DEFAULT_STROKE_WIDTH=1.5;/*\n * @framerDisableUnlink\n *\n * @framerSupportedLayoutWidth fixed\n * @framerSupportedLayoutHeight fixed\n *\n * @framerIntrinsicHeight 24\n * @framerIntrinsicWidth 24\n */export default function FramerIcons(props){const customizedSvg=getCustomizedSVG(props.svg,props.color,props.strokeWidth);return /*#__PURE__*/_jsx(\"div\",{\"aria-hidden\":\"true\",style:{display:\"flex\",maxWidth:\"100%\",maxHeight:\"100%\",alignItems:\"center\",justifyContent:\"center\",...props.style},dangerouslySetInnerHTML:{__html:customizedSvg}});}addPropertyControls(FramerIcons,{svg:{title:\"SVG\",type:ControlType.String,defaultValue:DEFAULT_SVG},strokeWidth:{type:ControlType.Number,step:.25,min:.25,max:3,defaultValue:DEFAULT_STROKE_WIDTH,hidden:props=>hideStrokeWidth(props.svg)},color:{type:ControlType.Color,defaultValue:DEFAULT_COLOR,description:\"By [FramerIcons](https://www.framericons.com?utm=FramerIconComponent)\"}});// hide if no stroke-width or all stroke-widths are 0\nfunction hideStrokeWidth(svg){const strokeWidthMatch=svg.match(/stroke-width=\"([^\"]+)\"/g);return!strokeWidthMatch||strokeWidthMatch.every(match=>match===\"0\");}function getCustomizedSVG(svg,color=DEFAULT_COLOR,strokeWidth=DEFAULT_STROKE_WIDTH){let svgAttributes=svg.match(/<svg[^>]*>/)?.[0];if(!svgAttributes){svg=DEFAULT_SVG;svgAttributes=svg.match(/<svg[^>]*>/)?.[0];}const width=svgAttributes.match(/width=\"([^\"]*)\"/)?.[1];const height=svgAttributes.match(/height=\"([^\"]*)\"/)?.[1];const viewBox=svgAttributes.match(/viewBox=\"([^\"]*)\"/)?.[1]?.split(\" \");const viewBoxWidth=viewBox?.[2];const viewBoxHeight=viewBox?.[3];if(width&&height){svg=svg.replace(/width=\"([^\"]*)\"/,`width=\"100%\"`);svg=svg.replace(/height=\"([^\"]*)\"/,`height=\"100%\"`);}else{svg=svg.replace(/<svg/,`<svg width=\"100%\" height=\"100%\"`);}let hasElementsWithValidColors=false;if(svg.includes('fill=\"')||svg.includes('stroke=\"')){svg=svg.replace(/(fill|stroke)=\"([^\"]+)\"/g,(match,attr,value)=>{if(value===\"none\"||value===\"transparent\"){return match;}// For iconsax -> Crypto -> Bulk\nif(value===\"white\"){return\"\";}hasElementsWithValidColors=true;return`${attr}=\"${color}\"`;});}if(!hasElementsWithValidColors){svg=svg.replace(/<(path|circle|rect|line|polygon|polyline) /g,match=>`<${match.slice(1)} fill=\"${color}\" `);}svg=svg.replace(/stroke-width=\"([^\"]+)\"/g,(match,value)=>{if(value===\"0\"){return match;}return`stroke-width=\"${strokeWidth}\"`;});return svg;}\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"FramerIcons\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\",\"framerDisableUnlink\":\"*\",\"framerIntrinsicWidth\":\"24\",\"framerSupportedLayoutWidth\":\"fixed\",\"framerIntrinsicHeight\":\"24\",\"framerSupportedLayoutHeight\":\"fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./FramerIcon.map","import { ControlType } from \"framer\";\nexport const fontStack = `\"Inter\", system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"`;\nexport const containerStyles = {\n    position: \"relative\",\n    width: \"100%\",\n    height: \"100%\",\n    display: \"flex\",\n    justifyContent: \"center\",\n    alignItems: \"center\"\n};\nexport const emptyStateStyle = {\n    ...containerStyles,\n    borderRadius: 6,\n    background: \"rgba(136, 85, 255, 0.3)\",\n    color: \"#85F\",\n    border: \"1px dashed #85F\",\n    flexDirection: \"column\"\n};\nexport const defaultEvents = {\n    onClick: {\n        type: ControlType.EventHandler\n    },\n    onMouseEnter: {\n        type: ControlType.EventHandler\n    },\n    onMouseLeave: {\n        type: ControlType.EventHandler\n    }\n};\nexport const fontSizeOptions = {\n    type: ControlType.Number,\n    title: \"Font Size\",\n    min: 2,\n    max: 200,\n    step: 1,\n    displayStepper: true\n};\nexport const fontControls = {\n    font: {\n        type: ControlType.Boolean,\n        title: \"Font\",\n        defaultValue: false,\n        disabledTitle: \"Default\",\n        enabledTitle: \"Custom\"\n    },\n    fontFamily: {\n        type: ControlType.String,\n        title: \"Family\",\n        placeholder: \"Inter\",\n        hidden: ({ font  })=>!font\n    },\n    fontWeight: {\n        type: ControlType.Enum,\n        title: \"Weight\",\n        options: [\n            100,\n            200,\n            300,\n            400,\n            500,\n            600,\n            700,\n            800,\n            900\n        ],\n        optionTitles: [\n            \"Thin\",\n            \"Extra-light\",\n            \"Light\",\n            \"Regular\",\n            \"Medium\",\n            \"Semi-bold\",\n            \"Bold\",\n            \"Extra-bold\",\n            \"Black\", \n        ],\n        hidden: ({ font  })=>!font\n    }\n};\n// @TODO check if we're missing anything here — there doesn't seem to be a reliable browser API for this\nexport const localeOptions = {\n    af: \"Afrikaans\",\n    sq: \"Albanian\",\n    an: \"Aragonese\",\n    ar: \"Arabic (Standard)\",\n    \"ar-dz\": \"Arabic (Algeria)\",\n    \"ar-bh\": \"Arabic (Bahrain)\",\n    \"ar-eg\": \"Arabic (Egypt)\",\n    \"ar-iq\": \"Arabic (Iraq)\",\n    \"ar-jo\": \"Arabic (Jordan)\",\n    \"ar-kw\": \"Arabic (Kuwait)\",\n    \"ar-lb\": \"Arabic (Lebanon)\",\n    \"ar-ly\": \"Arabic (Libya)\",\n    \"ar-ma\": \"Arabic (Morocco)\",\n    \"ar-om\": \"Arabic (Oman)\",\n    \"ar-qa\": \"Arabic (Qatar)\",\n    \"ar-sa\": \"Arabic (Saudi Arabia)\",\n    \"ar-sy\": \"Arabic (Syria)\",\n    \"ar-tn\": \"Arabic (Tunisia)\",\n    \"ar-ae\": \"Arabic (U.A.E.)\",\n    \"ar-ye\": \"Arabic (Yemen)\",\n    hy: \"Armenian\",\n    as: \"Assamese\",\n    ast: \"Asturian\",\n    az: \"Azerbaijani\",\n    eu: \"Basque\",\n    bg: \"Bulgarian\",\n    be: \"Belarusian\",\n    bn: \"Bengali\",\n    bs: \"Bosnian\",\n    br: \"Breton\",\n    my: \"Burmese\",\n    ca: \"Catalan\",\n    ch: \"Chamorro\",\n    ce: \"Chechen\",\n    zh: \"Chinese\",\n    \"zh-hk\": \"Chinese (Hong Kong)\",\n    \"zh-cn\": \"Chinese (PRC)\",\n    \"zh-sg\": \"Chinese (Singapore)\",\n    \"zh-tw\": \"Chinese (Taiwan)\",\n    cv: \"Chuvash\",\n    co: \"Corsican\",\n    cr: \"Cree\",\n    hr: \"Croatian\",\n    cs: \"Czech\",\n    da: \"Danish\",\n    nl: \"Dutch (Standard)\",\n    \"nl-be\": \"Dutch (Belgian)\",\n    en: \"English\",\n    \"en-au\": \"English (Australia)\",\n    \"en-bz\": \"English (Belize)\",\n    \"en-ca\": \"English (Canada)\",\n    \"en-ie\": \"English (Ireland)\",\n    \"en-jm\": \"English (Jamaica)\",\n    \"en-nz\": \"English (New Zealand)\",\n    \"en-ph\": \"English (Philippines)\",\n    \"en-za\": \"English (South Africa)\",\n    \"en-tt\": \"English (Trinidad & Tobago)\",\n    \"en-gb\": \"English (United Kingdom)\",\n    \"en-us\": \"English (United States)\",\n    \"en-zw\": \"English (Zimbabwe)\",\n    eo: \"Esperanto\",\n    et: \"Estonian\",\n    fo: \"Faeroese\",\n    fa: \"Farsi\",\n    fj: \"Fijian\",\n    fi: \"Finnish\",\n    fr: \"French (Standard)\",\n    \"fr-be\": \"French (Belgium)\",\n    \"fr-ca\": \"French (Canada)\",\n    \"fr-fr\": \"French (France)\",\n    \"fr-lu\": \"French (Luxembourg)\",\n    \"fr-mc\": \"French (Monaco)\",\n    \"fr-ch\": \"French (Switzerland)\",\n    fy: \"Frisian\",\n    fur: \"Friulian\",\n    gd: \"Gaelic (Scots)\",\n    \"gd-ie\": \"Gaelic (Irish)\",\n    gl: \"Galacian\",\n    ka: \"Georgian\",\n    de: \"German (Standard)\",\n    \"de-at\": \"German (Austria)\",\n    \"de-de\": \"German (Germany)\",\n    \"de-li\": \"German (Liechtenstein)\",\n    \"de-lu\": \"German (Luxembourg)\",\n    \"de-ch\": \"German (Switzerland)\",\n    el: \"Greek\",\n    gu: \"Gujurati\",\n    ht: \"Haitian\",\n    he: \"Hebrew\",\n    hi: \"Hindi\",\n    hu: \"Hungarian\",\n    is: \"Icelandic\",\n    id: \"Indonesian\",\n    iu: \"Inuktitut\",\n    ga: \"Irish\",\n    it: \"Italian (Standard)\",\n    \"it-ch\": \"Italian (Switzerland)\",\n    ja: \"Japanese\",\n    kn: \"Kannada\",\n    ks: \"Kashmiri\",\n    kk: \"Kazakh\",\n    km: \"Khmer\",\n    ky: \"Kirghiz\",\n    tlh: \"Klingon\",\n    ko: \"Korean\",\n    \"ko-kp\": \"Korean (North Korea)\",\n    \"ko-kr\": \"Korean (South Korea)\",\n    la: \"Latin\",\n    lv: \"Latvian\",\n    lt: \"Lithuanian\",\n    lb: \"Luxembourgish\",\n    mk: \"FYRO Macedonian\",\n    ms: \"Malay\",\n    ml: \"Malayalam\",\n    mt: \"Maltese\",\n    mi: \"Maori\",\n    mr: \"Marathi\",\n    mo: \"Moldavian\",\n    nv: \"Navajo\",\n    ng: \"Ndonga\",\n    ne: \"Nepali\",\n    no: \"Norwegian\",\n    nb: \"Norwegian (Bokmal)\",\n    nn: \"Norwegian (Nynorsk)\",\n    oc: \"Occitan\",\n    or: \"Oriya\",\n    om: \"Oromo\",\n    \"fa-ir\": \"Persian/Iran\",\n    pl: \"Polish\",\n    pt: \"Portuguese\",\n    \"pt-br\": \"Portuguese (Brazil)\",\n    pa: \"Punjabi\",\n    \"pa-in\": \"Punjabi (India)\",\n    \"pa-pk\": \"Punjabi (Pakistan)\",\n    qu: \"Quechua\",\n    rm: \"Rhaeto-Romanic\",\n    ro: \"Romanian\",\n    \"ro-mo\": \"Romanian (Moldavia)\",\n    ru: \"Russian\",\n    \"ru-mo\": \"Russian (Moldavia)\",\n    sz: \"Sami (Lappish)\",\n    sg: \"Sango\",\n    sa: \"Sanskrit\",\n    sc: \"Sardinian\",\n    sd: \"Sindhi\",\n    si: \"Singhalese\",\n    sr: \"Serbian\",\n    sk: \"Slovak\",\n    sl: \"Slovenian\",\n    so: \"Somani\",\n    sb: \"Sorbian\",\n    es: \"Spanish\",\n    \"es-ar\": \"Spanish (Argentina)\",\n    \"es-bo\": \"Spanish (Bolivia)\",\n    \"es-cl\": \"Spanish (Chile)\",\n    \"es-co\": \"Spanish (Colombia)\",\n    \"es-cr\": \"Spanish (Costa Rica)\",\n    \"es-do\": \"Spanish (Dominican Republic)\",\n    \"es-ec\": \"Spanish (Ecuador)\",\n    \"es-sv\": \"Spanish (El Salvador)\",\n    \"es-gt\": \"Spanish (Guatemala)\",\n    \"es-hn\": \"Spanish (Honduras)\",\n    \"es-mx\": \"Spanish (Mexico)\",\n    \"es-ni\": \"Spanish (Nicaragua)\",\n    \"es-pa\": \"Spanish (Panama)\",\n    \"es-py\": \"Spanish (Paraguay)\",\n    \"es-pe\": \"Spanish (Peru)\",\n    \"es-pr\": \"Spanish (Puerto Rico)\",\n    \"es-es\": \"Spanish (Spain)\",\n    \"es-uy\": \"Spanish (Uruguay)\",\n    \"es-ve\": \"Spanish (Venezuela)\",\n    sx: \"Sutu\",\n    sw: \"Swahili\",\n    sv: \"Swedish\",\n    \"sv-fi\": \"Swedish (Finland)\",\n    \"sv-sv\": \"Swedish (Sweden)\",\n    ta: \"Tamil\",\n    tt: \"Tatar\",\n    te: \"Teluga\",\n    th: \"Thai\",\n    tig: \"Tigre\",\n    ts: \"Tsonga\",\n    tn: \"Tswana\",\n    tr: \"Turkish\",\n    tk: \"Turkmen\",\n    uk: \"Ukrainian\",\n    hsb: \"Upper Sorbian\",\n    ur: \"Urdu\",\n    ve: \"Venda\",\n    vi: \"Vietnamese\",\n    vo: \"Volapuk\",\n    wa: \"Walloon\",\n    cy: \"Welsh\",\n    xh: \"Xhosa\",\n    ji: \"Yiddish\",\n    zu: \"Zulu\"\n};\n\nexport const __FramerMetadata__ = {\"exports\":{\"fontSizeOptions\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"fontControls\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"localeOptions\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"fontStack\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"emptyStateStyle\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"containerStyles\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultEvents\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./constants.map","import { useIsInCurrentNavigationTarget } from \"framer\";\nimport { useEffect } from \"react\";\nexport function useOnEnter(onEnter, enabled) {\n    return useOnSpecificTargetChange(true, onEnter, enabled);\n}\nexport function useOnExit(onExit, enabled) {\n    return useOnSpecificTargetChange(false, onExit, enabled);\n}\nfunction useOnSpecificTargetChange(goal, callback, enabled = true) {\n    const isInTarget = useIsInCurrentNavigationTarget();\n    useEffect(()=>{\n        if (enabled && isInTarget === goal) callback();\n    }, [\n        isInTarget\n    ]);\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"useOnEnter\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useOnExit\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useOnNavigationTargetChange.map","import { useRef } from \"react\";\n/**\n * Creates a constant value over the lifecycle of a component.\n *\n * Even if `useMemo` is provided an empty array as its final argument, it doesn't offer\n * a guarantee that it won't re-run for performance reasons later on. By using `useConstant`\n * you can ensure that initialisers don't execute twice or more.\n */ export function useConstant(init) {\n    const ref = useRef(null);\n    if (ref.current === null) {\n        ref.current = init();\n    }\n    return ref.current;\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"useConstant\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useConstant.map","import { Color } from \"framer\";\nexport function colorFromToken(color) {\n    if (color.startsWith(\"var(--token-\")) return \"rgb\" + color.split(\") /*\")[0].split(\", rgb\")[1];\n    return color;\n}\nexport function colorTokentoValue(color) {\n    return Color(colorFromToken(color)).toValue();\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"colorFromToken\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"colorTokentoValue\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./colorFromToken.map","import { MotionValue } from \"framer\";\nexport const isMotionValue = (v)=>v instanceof MotionValue\n;\n\nexport const __FramerMetadata__ = {\"exports\":{\"isMotionValue\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./isMotionValue.map","import * as React from \"react\";\nconst letters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\nconst l = ()=>letters[Math.floor(Math.random() * letters.length)]\n;\nexport const randomID = ()=>l() + l() + l() + l() + l() + l() + l() + l() + l()\n;\nfunction createUniqueClass(suffix) {\n    return `framer-${suffix}-${randomID()}`;\n}\nexport function useUniqueClassName(suffix, deps) {\n    const [className, setClassName] = React.useState(createUniqueClass(suffix));\n    React.useEffect(()=>{\n        setClassName(createUniqueClass(suffix));\n    }, [\n        suffix,\n        ...deps\n    ]);\n    return className;\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"useUniqueClassName\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"randomID\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useUniqueClassName.map","import { ControlType } from \"framer\";\n// I realize this only applies to select right now\n// but we can work on it in here\nexport function getVariantControls(Component, variant, additionalControls = {\n}) {\n    return {\n        [`${variant}TextColor`]: {\n            type: ControlType.Color,\n            title: \"Text Color\",\n            defaultValue: Component.defaultProps[`${variant}TextColor`],\n            hidden: (props)=>props.variant !== variant\n        },\n        [`${variant}IconColor`]: {\n            type: ControlType.Color,\n            title: \"Icon Color\",\n            defaultValue: Component.defaultProps[`${variant}IconColor`],\n            hidden: (props)=>props.variant !== variant\n        },\n        [`${variant}BackgroundColor`]: {\n            type: ControlType.Color,\n            title: \"Bg Color\",\n            defaultValue: Component.defaultProps[`${variant}BackgroundColor`],\n            hidden: (props)=>props.variant !== variant\n        },\n        [`${variant}BorderColor`]: {\n            type: ControlType.Color,\n            title: \"Border Color\",\n            defaultValue: Component.defaultProps[`${variant}BorderColor`],\n            hidden: (props)=>props.variant !== variant\n        },\n        [`${variant}BorderWidth`]: {\n            type: ControlType.Number,\n            title: \" \",\n            min: 0,\n            max: 5,\n            displayStepper: true,\n            defaultValue: Component.defaultProps[`${variant}BorderWidth`],\n            hidden: (props)=>props.variant !== variant\n        },\n        ...additionalControls\n    };\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"getVariantControls\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./variantUtils.map","import { useMemo } from \"react\";\nexport const isBrowserSafari = ()=>{\n    if (typeof navigator !== `undefined`) {\n        const userAgent = navigator.userAgent.toLowerCase();\n        const isSafari = (userAgent.indexOf(\"safari\") > -1 || userAgent.indexOf(\"framermobile\") > -1 || userAgent.indexOf(\"framerx\") > -1) && userAgent.indexOf(\"chrome\") < 0;\n        return isSafari;\n    } else return false;\n};\nexport const useIsBrowserSafari = ()=>useMemo(()=>isBrowserSafari()\n    , [])\n;\n\nexport const __FramerMetadata__ = {\"exports\":{\"useIsBrowserSafari\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"isBrowserSafari\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./isBrowser.map","import { useEffect } from \"react\";\n//@ts-ignore\nimport { isMotionValue } from \"https://framerusercontent.com/modules/3mKFSGQqKHV82uOV1eBc/5fbRLvOpxZC0JOXugvwm/isMotionValue.js\";\nexport function useOnChange(value, callback) {\n    useEffect(()=>// @ts-ignore this should be detected as a MV :shrug:\n        isMotionValue(value) ? value.onChange(callback) : undefined\n    );\n}\nexport function useMultiOnChange(values, handler) {\n    useEffect(()=>{\n        const subscriptions = values.map((value)=>value.onChange(handler)\n        );\n        return ()=>subscriptions.forEach((unsubscribe)=>unsubscribe()\n            )\n        ;\n    });\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"Subscriber\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useOnChange\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useMultiOnChange\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useOnChange.map","import { useCallback, useEffect, useRef } from \"react\";\nimport { motionValue, animate, RenderTarget } from \"framer\";\n// @ts-ignore\nimport { isMotionValue } from \"https://framerusercontent.com/modules/3mKFSGQqKHV82uOV1eBc/5fbRLvOpxZC0JOXugvwm/isMotionValue.js\";\n// @ts-ignore\nimport { useConstant } from \"https://framerusercontent.com/modules/ExNgrA7EJTKUPpH6vIlN/eiOrSJ2Ab5M9jPCvVwUz/useConstant.js\";\nexport function useAutoMotionValue(inputValue, options) {\n    var ref;\n    // Put options on a local ref\n    // Might wanna just memo instead but it works for now\n    const optionsRef = useRef(options);\n    const animation = useRef();\n    const didInitialMount = useRef(false);\n    const isOnCanvas = RenderTarget.current() === RenderTarget.canvas;\n    // in-progress - trying to figure out effect hooks\n    const onChangeDeps = (options === null || options === void 0 ? void 0 : options.onChangeDeps) ? options.onChangeDeps : [];\n    // Memoize the onChange handler\n    const onChange = useCallback(options === null || options === void 0 ? void 0 : options.onChange, [\n        ...onChangeDeps, \n    ]);\n    // Optionally scale the value from props\n    const transformer = useCallback((value)=>((ref = optionsRef.current) === null || ref === void 0 ? void 0 : ref.transform) ? optionsRef.current.transform(value) : value\n    , []);\n    // Create new MotionValue from inputValue\n    const value = useConstant(()=>isMotionValue(inputValue) ? inputValue : motionValue(transformer(inputValue))\n    );\n    // Setting value from prop change\n    useEffect(()=>{\n        if (!isMotionValue(inputValue) && didInitialMount.current) {\n            var ref1, ref2;\n            const newValue = transformer(inputValue);\n            (ref1 = animation.current) === null || ref1 === void 0 ? void 0 : ref1.stop();\n            // Call change callback\n            if (onChange) onChange(newValue, value);\n            // Trigger animation to new value\n            if (((ref2 = optionsRef.current) === null || ref2 === void 0 ? void 0 : ref2.animate) && !isOnCanvas) {\n                var ref3;\n                // @ts-ignore\n                animation.current = animate(value, newValue, (ref3 = optionsRef.current) === null || ref3 === void 0 ? void 0 : ref3.transition);\n            } else {\n                value.set(newValue);\n            }\n        }\n        didInitialMount.current = true;\n    }, [\n        inputValue,\n        ...onChangeDeps\n    ]);\n    return value;\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"useAutoMotionValue\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}","import * as React from \"react\";\nexport function useControlledState(value) {\n    const [controlledValue, setValue] = React.useState(value);\n    React.useEffect(()=>{\n        setValue(value);\n    }, [\n        value\n    ]);\n    return [\n        controlledValue,\n        setValue\n    ];\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"useControlledState\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useControlledState.map","import { useMemo } from \"react\";\nimport { ControlType } from \"framer\";\nexport function useRadius(props) {\n    const { borderRadius , isMixedBorderRadius , topLeftRadius , topRightRadius , bottomRightRadius , bottomLeftRadius ,  } = props;\n    const radiusValue = useMemo(()=>isMixedBorderRadius ? `${topLeftRadius}px ${topRightRadius}px ${bottomRightRadius}px ${bottomLeftRadius}px` : `${borderRadius}px`\n    , [\n        borderRadius,\n        isMixedBorderRadius,\n        topLeftRadius,\n        topRightRadius,\n        bottomRightRadius,\n        bottomLeftRadius, \n    ]);\n    return radiusValue;\n}\nexport const borderRadiusControl = {\n    borderRadius: {\n        title: \"Radius\",\n        type: ControlType.FusedNumber,\n        toggleKey: \"isMixedBorderRadius\",\n        toggleTitles: [\n            \"Radius\",\n            \"Radius per corner\"\n        ],\n        valueKeys: [\n            \"topLeftRadius\",\n            \"topRightRadius\",\n            \"bottomRightRadius\",\n            \"bottomLeftRadius\", \n        ],\n        valueLabels: [\n            \"TL\",\n            \"TR\",\n            \"BR\",\n            \"BL\"\n        ],\n        min: 0\n    }\n};\nexport function usePadding(props) {\n    const { padding , paddingPerSide , paddingTop , paddingRight , paddingBottom , paddingLeft ,  } = props;\n    const paddingValue = useMemo(()=>paddingPerSide ? `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px` : padding\n    , [\n        padding,\n        paddingPerSide,\n        paddingTop,\n        paddingRight,\n        paddingBottom,\n        paddingLeft, \n    ]);\n    return paddingValue;\n}\nexport const paddingControl = {\n    padding: {\n        type: ControlType.FusedNumber,\n        toggleKey: \"paddingPerSide\",\n        toggleTitles: [\n            \"Padding\",\n            \"Padding per side\"\n        ],\n        valueKeys: [\n            \"paddingTop\",\n            \"paddingRight\",\n            \"paddingBottom\",\n            \"paddingLeft\", \n        ],\n        valueLabels: [\n            \"T\",\n            \"R\",\n            \"B\",\n            \"L\"\n        ],\n        min: 0,\n        title: \"Padding\"\n    }\n};\n\nexport const __FramerMetadata__ = {\"exports\":{\"borderRadiusControl\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useRadius\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"RadiusProps\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"PaddingProps\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"usePadding\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"paddingControl\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./propUtils.map","// @ts-ignore\nimport{fontStore}from\"framer\";import{useEffect}from\"react\";import{fontStack}from\"https://framerusercontent.com/modules/VTUDdizacRHpwbkOamr7/AykinQJbgwl92LvMGZwu/constants.js\";const fontWeights={100:\"Thin\",200:\"Extra-light\",300:\"Light\",400:\"Regular\",500:\"Medium\",600:\"Semi-bold\",700:\"Bold\",800:\"Extra-bold\",900:\"Black\"};export function useFontControls(props){const{fontFamily=\"Inter\",fontSize=16,fontWeight=400,font=false}=props;const fontWeightName=fontWeights[fontWeight];const customFontStack=`\"${fontFamily} ${fontWeightName}\", \"${fontFamily}\", ${fontStack}`;const fontFamilyStyle=fontFamily?{fontSize,fontWeight,fontFamily:customFontStack}:{fontSize,fontWeight};const fetchCustomFonts=async()=>{await fontStore.loadWebFontsFromSelectors([`CUSTOM;${fontFamily}`,`CUSTOM;${fontFamily} ${fontWeightName}`,`GF;${fontFamily}-${fontWeightName.toLowerCase()}`,]).catch(e=>console.error(e));};useEffect(()=>{if(font)fetchCustomFonts();},[font,fontFamily,fontWeight]);return fontFamilyStyle;}\nexport const __FramerMetadata__ = {\"exports\":{\"useFontControls\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useFontControls.map","import { useMemo } from \"react\";\nimport { RenderTarget } from \"framer\";\nexport function useRenderTarget() {\n    const currentRenderTarget = useMemo(()=>RenderTarget.current()\n    , []);\n    return currentRenderTarget;\n}\nexport function useIsInPreview() {\n    const inPreview = useMemo(()=>RenderTarget.current() === RenderTarget.preview\n    , []);\n    return inPreview;\n}\nexport function useIsOnCanvas() {\n    const onCanvas = useMemo(()=>RenderTarget.current() === RenderTarget.canvas\n    , []);\n    return onCanvas;\n}\n\nexport const __FramerMetadata__ = {\"exports\":{\"useIsInPreview\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useRenderTarget\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useIsOnCanvas\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}\n//# sourceMappingURL=./useRenderTarget.map","import{defaultEvents,localeOptions,fontControls,fontSizeOptions,emptyStateStyle,containerStyles,fontStack}from\"https://framerusercontent.com/modules/VTUDdizacRHpwbkOamr7/AykinQJbgwl92LvMGZwu/constants.js\";import{useOnEnter,useOnExit}from\"https://framerusercontent.com/modules/D4TWeLfcxT6Tysr2BlYg/iZjmqdxVx1EOiM3k1FaW/useOnNavigationTargetChange.js\";import{useConstant}from\"https://framerusercontent.com/modules/ExNgrA7EJTKUPpH6vIlN/eiOrSJ2Ab5M9jPCvVwUz/useConstant.js\";import{colorTokentoValue,colorFromToken}from\"https://framerusercontent.com/modules/D2Lz5CmnNVPZFFiZXalt/QaCzPbriZBfXWZIIycFI/colorFromToken.js\";import{isMotionValue}from\"https://framerusercontent.com/modules/3mKFSGQqKHV82uOV1eBc/5fbRLvOpxZC0JOXugvwm/isMotionValue.js\";import{useUniqueClassName,randomID}from\"https://framerusercontent.com/modules/xDiQsqBGXzmMsv7AlEVy/uhunpMiNsbXxzjlXsg1y/useUniqueClassName.js\";import{getVariantControls}from\"https://framerusercontent.com/modules/ETACN5BJyFTSo0VVDJfu/NHRqowOiXkF9UwOzczF7/variantUtils.js\";import{useIsBrowserSafari}from\"https://framerusercontent.com/modules/eMBrwoqQK7h6mEeGQUH8/GuplvPJVjmxpk9zqOTcb/isBrowser.js\";import{useMultiOnChange,useOnChange}from\"https://framerusercontent.com/modules/v9AWX2URmiYsHf7GbctE/XxKAZ9KlhWqf5x1JMyyF/useOnChange.js\";import{mstoMinAndSec,secondsToMinutes}from\"https://framerusercontent.com/modules/4zHZnO5JojN1PrIbu2jm/revv9QCWpkh8lPzi2jje/time.js\";import{useAutoMotionValue}from\"https://framerusercontent.com/modules/kNDwabfjDEb3vUxkQlZS/fSIr3AOAYbGlfSPgXpYu/useAutoMotionValue.js\";import{useFontControls}from\"https://framerusercontent.com/modules/cuQH4dmpDnV8YK1mSgQX/KqRXqunFjE6ufhpc7ZRu/useFontControls.js\";import{useRenderTarget,useIsInPreview,useIsOnCanvas}from\"https://framerusercontent.com/modules/afBE9Yx1W6bY5q32qPxe/m3q7puE2tbo1S2C0s0CT/useRenderTarget.js\";import{useControlledState}from\"https://framerusercontent.com/modules/zGkoP8tPDCkoBzMdt5uq/0zFSjxIYliHxrQQnryFX/useControlledState.js\";import{usePadding,useRadius,paddingControl,borderRadiusControl}from\"https://framerusercontent.com/modules/5SM58HxZHxjjv7aLMOgQ/WXz9i6mVki0bBCrKdqB3/propUtils.js\";import{detectAutoSizingAxis}from\"https://framerusercontent.com/modules/8CkHAZatUz1UR8jNTcfD/HwbnIAZlUmQ2oTpcLkaH/detectAutoSizingAxis.js\";export{useOnEnter,useOnExit,defaultEvents,isMotionValue,colorFromToken,colorTokentoValue,localeOptions,fontControls,fontSizeOptions,emptyStateStyle,containerStyles,fontStack,useUniqueClassName,getVariantControls,useIsBrowserSafari,randomID,useConstant,useMultiOnChange,useOnChange,usePadding,useRadius,paddingControl,borderRadiusControl,mstoMinAndSec,useFontControls,secondsToMinutes,useAutoMotionValue,useRenderTarget,useIsInPreview,useControlledState,detectAutoSizingAxis,useIsOnCanvas,};\nexport const __FramerMetadata__ = {\"exports\":{\"useConstant\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"isMotionValue\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"fontControls\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"defaultEvents\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useUniqueClassName\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useMultiOnChange\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useOnChange\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useIsOnCanvas\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useOnExit\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"fontSizeOptions\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"colorTokentoValue\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useRadius\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getVariantControls\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"colorFromToken\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"containerStyles\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"usePadding\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"fontStack\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useControlledState\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useFontControls\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useAutoMotionValue\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"emptyStateStyle\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useIsInPreview\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useIsBrowserSafari\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"detectAutoSizingAxis\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"borderRadiusControl\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"mstoMinAndSec\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"randomID\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"localeOptions\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useOnEnter\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"secondsToMinutes\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useRenderTarget\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"paddingControl\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}}}}","/*\n * index (framer/default-utils@0.45.0)\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/G4IfyjvwmaeSBpdb4TWu/OIjZRBmWDcIE2B6qgG1j/index.js\"\n"],"mappings":"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"}