@engenty/wizards-runtime 0.7.8 → 0.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +2 -1
  2. package/apps/runtime/dist/app.js +2 -2
  3. package/apps/runtime/dist/cli/autostart.js +90 -7
  4. package/apps/runtime/dist/cli/autoupdate.js +18 -5
  5. package/apps/runtime/dist/cli/clients.js +25 -6
  6. package/apps/runtime/dist/cli/connect.js +7 -2
  7. package/apps/runtime/dist/cli/environment.js +33 -2
  8. package/apps/runtime/dist/cli/exec.js +38 -1
  9. package/apps/runtime/dist/cli/home.js +15 -0
  10. package/apps/runtime/dist/cli/machine.js +18 -8
  11. package/apps/runtime/dist/cli/processes.js +23 -3
  12. package/apps/runtime/dist/cli/setup.js +11 -1
  13. package/apps/runtime/dist/cli/start.js +33 -7
  14. package/apps/runtime/dist/cli/uninstall.js +100 -6
  15. package/apps/runtime/dist/cli/update.js +28 -12
  16. package/apps/runtime/dist/cli/versions.js +16 -4
  17. package/apps/runtime/dist/clients.js +118 -0
  18. package/apps/runtime/dist/db/client.js +37 -3
  19. package/apps/runtime/dist/db/migrations/tenant/0017_run_client.sql +1 -0
  20. package/apps/runtime/dist/db/migrations/tenant/meta/0017_snapshot.json +3333 -0
  21. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  22. package/apps/runtime/dist/db/schema.js +2 -0
  23. package/apps/runtime/dist/docs/dev/api.md +39 -0
  24. package/apps/runtime/dist/docs/dev/index.md +1 -0
  25. package/apps/runtime/dist/docs/dev/integration/openui.md +5 -3
  26. package/apps/runtime/dist/docs/dev/meta.json +1 -1
  27. package/apps/runtime/dist/docs/user/ai-apps.md +14 -3
  28. package/apps/runtime/dist/docs/user/install.md +18 -8
  29. package/apps/runtime/dist/engine/runner.js +1 -0
  30. package/apps/runtime/dist/harness/env.js +41 -8
  31. package/apps/runtime/dist/harness/index.js +10 -1
  32. package/apps/runtime/dist/harness/model.js +1 -1
  33. package/apps/runtime/dist/index.js +13 -4
  34. package/apps/runtime/dist/plugin.js +24 -8
  35. package/apps/runtime/dist/render/browser-path.js +43 -11
  36. package/apps/runtime/dist/routes/runs.js +9 -0
  37. package/apps/runtime/dist/update.js +4 -0
  38. package/apps/web/dist/assets/AboutDialog-B2LuZ_mC.js +1 -0
  39. package/apps/web/dist/assets/ChangelogDialog-B0lS0BdL.js +1 -0
  40. package/apps/web/dist/assets/ChatView-BcPDcU2d.js +10 -0
  41. package/apps/web/dist/assets/EditorPage-erduYKNM.js +4 -0
  42. package/apps/web/dist/assets/{FlowPreview-Dx8AjXvE.js → FlowPreview-oX_Emm7u.js} +1 -1
  43. package/apps/web/dist/assets/{Harness-NvIb36TG.js → Harness-Dv9ln5xB.js} +2 -2
  44. package/apps/web/dist/assets/{NewWizardChannels-B2YgtJlt.js → NewWizardChannels-JveYyh-U.js} +1 -1
  45. package/apps/web/dist/assets/NewWizardPage-Dfk-WOhX.js +7 -0
  46. package/apps/web/dist/assets/OnboardingPage-CT9dL4ke.js +1 -0
  47. package/apps/web/dist/assets/ProjectPage-5_Wsk9Hv.js +1 -0
  48. package/apps/web/dist/assets/PublicRunner-Cw1WzTze.js +1 -0
  49. package/apps/web/dist/assets/{ReadOnly-CGNHlgUT.js → ReadOnly-S9vGVQHr.js} +1 -1
  50. package/apps/web/dist/assets/RunDrawer-O4rEFCL8.js +4 -0
  51. package/apps/web/dist/assets/RunnerView-BW1h4x63.js +1 -0
  52. package/apps/web/dist/assets/SettingsPage-DmhN7OTy.js +1 -0
  53. package/apps/web/dist/assets/SetupPage-BlWd7Uln.js +1 -0
  54. package/apps/web/dist/assets/{SharePage-hG7Z6SLy.js → SharePage-ktqm-jWI.js} +1 -1
  55. package/apps/web/dist/assets/changelog-FJJS0Tpt.js +1 -0
  56. package/apps/web/dist/assets/engenty-WpMi3xwq.js +1 -0
  57. package/apps/web/dist/assets/{esm-DVk3RJij.js → esm-C-ZWeuhU.js} +1 -1
  58. package/apps/web/dist/assets/{fluffy-engenty-ClRou7yu.js → fluffy-engenty-DPNHytrz.js} +135 -16
  59. package/apps/web/dist/assets/goose-helmet-Cvc7KjUg.bin +0 -0
  60. package/apps/web/dist/assets/goose-helmet-livery-CZD9u0XS.webp +0 -0
  61. package/apps/web/dist/assets/index-C4aHMcg9.css +1 -0
  62. package/apps/web/dist/assets/index-xH9uN8Nh.js +14 -0
  63. package/apps/web/dist/assets/oss-credits-Bc05Qv5H.js +1 -0
  64. package/apps/web/dist/assets/{phone-CXXHXYnA.js → phone-BjmhIKuT.js} +1 -1
  65. package/apps/web/dist/assets/{settings-menu-DXzZCIMx.js → settings-menu-Dpkp3f56.js} +1 -1
  66. package/apps/web/dist/assets/{ui-DQ4L2npj.js → ui-DMmT-cSO.js} +4 -4
  67. package/apps/web/dist/assets/{upload-BnYHIfu5.js → upload-JX9BcMTq.js} +1 -1
  68. package/apps/web/dist/assets/{wrench-BrUJ7SV6.js → wrench-BSxnPs2_.js} +1 -1
  69. package/apps/web/dist/index.html +4 -4
  70. package/apps/web/dist/install.ps1 +307 -0
  71. package/apps/web/dist/mcp/flow.html +141 -22
  72. package/bin/wizards.mjs +59 -35
  73. package/node_modules/@engenty/wizards/package.json +1 -4
  74. package/node_modules/@engenty-wizards/shared/dist/claude-plugin.d.ts +7 -0
  75. package/node_modules/@engenty-wizards/shared/dist/claude-plugin.js +10 -0
  76. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +2 -0
  77. package/node_modules/@engenty-wizards/shared/dist/run.js +4 -0
  78. package/package.json +2 -5
  79. package/plugin/.claude-plugin/plugin.json +28 -6
  80. package/plugin/README.md +58 -0
  81. package/plugin/hooks/engenty.ts +140 -0
  82. package/plugin/hooks/hooks.json +1 -0
  83. package/plugin/hooks/pane.test.tsx +177 -0
  84. package/plugin/hooks/register.tsx +396 -0
  85. package/plugin/types/index.d.ts +44 -0
  86. package/apps/web/dist/assets/AboutDialog-ByZyHXDj.js +0 -1
  87. package/apps/web/dist/assets/ChangelogDialog-QHYP0jAv.js +0 -1
  88. package/apps/web/dist/assets/ChatView-DupTtI8K.js +0 -10
  89. package/apps/web/dist/assets/EditorPage-k6qouLeS.js +0 -4
  90. package/apps/web/dist/assets/NewWizardPage-BgLY6SL6.js +0 -7
  91. package/apps/web/dist/assets/OnboardingPage-CxhwefJU.js +0 -1
  92. package/apps/web/dist/assets/ProjectPage-6ceSSS7W.js +0 -1
  93. package/apps/web/dist/assets/PublicRunner-6lQvReDx.js +0 -1
  94. package/apps/web/dist/assets/RunDrawer-TVGNnWyx.js +0 -4
  95. package/apps/web/dist/assets/RunnerView-DInSK0VZ.js +0 -1
  96. package/apps/web/dist/assets/SettingsPage-D3k5pXN5.js +0 -1
  97. package/apps/web/dist/assets/SetupPage-Bj5frdzY.js +0 -1
  98. package/apps/web/dist/assets/changelog-CO9vKjV0.js +0 -1
  99. package/apps/web/dist/assets/engenty-eXZ-EAwd.js +0 -1
  100. package/apps/web/dist/assets/index-DfaoPjNW.css +0 -1
  101. package/apps/web/dist/assets/index-DlDsr9Lc.js +0 -14
  102. package/apps/web/dist/assets/oss-credits-X2JPiMOR.js +0 -1
  103. package/node_modules/@engenty/wizards/dist/openui/Wizard.d.ts +0 -20
  104. package/node_modules/@engenty/wizards/dist/openui/Wizard.js +0 -62
  105. package/node_modules/@engenty/wizards/dist/openui/index.d.ts +0 -9
  106. package/node_modules/@engenty/wizards/dist/openui/index.js +0 -9
  107. package/node_modules/@engenty/wizards/dist/openui/message.d.ts +0 -11
  108. package/node_modules/@engenty/wizards/dist/openui/message.js +0 -69
  109. package/node_modules/@engenty/wizards/dist/openui/run.d.ts +0 -8
  110. package/node_modules/@engenty/wizards/dist/openui/run.js +0 -137
  111. package/node_modules/@engenty/wizards/dist/openui/server.d.ts +0 -37
  112. package/node_modules/@engenty/wizards/dist/openui/server.js +0 -77
  113. package/plugin/.mcp.json +0 -8
@@ -1,7 +1,7 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,t as n}from"./jsx-runtime-BNakU3Ej.js";import{a as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./engenty-eXZ-EAwd.js";var f=e(t(),1),p=new Map,m=null,h=new WeakMap;function g(e){let t=p.get(e);if(t)return t;if(!m){let e=document.createElement(`canvas`);e.width=1,e.height=1,m=e.getContext(`2d`,{willReadFrequently:!0})}let n=[.5,.5,.5];if(m){m.clearRect(0,0,1,1),m.fillStyle=`#808080`,m.fillStyle=e,m.fillRect(0,0,1,1);let[t,r,i]=m.getImageData(0,0,1,1).data;n=[t/255,r/255,i/255]}return p.set(e,n),n}function _(e,t){let n=h.get(e);return n||(n=document.createElement(`span`),n.setAttribute(`aria-hidden`,`true`),n.style.cssText=`position:absolute;width:0;height:0;overflow:hidden;visibility:hidden`,e.appendChild(n),h.set(e,n)),n.style.color=``,n.style.color=t,g(getComputedStyle(n).color||`#808080`)}var v=(e,t,n)=>[e[0]+(t[0]-e[0])*n,e[1]+(t[1]-e[1])*n,e[2]+(t[2]-e[2])*n];function ee(e,t){let n=_(e,a[d[t]]),r=Math.max(...n),i=[Math.min(1,n[0]+n[0]/(r||1)*.45),Math.min(1,n[1]+n[1]/(r||1)*.45),Math.min(1,n[2]+n[2]/(r||1)*.45)];return{body:v(n,[1,1,1],.12),deep:v(n,[.03,.02,.06],.62),tip:v(i,[1,1,1],.12)}}var y=`#version 300 es
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,t as n}from"./jsx-runtime-BNakU3Ej.js";import{a as r,c as i,f as a,i as o,l as s,n as c,o as l,p as u,r as d,s as f,t as p,u as m}from"./engenty-WpMi3xwq.js";var h=e(t(),1),g=new Map,_=null,v=new WeakMap;function y(e){let t=g.get(e);if(t)return t;if(!_){let e=document.createElement(`canvas`);e.width=1,e.height=1,_=e.getContext(`2d`,{willReadFrequently:!0})}let n=[.5,.5,.5];if(_){_.clearRect(0,0,1,1),_.fillStyle=`#808080`,_.fillStyle=e,_.fillRect(0,0,1,1);let[t,r,i]=_.getImageData(0,0,1,1).data;n=[t/255,r/255,i/255]}return g.set(e,n),n}function b(e,t){let n=v.get(e);return n||(n=document.createElement(`span`),n.setAttribute(`aria-hidden`,`true`),n.style.cssText=`position:absolute;width:0;height:0;overflow:hidden;visibility:hidden`,e.appendChild(n),v.set(e,n)),n.style.color=``,n.style.color=t,y(getComputedStyle(n).color||`#808080`)}var x=(e,t,n)=>[e[0]+(t[0]-e[0])*n,e[1]+(t[1]-e[1])*n,e[2]+(t[2]-e[2])*n];function ee(e,t){let n=b(e,a[u[t]]),r=Math.max(...n),i=[Math.min(1,n[0]+n[0]/(r||1)*.45),Math.min(1,n[1]+n[1]/(r||1)*.45),Math.min(1,n[2]+n[2]/(r||1)*.45)];return{body:x(n,[1,1,1],.12),deep:x(n,[.03,.02,.06],.62),tip:x(i,[1,1,1],.12)}}var S=`#version 300 es
2
2
  precision highp float;
3
- #define BLOBS ${c}
4
- #define EXTRAS ${i}
3
+ #define BLOBS ${l}
4
+ #define EXTRAS ${f}
5
5
  #define VIEW ${152 .toFixed(1)}
6
6
  #define ORIGIN ${(-16).toFixed(1)}
7
7
  #define TAU 6.2831853
@@ -148,7 +148,7 @@ vec4 gogglesOver(vec2 p, float aa, float front) {
148
148
  return acc;
149
149
  }
150
150
 
151
- `;function b(e){let t=[];for(let n=0;n<e.extraMeta.length/4;n++){let[r,,i,a]=e.extraMeta.slice(n*4,n*4+4);if(r!==2&&!(r===3&&a>.5))continue;let[o,s,c,l]=e.extras.slice(n*4,n*4+4),u=r===2?16:32,d=(e,t)=>{let a=e/u*(r===2?Math.PI:l*2)-(r===2?0:l),d=t/16*Math.PI*2,f=r===2?[Math.sin(a)*Math.cos(d),-Math.cos(a),Math.sin(a)*Math.sin(d)]:[Math.sin(a)*Math.cos(d),-Math.cos(a)*Math.cos(d),Math.sin(d)],p=r===2?[o,s,0]:[o+Math.sin(a)*c,s-Math.cos(a)*c,0],m=r===2?c:i*.5;return[...p.map((e,t)=>e+f[t]*m),...f,n]},f=(e,n,r)=>{let i=n.map((t,n)=>t-e[n]),a=r.map((t,n)=>t-e[n]),o=[i[1]*a[2]-i[2]*a[1],i[2]*a[0]-i[0]*a[2],i[0]*a[1]-i[1]*a[0]].reduce((t,n,r)=>t+n*e[r+3],0)<0?[e,r,n]:[e,n,r];for(let e of o)t.push(...e)};for(let e=0;e<u;e++)for(let t=0;t<16;t++){let n=d(e,t),r=d(e+1,t),i=d(e+1,t+1),a=d(e,t+1);f(n,r,i),f(n,i,a)}}return new Float32Array(t)}function x(e,t){let n=new Map,r=[[`aPosition`,3,0],[`aNormal`,3,12],[`aExtra`,1,24]];return{draw(i){let a=`${i.extras.join(`,`)}:${i.extraMeta.join(`,`)}`,o=n.get(a);if(!o){let t=e.createBuffer();if(!t)throw Error(`engenty: accessory allocation failed`);let r=b(i);if(e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),o={buffer:t,count:r.length/7},n.set(a,o),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,o.buffer);for(let[n,i,a]of r){let r=e.getAttribLocation(t,n);e.enableVertexAttribArray(r),e.vertexAttribPointer(r,i,e.FLOAT,!1,28,a)}e.drawArrays(e.TRIANGLES,0,o.count)},dispose(){for(let t of n.values())e.deleteBuffer(t.buffer);n.clear()}}}var S=`${y}
151
+ `;function C(e){let t=[];for(let n=0;n<e.extraMeta.length/4;n++){let[r,,i,a]=e.extraMeta.slice(n*4,n*4+4);if(r!==2&&!(r===3&&a>.5))continue;let[o,s,c,l]=e.extras.slice(n*4,n*4+4),u=r===2?16:32,d=(e,t)=>{let a=e/u*(r===2?Math.PI:l*2)-(r===2?0:l),d=t/16*Math.PI*2,f=r===2?[Math.sin(a)*Math.cos(d),-Math.cos(a),Math.sin(a)*Math.sin(d)]:[Math.sin(a)*Math.cos(d),-Math.cos(a)*Math.cos(d),Math.sin(d)],p=r===2?[o,s,0]:[o+Math.sin(a)*c,s-Math.cos(a)*c,0],m=r===2?c:i*.5;return[...p.map((e,t)=>e+f[t]*m),...f,n]},f=(e,n,r)=>{let i=n.map((t,n)=>t-e[n]),a=r.map((t,n)=>t-e[n]),o=[i[1]*a[2]-i[2]*a[1],i[2]*a[0]-i[0]*a[2],i[0]*a[1]-i[1]*a[0]].reduce((t,n,r)=>t+n*e[r+3],0)<0?[e,r,n]:[e,n,r];for(let e of o)t.push(...e)};for(let e=0;e<u;e++)for(let t=0;t<16;t++){let n=d(e,t),r=d(e+1,t),i=d(e+1,t+1),a=d(e,t+1);f(n,r,i),f(n,i,a)}}return new Float32Array(t)}function w(e,t){let n=new Map,r=[[`aPosition`,3,0],[`aNormal`,3,12],[`aExtra`,1,24]];return{draw(i){let a=`${i.extras.join(`,`)}:${i.extraMeta.join(`,`)}`,o=n.get(a);if(!o){let t=e.createBuffer();if(!t)throw Error(`engenty: accessory allocation failed`);let r=C(i);if(e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),o={buffer:t,count:r.length/7},n.set(a,o),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,o.buffer);for(let[n,i,a]of r){let r=e.getAttribLocation(t,n);e.enableVertexAttribArray(r),e.vertexAttribPointer(r,i,e.FLOAT,!1,28,a)}e.drawArrays(e.TRIANGLES,0,o.count)},dispose(){for(let t of n.values())e.deleteBuffer(t.buffer);n.clear()}}}var T=`${S}
152
152
  in vec3 aPosition;
153
153
  in vec3 aNormal;
154
154
  in float aExtra;
@@ -163,7 +163,7 @@ void main(){
163
163
  vAlpha=mix(uExtraMeta[index].y,1.0,0.65);
164
164
  gl_Position=projectCoat(poseCoat(p));
165
165
  }
166
- `,C=`${y}
166
+ `,E=`${S}
167
167
  in vec3 vNormal;
168
168
  in float vAlpha;
169
169
  out vec4 outColor;
@@ -176,7 +176,7 @@ void main(){
176
176
  color+=uTip*pow(1.0-abs(n.z),3.0)*0.2;
177
177
  outColor=vec4(color*vAlpha,vAlpha);
178
178
  }
179
- `,w={inflate:27,softness:.05,clarity:.15},T=`uResolution.uTime.uBlobs.uFalloff.uScale.uFur.uPeriod.uInflate.uDensity.uThick.uLean.uLight.uBody.uDeep.uTip.uEye.uWind.uGaze.uTurn.uGoggles.uExtras.uExtraMeta.uWobble.uClarity.uSoftness.uPull`.split(`.`);function E(e,t,n){let r=e.createShader(t);if(!r)throw Error(`engenty fur: could not create shader`);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){let t=e.getShaderInfoLog(r);throw e.deleteShader(r),Error(`engenty fur: shader compile failed — ${t}`)}return r}function D(e,t,n){let r=e.getContext(`webgl2`,{alpha:!0,antialias:!0,depth:!0,premultipliedAlpha:!0,preserveDrawingBuffer:!1,stencil:!1});if(!r)return null;let i=null;try{let e=E(r,r.VERTEX_SHADER,n.vertex),a=E(r,r.FRAGMENT_SHADER,t);if(i=r.createProgram(),!i)throw Error(`engenty fur: could not create program`);if(r.attachShader(i,e),r.attachShader(i,a),r.linkProgram(i),r.deleteShader(e),r.deleteShader(a),!r.getProgramParameter(i,r.LINK_STATUS))throw Error(`engenty fur: link failed — ${r.getProgramInfoLog(i)}`)}catch(e){return i&&r.deleteProgram(i),console.error(e),null}let a={};for(let e of T)a[e]=r.getUniformLocation(i,e);let o=r.createVertexArray();r.bindVertexArray(o);let s=n.geometry(r,i),c=r.useProgram.bind(r);r.enable(r.BLEND),r.blendFunc(r.ONE,r.ONE_MINUS_SRC_ALPHA);let l=!1,u=1;return{dispose(){l||(l=!0,s.dispose(),r.deleteVertexArray(o),r.deleteProgram(i))},render(e){l||(c(i),r.bindVertexArray(o),r.uniform2f(a.uResolution,u,u),r.uniform1f(a.uTime,e.time),r.uniform4fv(a.uBlobs,e.blobs),r.uniform1f(a.uFalloff,e.falloff),r.uniform1f(a.uScale,e.scale),r.uniform1f(a.uFur,e.fur),r.uniform1f(a.uPeriod,e.period),r.uniform1f(a.uInflate,e.inflate),r.uniform1f(a.uDensity,e.density),r.uniform1f(a.uThick,e.thick),r.uniform1f(a.uClarity,e.clarity),r.uniform1f(a.uSoftness,e.softness??w.softness),r.uniform4fv(a.uPull,e.pull??[60,60,0,0]),r.uniform2fv(a.uLean,e.lean),r.uniform3fv(a.uLight,e.light),r.uniform3fv(a.uBody,e.body),r.uniform3fv(a.uDeep,e.deep),r.uniform3fv(a.uTip,e.tip),r.uniform3fv(a.uEye,e.eye),r.uniform1f(a.uWind,e.wind),r.uniform2fv(a.uGaze,e.gaze),r.uniform2fv(a.uTurn,e.turn??[0,0]),r.uniform1f(a.uGoggles,+!!e.goggles),r.uniform4fv(a.uExtras,e.extras),r.uniform4fv(a.uExtraMeta,e.extraMeta),r.uniform2fv(a.uWobble,e.wobble),r.enable(r.SCISSOR_TEST),r.scissor(0,0,u,u),r.enable(r.DEPTH_TEST),r.depthFunc(r.LEQUAL),r.depthMask(!0),r.frontFace(r.CW),n.doubleSided?r.disable(r.CULL_FACE):(r.enable(r.CULL_FACE),r.cullFace(r.BACK)),n.clear!==!1&&(r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT|r.DEPTH_BUFFER_BIT)),r.depthMask(n.depthWrite!==!1),s.draw(e))},viewport(e){l||(u=e,r.viewport(0,0,e,e))}}}var O=new Map,k=[[0,5,1,6],[0,1,2,6],[0,2,3,6],[0,3,7,6],[0,7,4,6],[0,4,5,6]];function A(e){return`${e.blobs.join(`,`)}:${e.falloff}:${e.inflate}`}function j(e,t){let n=0,r=[0,0,0];for(let i=0;i<t.blobs.length;i+=4){let a=t.blobs[i+2],o=t.blobs[i+3];if(a<=0||o<=0)continue;let s=a*t.inflate/30,c=e[0]-t.blobs[i],l=e[1]-t.blobs[i+1],u=e[2],d=Math.exp(-t.falloff*(c*c/(a*a)+l*l/(o*o)+u*u/(s*s)));n+=d,r[0]+=d*c/(a*a),r[1]+=d*l/(o*o),r[2]+=d*u/(s*s)}let i=Math.hypot(...r)||1;return{value:n,normal:[r[0]/i,r[1]/i,r[2]/i]}}function M(e){let t=A(e),n=O.get(t);if(n)return n;let r=[1/0,1/0,1/0],i=[-1/0,-1/0,-1/0];for(let t=0;t<e.blobs.length;t+=4){if(e.blobs[t+2]<=0)continue;let n=[e.blobs[t],e.blobs[t+1],0],a=[e.blobs[t+2],e.blobs[t+3],e.blobs[t+2]*e.inflate/30];for(let e=0;e<3;e++)r[e]=Math.min(r[e],n[e]-a[e]*1.5),i[e]=Math.max(i[e],n[e]+a[e]*1.5)}let a=2.7,[o,s,c]=i.map((e,t)=>Math.ceil((e-r[t])/a)+1),l=[],u=[];for(let t=0;t<c;t++)for(let n=0;n<s;n++)for(let i=0;i<o;i++){let o=[r[0]+i*a,r[1]+n*a,r[2]+t*a];l.push(o),u.push(j(o,e).value)}let d=Math.exp(-e.falloff),f=[],p=0,m=(e,t)=>{let n=(d-u[e])/(u[t]-u[e]);return[0,1,2].map(r=>l[e][r]+(l[t][r]-l[e][r])*n)},h=(t,n,r)=>{let i=n.map((e,n)=>e-t[n]),a=r.map((e,n)=>e-t[n]),o=[i[1]*a[2]-i[2]*a[1],i[2]*a[0]-i[0]*a[2],i[0]*a[1]-i[1]*a[0]],s=Math.hypot(...o)*.5;if(s<1e-9)return;let c=j(t,e).normal,l=o.reduce((e,t,n)=>e+t*c[n],0)<0?[t,r,n]:[t,n,r];for(let t of l)f.push(...t,...j(t,e).normal);p+=s};for(let e=0;e<c-1;e++)for(let t=0;t<s-1;t++)for(let n=0;n<o-1;n++){let r=n+o*(t+s*e),i=o*s,a=[r,r+1,r+o+1,r+o,r+i,r+i+1,r+i+o+1,r+i+o];if(!(a.every(e=>u[e]<d)||a.every(e=>u[e]>=d)))for(let e of k){let t=e.map(e=>a[e]).filter(e=>u[e]>=d),n=e.map(e=>a[e]).filter(e=>u[e]<d);if(t.length===1)h(...n.map(e=>m(t[0],e)));else if(t.length===3)h(...t.map(e=>m(n[0],e)));else if(t.length===2){let e=m(t[0],n[0]),r=m(t[0],n[1]),i=m(t[1],n[0]),a=m(t[1],n[1]);h(e,r,i),h(r,a,i)}}}let g={vertices:new Float32Array(f),area:p};if(O.set(t,g),O.size>24){let e=O.keys().next().value;e&&O.delete(e)}return g}function te(e,t,n){let r=0,i=200;for(let a=0;a<24;a++){let a=(r+i)/2,o=0;for(let r=0;r<e.blobs.length;r+=4){let[i,s,c,l]=e.blobs.slice(r,r+4);c<=0||(o+=Math.exp(-e.falloff*(((t-i)/c)**2+((n-s)/l)**2+(a/(c*e.inflate/30))**2)))}o>Math.exp(-e.falloff)?r=a:i=a}return(r+i)/2}function ne(e){let t=[],[n,r,i]=e.eye,a=i*1.35,o=te(e,n,r),s=(e,n,r)=>{let i=n.map((t,n)=>t-e[n]),a=r.map((t,n)=>t-e[n]),o=[i[1]*a[2]-i[2]*a[1],i[2]*a[0]-i[0]*a[2],i[0]*a[1]-i[1]*a[0]];for(let i of o.reduce((t,n,r)=>t+n*e[r+3],0)<0?[e,r,n]:[e,n,r])t.push(...i)},c=(e,t,n)=>{for(let r=0;r<e;r++)for(let i=0;i<t;i++){let a=n(r/e,i/t),o=n((r+1)/e,i/t),c=n((r+1)/e,(i+1)/t),l=n(r/e,(i+1)/t);s(a,o,c),s(a,c,l)}},l=(e,t,i,a,s)=>c(96,16,(c,l)=>{let u=c*Math.PI*2,d=l*Math.PI*2,f=Math.cos(u)*Math.cos(d)/t,p=Math.sin(u)*Math.cos(d)/t,m=Math.sin(d)/a,h=Math.hypot(f,p,m);return[n+Math.cos(u)*(e+Math.cos(d)*t),r+Math.sin(u)*(e+Math.cos(d)*t),o+i+Math.sin(d)*a,f/h,p/h,m/h,s]});l(a*1.14,a*.2,.3,1.5,0),l(a*1.13,a*.14,2.1,1.8,1);for(let e=0;e<4;e++){let t=Math.PI/4+e*Math.PI/2,i=n+Math.cos(t)*a*1.13,s=r+Math.sin(t)*a*1.13;c(10,12,(e,t)=>{let n=e*Math.PI,r=t*Math.PI*2,a=[Math.sin(n)*Math.cos(r),Math.sin(n)*Math.sin(r),Math.cos(n)];return[i+a[0]*.65,s+a[1]*.65,o+3.9+a[2]*.4,...a,2]})}return c(18,96,(e,t)=>{let i=t*Math.PI*2,s=Math.cos(i)*e,c=Math.sin(i)*e,l=[s*.45,c*.45,1],u=Math.hypot(...l);return[n+s*a,r+c*a,o+2.4+2.3*(1-e*e),l[0]/u,l[1]/u,l[2]/u,3]}),new Float32Array(t)}function re(e,t){let n=new Map,r=[[`aPosition`,3,0],[`aNormal`,3,12],[`aMaterial`,1,24]];return{draw(i){if(!i.goggles)return;let a=`${A(i)}:${i.eye.join(`,`)}`,o=n.get(a);if(!o){let t=e.createBuffer();if(!t)throw Error(`engenty: goggle allocation failed`);let r=ne(i);if(e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),o={buffer:t,count:r.length/7},n.set(a,o),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,o.buffer);for(let[n,i,a]of r){let r=e.getAttribLocation(t,n);e.enableVertexAttribArray(r),e.vertexAttribPointer(r,i,e.FLOAT,!1,28,a)}e.drawArrays(e.TRIANGLES,0,o.count)},dispose(){for(let{buffer:t}of n.values())e.deleteBuffer(t);n.clear()}}}var N=`${y}
179
+ `,D={inflate:27,softness:.05,clarity:.15},O=`uResolution.uTime.uBlobs.uFalloff.uScale.uFur.uPeriod.uInflate.uDensity.uThick.uLean.uLight.uBody.uDeep.uTip.uEye.uWind.uGaze.uTurn.uGoggles.uExtras.uExtraMeta.uWobble.uClarity.uSoftness.uPull`.split(`.`);function k(e,t,n){let r=e.createShader(t);if(!r)throw Error(`engenty fur: could not create shader`);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){let t=e.getShaderInfoLog(r);throw e.deleteShader(r),Error(`engenty fur: shader compile failed — ${t}`)}return r}function A(e,t,n){let r=e.getContext(`webgl2`,{alpha:!0,antialias:!0,depth:!0,premultipliedAlpha:!0,preserveDrawingBuffer:!1,stencil:!1});if(!r)return null;let i=null;try{let e=k(r,r.VERTEX_SHADER,n.vertex),a=k(r,r.FRAGMENT_SHADER,t);if(i=r.createProgram(),!i)throw Error(`engenty fur: could not create program`);if(r.attachShader(i,e),r.attachShader(i,a),r.linkProgram(i),r.deleteShader(e),r.deleteShader(a),!r.getProgramParameter(i,r.LINK_STATUS))throw Error(`engenty fur: link failed — ${r.getProgramInfoLog(i)}`)}catch(e){return i&&r.deleteProgram(i),console.error(e),null}let a={};for(let e of O)a[e]=r.getUniformLocation(i,e);let o=r.createVertexArray();r.bindVertexArray(o);let s=n.geometry(r,i),c=r.useProgram.bind(r);r.enable(r.BLEND),r.blendFunc(r.ONE,r.ONE_MINUS_SRC_ALPHA);let l=!1,u=1;return{dispose(){l||(l=!0,s.dispose(),r.deleteVertexArray(o),r.deleteProgram(i))},render(e){l||(c(i),r.bindVertexArray(o),r.uniform2f(a.uResolution,u,u),r.uniform1f(a.uTime,e.time),r.uniform4fv(a.uBlobs,e.blobs),r.uniform1f(a.uFalloff,e.falloff),r.uniform1f(a.uScale,e.scale),r.uniform1f(a.uFur,e.fur),r.uniform1f(a.uPeriod,e.period),r.uniform1f(a.uInflate,e.inflate),r.uniform1f(a.uDensity,e.density),r.uniform1f(a.uThick,e.thick),r.uniform1f(a.uClarity,e.clarity),r.uniform1f(a.uSoftness,e.softness??D.softness),r.uniform4fv(a.uPull,e.pull??[60,60,0,0]),r.uniform2fv(a.uLean,e.lean),r.uniform3fv(a.uLight,e.light),r.uniform3fv(a.uBody,e.body),r.uniform3fv(a.uDeep,e.deep),r.uniform3fv(a.uTip,e.tip),r.uniform3fv(a.uEye,e.eye),r.uniform1f(a.uWind,e.wind),r.uniform2fv(a.uGaze,e.gaze),r.uniform2fv(a.uTurn,e.turn??[0,0]),r.uniform1f(a.uGoggles,+!!e.goggles),r.uniform4fv(a.uExtras,e.extras),r.uniform4fv(a.uExtraMeta,e.extraMeta),r.uniform2fv(a.uWobble,e.wobble),r.enable(r.SCISSOR_TEST),r.scissor(0,0,u,u),r.enable(r.DEPTH_TEST),r.depthFunc(r.LEQUAL),r.depthMask(!0),r.frontFace(r.CW),n.doubleSided?r.disable(r.CULL_FACE):(r.enable(r.CULL_FACE),r.cullFace(r.BACK)),n.clear!==!1&&(r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT|r.DEPTH_BUFFER_BIT)),r.depthMask(n.depthWrite!==!1),s.draw(e))},viewport(e){l||(u=e,r.viewport(0,0,e,e))}}}var j=new Map,M=[[0,5,1,6],[0,1,2,6],[0,2,3,6],[0,3,7,6],[0,7,4,6],[0,4,5,6]];function N(e){return`${e.blobs.join(`,`)}:${e.falloff}:${e.inflate}`}function P(e,t){let n=0,r=[0,0,0];for(let i=0;i<t.blobs.length;i+=4){let a=t.blobs[i+2],o=t.blobs[i+3];if(a<=0||o<=0)continue;let s=a*t.inflate/30,c=e[0]-t.blobs[i],l=e[1]-t.blobs[i+1],u=e[2],d=Math.exp(-t.falloff*(c*c/(a*a)+l*l/(o*o)+u*u/(s*s)));n+=d,r[0]+=d*c/(a*a),r[1]+=d*l/(o*o),r[2]+=d*u/(s*s)}let i=Math.hypot(...r)||1;return{value:n,normal:[r[0]/i,r[1]/i,r[2]/i]}}function F(e){let t=N(e),n=j.get(t);if(n)return n;let r=[1/0,1/0,1/0],i=[-1/0,-1/0,-1/0];for(let t=0;t<e.blobs.length;t+=4){if(e.blobs[t+2]<=0)continue;let n=[e.blobs[t],e.blobs[t+1],0],a=[e.blobs[t+2],e.blobs[t+3],e.blobs[t+2]*e.inflate/30];for(let e=0;e<3;e++)r[e]=Math.min(r[e],n[e]-a[e]*1.5),i[e]=Math.max(i[e],n[e]+a[e]*1.5)}let a=2.7,[o,s,c]=i.map((e,t)=>Math.ceil((e-r[t])/a)+1),l=[],u=[];for(let t=0;t<c;t++)for(let n=0;n<s;n++)for(let i=0;i<o;i++){let o=[r[0]+i*a,r[1]+n*a,r[2]+t*a];l.push(o),u.push(P(o,e).value)}let d=Math.exp(-e.falloff),f=[],p=0,m=(e,t)=>{let n=(d-u[e])/(u[t]-u[e]);return[0,1,2].map(r=>l[e][r]+(l[t][r]-l[e][r])*n)},h=(t,n,r)=>{let i=n.map((e,n)=>e-t[n]),a=r.map((e,n)=>e-t[n]),o=[i[1]*a[2]-i[2]*a[1],i[2]*a[0]-i[0]*a[2],i[0]*a[1]-i[1]*a[0]],s=Math.hypot(...o)*.5;if(s<1e-9)return;let c=P(t,e).normal,l=o.reduce((e,t,n)=>e+t*c[n],0)<0?[t,r,n]:[t,n,r];for(let t of l)f.push(...t,...P(t,e).normal);p+=s};for(let e=0;e<c-1;e++)for(let t=0;t<s-1;t++)for(let n=0;n<o-1;n++){let r=n+o*(t+s*e),i=o*s,a=[r,r+1,r+o+1,r+o,r+i,r+i+1,r+i+o+1,r+i+o];if(!(a.every(e=>u[e]<d)||a.every(e=>u[e]>=d)))for(let e of M){let t=e.map(e=>a[e]).filter(e=>u[e]>=d),n=e.map(e=>a[e]).filter(e=>u[e]<d);if(t.length===1)h(...n.map(e=>m(t[0],e)));else if(t.length===3)h(...t.map(e=>m(n[0],e)));else if(t.length===2){let e=m(t[0],n[0]),r=m(t[0],n[1]),i=m(t[1],n[0]),a=m(t[1],n[1]);h(e,r,i),h(r,a,i)}}}let g={vertices:new Float32Array(f),area:p};if(j.set(t,g),j.size>24){let e=j.keys().next().value;e&&j.delete(e)}return g}function te(e,t,n){let r=0,i=200;for(let a=0;a<24;a++){let a=(r+i)/2,o=0;for(let r=0;r<e.blobs.length;r+=4){let[i,s,c,l]=e.blobs.slice(r,r+4);c<=0||(o+=Math.exp(-e.falloff*(((t-i)/c)**2+((n-s)/l)**2+(a/(c*e.inflate/30))**2)))}o>Math.exp(-e.falloff)?r=a:i=a}return(r+i)/2}function ne(e){let t=[],[n,r,i]=e.eye,a=i*1.35,o=te(e,n,r),s=(e,n,r)=>{let i=n.map((t,n)=>t-e[n]),a=r.map((t,n)=>t-e[n]),o=[i[1]*a[2]-i[2]*a[1],i[2]*a[0]-i[0]*a[2],i[0]*a[1]-i[1]*a[0]];for(let i of o.reduce((t,n,r)=>t+n*e[r+3],0)<0?[e,r,n]:[e,n,r])t.push(...i)},c=(e,t,n)=>{for(let r=0;r<e;r++)for(let i=0;i<t;i++){let a=n(r/e,i/t),o=n((r+1)/e,i/t),c=n((r+1)/e,(i+1)/t),l=n(r/e,(i+1)/t);s(a,o,c),s(a,c,l)}},l=(e,t,i,a,s)=>c(96,16,(c,l)=>{let u=c*Math.PI*2,d=l*Math.PI*2,f=Math.cos(u)*Math.cos(d)/t,p=Math.sin(u)*Math.cos(d)/t,m=Math.sin(d)/a,h=Math.hypot(f,p,m);return[n+Math.cos(u)*(e+Math.cos(d)*t),r+Math.sin(u)*(e+Math.cos(d)*t),o+i+Math.sin(d)*a,f/h,p/h,m/h,s]});l(a*1.14,a*.2,.3,1.5,0),l(a*1.13,a*.14,2.1,1.8,1);for(let e=0;e<4;e++){let t=Math.PI/4+e*Math.PI/2,i=n+Math.cos(t)*a*1.13,s=r+Math.sin(t)*a*1.13;c(10,12,(e,t)=>{let n=e*Math.PI,r=t*Math.PI*2,a=[Math.sin(n)*Math.cos(r),Math.sin(n)*Math.sin(r),Math.cos(n)];return[i+a[0]*.65,s+a[1]*.65,o+3.9+a[2]*.4,...a,2]})}return c(18,96,(e,t)=>{let i=t*Math.PI*2,s=Math.cos(i)*e,c=Math.sin(i)*e,l=[s*.45,c*.45,1],u=Math.hypot(...l);return[n+s*a,r+c*a,o+2.4+2.3*(1-e*e),l[0]/u,l[1]/u,l[2]/u,3]}),new Float32Array(t)}function re(e,t){let n=new Map,r=[[`aPosition`,3,0],[`aNormal`,3,12],[`aMaterial`,1,24]];return{draw(i){if(!i.goggles)return;let a=`${N(i)}:${i.eye.join(`,`)}`,o=n.get(a);if(!o){let t=e.createBuffer();if(!t)throw Error(`engenty: goggle allocation failed`);let r=ne(i);if(e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),o={buffer:t,count:r.length/7},n.set(a,o),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,o.buffer);for(let[n,i,a]of r){let r=e.getAttribLocation(t,n);e.enableVertexAttribArray(r),e.vertexAttribPointer(r,i,e.FLOAT,!1,28,a)}e.drawArrays(e.TRIANGLES,0,o.count)},dispose(){for(let{buffer:t}of n.values())e.deleteBuffer(t);n.clear()}}}var I=`${S}
180
180
  in vec3 aPosition;
181
181
  in vec3 aNormal;
182
182
  in float aMaterial;
@@ -187,7 +187,7 @@ void main(){
187
187
  vMaterial=int(aMaterial+0.5);
188
188
  gl_Position=projectCoat(poseCoat(aPosition));
189
189
  }
190
- `,ie=`${y}
190
+ `,ie=`${S}
191
191
  in vec3 vNormal;
192
192
  flat in int vMaterial;
193
193
  out vec4 outColor;
@@ -207,7 +207,125 @@ void main(){
207
207
  vec3 color=base*(0.4+diffuse*0.75)+reflected*(vMaterial==0?0.04:0.27)+vec3(1.0,0.9,0.65)*spec*(vMaterial==0?0.1:0.8);
208
208
  outColor=vec4(color,1.0);
209
209
  }
210
- `,P=`${y}
210
+ `,ae=`/studio/assets/goose-helmet-Cvc7KjUg.bin`,oe=`/studio/assets/goose-helmet-livery-CZD9u0XS.webp`,L=18,R=null,z=new WeakMap;async function se(){let e=new Image;return e.src=oe,await e.decode(),e}function ce(){return R??=Promise.all([fetch(ae).then(e=>e.arrayBuffer()),se()]).then(([e,t])=>{let n=new DataView(e,0,20);if(String.fromCharCode(...new Uint8Array(e,0,4))!==`GHLM`)throw Error(`engenty: helmet mesh is not a GHLM file`);let r=n.getUint32(4,!0),i=n.getUint32(8,!0),a=20+r*L;return{vertices:e.slice(20,a),indices:new Uint16Array(e.slice(a,a+i*2)),opaqueCount:n.getUint32(12,!0),positionScale:n.getFloat32(16,!0),livery:t}}),R}function le(e,t){let n=z.get(e);if(n)return n;let r=e.createBuffer(),i=e.createBuffer(),a=e.createTexture();if(!(r&&i&&a))throw Error(`engenty: helmet allocation failed`);e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,t.vertices,e.STATIC_DRAW);let o=e.getParameter(e.VERTEX_ARRAY_BINDING);e.bindVertexArray(null),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,i),e.bufferData(e.ELEMENT_ARRAY_BUFFER,t.indices,e.STATIC_DRAW),e.bindVertexArray(o),e.bindTexture(e.TEXTURE_2D,a),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!0),e.texImage2D(e.TEXTURE_2D,0,e.RGB,e.RGB,e.UNSIGNED_BYTE,t.livery),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!1),e.generateMipmap(e.TEXTURE_2D),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);let s=e.getExtension(`EXT_texture_filter_anisotropic`);s&&e.texParameterf(e.TEXTURE_2D,s.TEXTURE_MAX_ANISOTROPY_EXT,8);let c={vertex:r,index:i,texture:a,opaqueCount:t.opaqueCount,totalCount:t.indices.length,positionScale:t.positionScale,users:0};return z.set(e,c),c}function ue(e,t,n,r){let i=null,a=!1,o=!1,s=e.getParameter(e.VERTEX_ARRAY_BINDING),c=e.getUniformLocation(t,`uHelmetFit`),l=e.getUniformLocation(t,`uHelmetAspect`),u=e.getUniformLocation(t,`uLivery`),f=e.getUniformLocation(t,`uHeadUnit`),p=n=>{let r=e.getParameter(e.VERTEX_ARRAY_BINDING);e.bindVertexArray(s),e.bindBuffer(e.ARRAY_BUFFER,n.vertex),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,n.index);let a=(n,r,i,a,o)=>{let s=e.getAttribLocation(t,n);s<0||(e.enableVertexAttribArray(s),e.vertexAttribPointer(s,r,i,a,L,o))};a(`aPosition`,3,e.SHORT,!1,0),a(`aNormal`,3,e.SHORT,!0,6),a(`aUv`,2,e.UNSIGNED_SHORT,!0,12),a(`aMaterial`,1,e.UNSIGNED_SHORT,!1,16),e.bindVertexArray(r),n.users++,i=n};return{draw(t){if(!(t.gooseHelmet&&t.helmetKind))return;if(!i){a||(a=!0,ce().then(t=>{o||p(le(e,t))},e=>console.error(e)));return}let m=d[t.helmetKind][n];e.uniform4f(c,m.scale/i.positionScale,m.x,m.y,m.z),e.uniform3f(l,m.width,m.height,m.depth),e.uniform1f(f,1/i.positionScale),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,i.texture),e.uniform1i(u,0),e.bindVertexArray(s),r===`shell`?e.drawElements(e.TRIANGLES,i.opaqueCount,e.UNSIGNED_SHORT,0):e.drawElements(e.TRIANGLES,i.totalCount-i.opaqueCount,e.UNSIGNED_SHORT,i.opaqueCount*2)},dispose(){o=!0,i&&(i.users--,!(i.users>0)&&(z.delete(e),e.deleteBuffer(i.vertex),e.deleteBuffer(i.index),e.deleteTexture(i.texture)))}}}var B=`${S}
211
+ in vec3 aPosition;
212
+ in vec3 aNormal;
213
+ in vec2 aUv;
214
+ in float aMaterial;
215
+ // x: form units per stored position step, yzw: the head centre in form space.
216
+ uniform vec4 uHelmetFit;
217
+ uniform vec3 uHelmetAspect;
218
+ // Head units per stored position step.
219
+ uniform float uHeadUnit;
220
+ out vec3 vNormal;
221
+ out vec2 vUv;
222
+ out float vHeight;
223
+ flat out int vMaterial;
224
+
225
+ // The rigid helmet follows the head turn, lean and bob. On Jelly it also rides the sway and
226
+ // squash of the head under it, as one piece, so the head never slides out from inside it.
227
+ vec3 poseHelmet(vec3 p) {
228
+ float w = TAU * uTime / uPeriod;
229
+ vec3 q = p - vec3(60.0, 60.0, 0.0);
230
+ #ifdef JELLY_COAT
231
+ float softness = clamp(uSoftness, 0.0, 1.5);
232
+ vec2 lag = clamp(uWobble, vec2(-7.0), vec2(7.0));
233
+ float phase = TAU * uTime / uPeriod;
234
+ float squash = softness * (sin(phase) * 0.08 + sin(phase * 1.7) * 0.012 + lag.y * 0.012);
235
+ // The crown sits about 20 form units above the head centre (uHelmetFit.z).
236
+ float crownY = uHelmetFit.z - 20.0;
237
+ float top = clamp(1.0 - crownY / 125.0, 0.0, 1.0);
238
+ q.x += softness * lag.x * 1.15 * top * top;
239
+ q.y += (crownY - 60.0) * squash;
240
+ #endif
241
+ q.xy += uLean * (1.15 - p.y / 120.0) * 0.3;
242
+ q = rotateCoat(q);
243
+ q.xy += vec2(60.0 + sin(w) * 1.5, 60.0 + cos(w * 0.8) * 1.1);
244
+ return q;
245
+ }
246
+
247
+ void main() {
248
+ vec3 p = aPosition * uHelmetFit.x * uHelmetAspect + uHelmetFit.yzw;
249
+ vNormal = rotateCoat(normalize(aNormal / uHelmetAspect));
250
+ vUv = aUv;
251
+ vHeight = aPosition.y * uHeadUnit;
252
+ vMaterial = int(aMaterial + 0.5);
253
+ gl_Position = projectCoat(poseHelmet(p));
254
+ }
255
+ `,de=`${S}
256
+ in vec3 vNormal;
257
+ in vec2 vUv;
258
+ in float vHeight;
259
+ flat in int vMaterial;
260
+ uniform sampler2D uLivery;
261
+ out vec4 outColor;
262
+
263
+ const vec3 ENAMEL = vec3(0.82, 0.05, 0.094);
264
+
265
+ // Bright overhead softboxes over a warm floor, as in the Blender portrait.
266
+ vec3 studio(vec3 r) {
267
+ float up = clamp(-r.y * 0.5 + 0.5, 0.0, 1.0);
268
+ vec3 c = mix(vec3(0.18, 0.16, 0.15), vec3(0.92, 0.9, 0.86), smoothstep(0.4, 0.95, up));
269
+ float key = smoothstep(0.93, 0.99, dot(r, normalize(vec3(-0.6, -0.55, 0.58))));
270
+ float rim = smoothstep(0.95, 0.995, dot(r, normalize(vec3(0.75, -0.35, 0.55))));
271
+ return c + vec3(1.0, 0.98, 0.95) * (key * 1.2 + rim * 0.5);
272
+ }
273
+
274
+ void main() {
275
+ vec3 n = normalize(vNormal);
276
+ if (!gl_FrontFacing) n = -n;
277
+ vec3 view = vec3(0.0, 0.0, 1.0);
278
+ vec3 light = normalize(uLight);
279
+ float ndv = max(dot(n, view), 0.0);
280
+ float diffuse = max(dot(n, light), 0.0);
281
+ vec3 r = reflect(-view, n);
282
+ float fresnel = 0.04 + 0.96 * pow(1.0 - ndv, 5.0);
283
+ float spec = pow(max(dot(n, normalize(light + view)), 0.0), 90.0);
284
+
285
+ if (vMaterial == 6) {
286
+ // Smoke polycarbonate: darker under the brow, clearer over the eye, with small studio glints.
287
+ float smoke = mix(0.74, 0.26, smoothstep(-0.7, -0.15, vHeight));
288
+ float alpha = smoke + 0.15 * fresnel;
289
+ vec3 tint = vec3(0.015, 0.025, 0.07);
290
+ float glint = smoothstep(0.965, 0.995, dot(r, normalize(vec3(-0.6, -0.55, 0.58))));
291
+ float band = smoothstep(0.75, 0.95, -r.y * 0.5 + 0.5) * 0.12;
292
+ vec3 reflection =
293
+ vec3(1.0, 0.98, 0.95) * (glint * 0.9 + band * 0.6 + fresnel * 0.06) + vec3(1.0) * spec * 0.3;
294
+ outColor = vec4(tint * alpha + reflection, min(1.0, alpha + glint * 0.5));
295
+ return;
296
+ }
297
+
298
+ vec3 base;
299
+ float gloss;
300
+ float metal = 0.0;
301
+ if (vMaterial == 1) {
302
+ base = texture(uLivery, vUv).rgb;
303
+ gloss = 0.3;
304
+ } else if (vMaterial == 0) {
305
+ base = ENAMEL;
306
+ gloss = 0.3;
307
+ } else if (vMaterial == 2) {
308
+ base = ENAMEL * 0.7;
309
+ gloss = 0.2;
310
+ } else if (vMaterial == 3) {
311
+ base = vec3(0.62, 0.64, 0.66);
312
+ gloss = 0.5;
313
+ metal = 0.7;
314
+ } else if (vMaterial == 4) {
315
+ base = vec3(0.022, 0.026, 0.036);
316
+ gloss = 0.03;
317
+ } else {
318
+ base = vec3(0.012, 0.018, 0.035);
319
+ gloss = 0.3;
320
+ }
321
+ vec3 color = base * (0.8 + 0.38 * diffuse);
322
+ vec3 env = studio(r);
323
+ color = mix(color, env * mix(vec3(1.0), base, 0.4), metal);
324
+ color += env * gloss * (0.03 + 0.7 * fresnel) * (1.0 - metal * 0.5);
325
+ color += vec3(1.0, 0.97, 0.92) * spec * gloss * 1.6;
326
+ outColor = vec4(color, 1.0);
327
+ }
328
+ `,V=`${S}
211
329
  in vec3 aPosition;
212
330
  in vec3 aNormal;
213
331
  out vec3 vLocal;
@@ -217,11 +335,11 @@ void main(){
217
335
  vNormal=poseNormal(aPosition,aNormal);
218
336
  gl_Position=projectCoat(poseCoat(aPosition));
219
337
  }
220
- `,F=`
338
+ `,H=`
221
339
  in vec3 vLocal;
222
340
  in vec3 vNormal;
223
341
  out vec4 outColor;
224
- `,ae=`${y}${F}
342
+ `,fe=`${S}${H}
225
343
  void main(){
226
344
  vec2 p=vLocal.xy;
227
345
  vec3 n=normalize(vNormal),light=normalize(uLight);
@@ -254,7 +372,7 @@ void main(){
254
372
  vec4 goggles=gogglesOver(p,aa,front);
255
373
  outColor=vec4(goggles.rgb+color*(1.0-goggles.a),1.0);
256
374
  }
257
- `,I=`${y}${F}
375
+ `,pe=`${S}${H}
258
376
  /** Luminance, for turning a reflection into coverage. */
259
377
  float lum(vec3 c) { return dot(c, vec3(0.2126, 0.7152, 0.0722)); }
260
378
 
@@ -395,7 +513,7 @@ void main(){
395
513
  vec4 goggles = gogglesOver(p, aaPx, front);
396
514
  outColor = goggles + acc * (1.0 - goggles.a);
397
515
  }
398
- `,L=8,R=256;function oe(e,t,n,r,i){let a=-Math.sin(n[0]),o=Math.cos(n[0])*Math.sin(n[1]),s=Math.cos(n[0])*Math.cos(n[1]),c=1/0,l=-1/0;for(let t=0;t<e.length;t+=L){let n=e[t]*a+e[t+1]*o+e[t+2]*s;c=Math.min(c,n),l=Math.max(l,n)}i.fill(0);let u=255/Math.max(l-c,.001);for(let t=0;t<r.length;t++){let n=t*L,l=e[n]*a+e[n+1]*o+e[n+2]*s,d=Math.min(255,Math.max(0,Math.floor((l-c)*u)));r[t]=d,i[d]++}let d=0;for(let e=0;e<R;e++){let t=i[e];i[e]=d,d+=t}for(let n=0;n<r.length;n++){let a=i[r[n]]++*L;for(let r=0;r<L;r++)t[a+r]=e[n*L+r]}}function se(e){return{roots:e,sorted:new Float32Array(e.length),buckets:new Uint16Array(e.length/L),counts:new Uint32Array(R),yaw:NaN,pitch:NaN}}function ce(e){let t=M(e),n=781,r=()=>(n=(n*1664525+1013904223)%4294967296,n/4294967296),i=[],a=Math.min(200,Math.max(10,e.density))**2/4e3,o=t.vertices;for(let e=0;e<o.length;e+=18){let t=[o[e+6]-o[e],o[e+7]-o[e+1],o[e+8]-o[e+2]],n=[o[e+12]-o[e],o[e+13]-o[e+1],o[e+14]-o[e+2]],s=Math.hypot(t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0])*.5*a,c=Math.floor(s)+ +(r()<s%1);for(let t=0;t<c;t++){let t=Math.sqrt(r()),n=r(),a=[1-t,t*(1-n),t*n],s=Array.from({length:6},(t,n)=>a.reduce((t,r,i)=>t+r*o[e+i*6+n],0)),c=Math.hypot(s[3],s[4],s[5]);i.push(s[0],s[1],s[2],s[3]/c,s[4]/c,s[5]/c,r(),r())}}return new Float32Array(i)}function z(e,t){let n=new Map,r=e.getAttribLocation(t,`aRoot`),i=e.getAttribLocation(t,`aNormal`),a=e.getAttribLocation(t,`aRandom`);return{draw(t){let o=`${A(t)}:${t.density}`,s=n.get(o);if(!s){let r=e.createBuffer();if(!r)throw Error(`engenty: strand allocation failed`);let i=ce(t);if(e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,i,e.DYNAMIC_DRAW),s={buffer:r,count:i.length/8,order:se(i)},n.set(o,s),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,s.buffer);let c=t.turn??[0,0],l=s.order;(l.yaw!==c[0]||l.pitch!==c[1])&&(oe(l.roots,l.sorted,c,l.buckets,l.counts),e.bufferSubData(e.ARRAY_BUFFER,0,l.sorted),l.yaw=c[0],l.pitch=c[1]);for(let[t,n,o]of[[r,3,0],[i,3,12],[a,2,24]])e.enableVertexAttribArray(t),e.vertexAttribPointer(t,n,e.FLOAT,!1,32,o),e.vertexAttribDivisor(t,1);e.drawArraysInstanced(e.TRIANGLE_STRIP,0,18,s.count)},dispose(){for(let t of n.values())e.deleteBuffer(t.buffer);n.clear()}}}var B=`${y}
516
+ `,U=8,W=256;function me(e,t,n,r,i){let a=-Math.sin(n[0]),o=Math.cos(n[0])*Math.sin(n[1]),s=Math.cos(n[0])*Math.cos(n[1]),c=1/0,l=-1/0;for(let t=0;t<e.length;t+=U){let n=e[t]*a+e[t+1]*o+e[t+2]*s;c=Math.min(c,n),l=Math.max(l,n)}i.fill(0);let u=255/Math.max(l-c,.001);for(let t=0;t<r.length;t++){let n=t*U,l=e[n]*a+e[n+1]*o+e[n+2]*s,d=Math.min(255,Math.max(0,Math.floor((l-c)*u)));r[t]=d,i[d]++}let d=0;for(let e=0;e<W;e++){let t=i[e];i[e]=d,d+=t}for(let n=0;n<r.length;n++){let a=i[r[n]]++*U;for(let r=0;r<U;r++)t[a+r]=e[n*U+r]}}function he(e){return{roots:e,sorted:new Float32Array(e.length),buckets:new Uint16Array(e.length/U),counts:new Uint32Array(W),yaw:NaN,pitch:NaN}}function ge(e){let t=F(e),n=781,r=()=>(n=(n*1664525+1013904223)%4294967296,n/4294967296),i=[],a=Math.min(200,Math.max(10,e.density))**2/4e3,o=t.vertices;for(let e=0;e<o.length;e+=18){let t=[o[e+6]-o[e],o[e+7]-o[e+1],o[e+8]-o[e+2]],n=[o[e+12]-o[e],o[e+13]-o[e+1],o[e+14]-o[e+2]],s=Math.hypot(t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0])*.5*a,c=Math.floor(s)+ +(r()<s%1);for(let t=0;t<c;t++){let t=Math.sqrt(r()),n=r(),a=[1-t,t*(1-n),t*n],s=Array.from({length:6},(t,n)=>a.reduce((t,r,i)=>t+r*o[e+i*6+n],0)),c=Math.hypot(s[3],s[4],s[5]);i.push(s[0],s[1],s[2],s[3]/c,s[4]/c,s[5]/c,r(),r())}}return new Float32Array(i)}function _e(e,t){let n=new Map,r=e.getAttribLocation(t,`aRoot`),i=e.getAttribLocation(t,`aNormal`),a=e.getAttribLocation(t,`aRandom`);return{draw(t){let o=`${N(t)}:${t.density}`,s=n.get(o);if(!s){let r=e.createBuffer();if(!r)throw Error(`engenty: strand allocation failed`);let i=ge(t);if(e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,i,e.DYNAMIC_DRAW),s={buffer:r,count:i.length/8,order:he(i)},n.set(o,s),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,s.buffer);let c=t.turn??[0,0],l=s.order;(l.yaw!==c[0]||l.pitch!==c[1])&&(me(l.roots,l.sorted,c,l.buckets,l.counts),e.bufferSubData(e.ARRAY_BUFFER,0,l.sorted),l.yaw=c[0],l.pitch=c[1]);for(let[t,n,o]of[[r,3,0],[i,3,12],[a,2,24]])e.enableVertexAttribArray(t),e.vertexAttribPointer(t,n,e.FLOAT,!1,32,o),e.vertexAttribDivisor(t,1);e.drawArraysInstanced(e.TRIANGLE_STRIP,0,18,s.count)},dispose(){for(let t of n.values())e.deleteBuffer(t.buffer);n.clear()}}}var ve=`${S}
399
517
  in vec3 aRoot;
400
518
  in vec3 aNormal;
401
519
  in vec2 aRandom;
@@ -440,7 +558,7 @@ void main(){
440
558
  vAcross=side;
441
559
  vCoverage=min(1.0,radius/(pixel*0.7))*socket*(1.0-strap*0.85);
442
560
  }
443
- `,V=`#version 300 es
561
+ `,ye=`#version 300 es
444
562
  precision highp float;
445
563
  in vec3 vColor;
446
564
  in float vAcross;
@@ -451,6 +569,7 @@ void main(){
451
569
  if(alpha<0.025)discard;
452
570
  outColor=vec4(vColor*alpha,alpha);
453
571
  }
454
- `;function H(e,t){let n=new Map,r=e.getAttribLocation(t,`aPosition`),i=e.getAttribLocation(t,`aNormal`);return{draw(t){let a=A(t),o=n.get(a);if(!o){let r=e.createBuffer();if(!r)throw Error(`engenty: body allocation failed`);let i=M(t);if(e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,i.vertices,e.STATIC_DRAW),o={buffer:r,count:i.vertices.length/6},n.set(a,o),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,o.buffer);for(let[t,n]of[[r,0],[i,12]])e.enableVertexAttribArray(t),e.vertexAttribPointer(t,3,e.FLOAT,!1,24,n);e.drawArrays(e.TRIANGLES,0,o.count)},dispose(){for(let t of n.values())e.deleteBuffer(t.buffer);n.clear()}}}function U(e,t){let n=D(e,t===`fur`?ae:I,{vertex:t===`fur`?P:P.replace(`#version 300 es`,`#version 300 es
455
- #define JELLY_COAT`),geometry:H});if(!n)return null;let r=[n];if(t===`fur`){let t=D(e,V,{vertex:B,geometry:z,clear:!1,doubleSided:!0,depthWrite:!1});if(!t)return n.dispose(),null;r.push(t)}let i=D(e,C,{vertex:S,geometry:x,clear:!1});if(!i){for(let e of r)e.dispose();return null}r.push(i);let a=D(e,ie,{vertex:t===`jelly`?N.replace(`#version 300 es`,`#version 300 es
456
- #define JELLY_COAT`):N,geometry:re,clear:!1});if(!a){for(let e of r)e.dispose();return null}return r.push(a),{render(e){for(let t of r)t.render(e)},viewport(e){for(let t of r)t.viewport(e)},dispose(){for(let e of r)e.dispose()}}}var W=new Map,G=new Set;function le(e){if(G.has(e)||typeof document>`u`)return null;let t=document.createElement(`canvas`);t.width=1,t.height=1;let n=U(t,e);return n?(t.addEventListener(`webglcontextlost`,t=>{t.preventDefault(),W.delete(e)}),{canvas:t,refs:0,renderer:n,size:0}):(G.add(e),null)}function ue(e=`fur`){let t=W.get(e);if(!t){let n=le(e);if(!n)return null;W.set(e,n),t=n}let n=t;n.refs+=1;let r=!1;return{drawInto(t,i,a){if(r||W.get(e)!==n)return;let o=i;o>n.size&&(n.size=o,n.canvas.width=o,n.canvas.height=o),n.renderer.viewport(o),n.renderer.render(a),t.clearRect(0,0,t.canvas.width,t.canvas.height),t.drawImage(n.canvas,0,n.canvas.height-o,o,o,0,0,t.canvas.width,t.canvas.height)},release(){r||(r=!0,--n.refs,n.refs<=0&&W.get(e)===n&&(n.renderer.dispose(),W.delete(e)))}}}var K=Math.PI/18;function q(e,t){let n=K/Math.max(1,Math.hypot(e,t));return[e*n,t===0?0:-t*n]}function J(e,t,n){if(n<=0)return;let r=3.8,i=Math.sqrt(110-r*r),a=Math.exp(-3.8*n),o=Math.cos(i*n),s=Math.sin(i*n);for(let[n,c,l]of[[`x`,`vx`,t[0]],[`y`,`vy`,t[1]]]){let t=e[n]-l,u=e[c];e[n]=l+a*(t*o+(u+r*t)/i*s),e[c]=a*(u*o-(r*u+110*t)/i*s)}}function de(e,t){let n={x:0,y:0,vx:0,vy:0},r=[60,60],i=null,a=[0,0],o=!1,s=n=>{if(!t()||n.button!==0||i!==null)return;let s=e.getBoundingClientRect(),c=(n.clientX-s.left)/s.width*152+-16,l=(n.clientY-s.top)/s.height*152+-16;Math.hypot(c-60,l-60)>48||(r[0]=c,r[1]=l,a=[n.clientX,n.clientY],i=n.pointerId,o=!1,e.setPointerCapture(i))},c=r=>{if(r.pointerId!==i)return;if(!t()){l(r);return}let s=e.getBoundingClientRect(),c=(r.clientX-a[0])/s.width*152,u=(r.clientY-a[1])/s.height*152,d=Math.min(1,18/(Math.hypot(c,u)||1));n.x=c*d,n.y=u*d,n.vx=0,n.vy=0,o||=Math.hypot(r.clientX-a[0],r.clientY-a[1])>4},l=t=>{t.pointerId===i&&(i=null,e.hasPointerCapture(t.pointerId)&&e.releasePointerCapture(t.pointerId))},u=e=>{o&&=(e.preventDefault(),e.stopPropagation(),!1)};return e.addEventListener(`pointerdown`,s),e.addEventListener(`pointermove`,c),e.addEventListener(`pointerup`,l),e.addEventListener(`pointercancel`,l),e.addEventListener(`lostpointercapture`,l),e.addEventListener(`click`,u,!0),{step(e){return i===null&&J(n,[0,0],e),[r[0],r[1],n.x,n.y]},dispose(){i!==null&&e.hasPointerCapture(i)&&e.releasePointerCapture(i),e.removeEventListener(`pointerdown`,s),e.removeEventListener(`pointermove`,c),e.removeEventListener(`pointerup`,l),e.removeEventListener(`pointercancel`,l),e.removeEventListener(`lostpointercapture`,l),e.removeEventListener(`click`,u,!0)}}}var Y={x:0,y:0},X=new Set,Z=!1;function fe(e){Y.x=e.clientX,Y.y=e.clientY;for(let e of X)e()}function pe(){return Y}function me(e){return!Z&&typeof window<`u`&&(Z=!0,Y.x=window.innerWidth*.62,Y.y=window.innerHeight*.28,window.addEventListener(`pointermove`,fe,{passive:!0})),X.add(e),()=>{X.delete(e)}}var Q=e(n(),1),he={high:{density:68,dprCap:2,thick:1},low:{density:40,dprCap:1,thick:1.15},medium:{density:55,dprCap:1.5,thick:1.05}},ge=1.7,$=0,_e=2.399963,ve=[-.42,-.72,.75],ye=30,be=.5,xe=e=>(e- -16)/152*100;function Se({className:e,motion:t=`auto`,animationSpeed:n=1,turn:i,coat:a=`fur`,goggles:c=!1,interactive:d=!0,look:p=null,kind:m=`round`,overrides:h,quality:g=`high`,size:_=260}){let v=(0,f.useRef)(null),y=(0,f.useRef)(null),b=(0,f.useRef)(0);b.current===0&&($+=1,b.current=$*_e);let x=(0,f.useRef)(null),[S,C]=(0,f.useState)(!0),T=o[m],E=(0,f.useMemo)(()=>s(T),[T]),D=(0,f.useMemo)(()=>l(T),[T]),O=(0,f.useMemo)(()=>r(T),[T]),k=(0,f.useRef)({animationSpeed:n,motion:t,turn:i,goggles:c,blobs:E,extras:D,form:T,interactive:d,kind:m,look:p,overrides:h,quality:g,scale:O,size:_});return k.current={animationSpeed:n,motion:t,turn:i,goggles:c,blobs:E,extras:D,form:T,interactive:d,kind:m,look:p,overrides:h,quality:g,scale:O,size:_},(0,f.useEffect)(()=>{v.current?.()},[m,h,g,_,d,p,c,t,n,i]),(0,f.useEffect)(()=>{let e=y.current,t=x.current;if(!(e&&t))return;let n=e.getContext(`2d`),r=n?ue(a):null;if(!(n&&r)){C(!1);return}let i=b.current,o=window.matchMedia(`(prefers-reduced-motion: reduce)`),s={x:0,y:0},c={x:0,y:0},l={vx:0,vy:0,x:0,y:0},u=0,d=!0,f=0,p=0,m=a===`jelly`?de(t,()=>k.current.interactive&&k.current.motion!==`pause`&&(k.current.motion===`play`||!o.matches)):null,h=g=>{u=0;let _=k.current,v=he[_.quality],y=_.motion===`pause`||_.motion===`auto`&&o.matches,b=y?0:Math.min((g-(p||g))/1e3,.1);f+=b*Math.max(.1,Math.min(2,_.animationSpeed)),p=g;let x=Math.min(window.devicePixelRatio||1,v.dprCap),S=Math.max(1,Math.round(_.size*x));e.width!==S&&(e.width=S,e.height=S);let C=120*S/(ge*152),T=_.overrides?.fur??_.form.fur;if((_.interactive||_.look)&&!y){let e,n,r,i;if(_.look)e=_.look.x,n=_.look.y,r=Math.hypot(e,n)||1,i=Math.min(1,r);else{let a=t.getBoundingClientRect(),o=pe();e=o.x-(a.left+a.width*.5),n=o.y-(a.top+a.height*.48),r=Math.hypot(e,n)||1,i=.35+Math.min(1,r/(a.width*2.4||1))*.65}s.x+=(e/r*5.5*i-s.x)*.16,s.y+=(n/r*3.5*i-s.y)*.16,c.x+=(e/r*i-c.x)*.24,c.y+=(n/r*.9*i-c.y)*.24}J(l,[s.x,s.y],b*Math.max(.1,Math.min(2,_.animationSpeed)));let E=ee(t,_.kind);r.drawInto(n,S,{blobs:_.blobs,clarity:_.overrides?.clarity??w.clarity,softness:_.overrides?.softness??w.softness,pull:m?.step(b*Math.max(.1,Math.min(2,_.animationSpeed))),body:E.body,deep:E.deep,density:Math.min(_.overrides?.density??v.density,C),extraMeta:_.extras.meta,extras:_.extras.geometry,eye:[_.form.eye.x,_.form.eye.y,_.form.eye.r],gaze:[c.x,c.y],goggles:_.goggles,turn:_.turn?q(_.turn.yaw/K,_.turn.pitch/K):q(c.x,c.y),fur:T,inflate:_.overrides?.inflate??(a===`jelly`?w.inflate:ye),lean:[s.x,s.y],light:ve,period:_.form.period,scale:_.scale,falloff:_.form.falloff,thick:_.overrides?.thick??v.thick,time:f+i,tip:E.tip,wind:_.overrides?.wind??be,wobble:[l.x-s.x,l.y-s.y]}),d&&!y&&(u=requestAnimationFrame(h))},g=()=>{u||=(p=0,requestAnimationFrame(h))},_=new IntersectionObserver(([e])=>{d=e?.isIntersecting??!0,d?g():u&&=(cancelAnimationFrame(u),0)},{rootMargin:`120px`});_.observe(t),v.current=g;let S=me(g);return o.addEventListener(`change`,g),g(),()=>{v.current=null,_.disconnect(),m?.dispose(),S(),o.removeEventListener(`change`,g),u&&cancelAnimationFrame(u),r.release()}},[a]),S?(0,Q.jsxs)(`div`,{"aria-hidden":`true`,className:e,ref:x,style:{height:_,position:`relative`,width:_},children:[(0,Q.jsx)(`div`,{style:{background:`radial-gradient(closest-side, rgb(0 0 0 / 0.2), transparent)`,filter:`blur(4px)`,height:`${T.shadowRx*50/152}%`,left:`50%`,position:`absolute`,top:`${xe(110)}%`,transform:`translate(-50%, -50%)`,width:`${T.shadowRx*2.5*100/152}%`}}),(0,Q.jsx)(`canvas`,{ref:y,style:{display:`block`,height:_,width:_,touchAction:a===`jelly`&&d&&t!==`pause`?`none`:void 0,cursor:a===`jelly`&&d?`grab`:void 0}})]}):(0,Q.jsx)(u,{className:e,goggles:c,kind:m,size:_})}export{Se as FluffyEngenty};
572
+ `;function be(e,t){let n=new Map,r=e.getAttribLocation(t,`aPosition`),i=e.getAttribLocation(t,`aNormal`);return{draw(t){let a=N(t),o=n.get(a);if(!o){let r=e.createBuffer();if(!r)throw Error(`engenty: body allocation failed`);let i=F(t);if(e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,i.vertices,e.STATIC_DRAW),o={buffer:r,count:i.vertices.length/6},n.set(a,o),n.size>24){let t=n.entries().next().value;t&&(e.deleteBuffer(t[1].buffer),n.delete(t[0]))}}e.bindBuffer(e.ARRAY_BUFFER,o.buffer);for(let[t,n]of[[r,0],[i,12]])e.enableVertexAttribArray(t),e.vertexAttribPointer(t,3,e.FLOAT,!1,24,n);e.drawArrays(e.TRIANGLES,0,o.count)},dispose(){for(let t of n.values())e.deleteBuffer(t.buffer);n.clear()}}}function xe(e,t){let n=A(e,t===`fur`?fe:pe,{vertex:t===`fur`?V:V.replace(`#version 300 es`,`#version 300 es
573
+ #define JELLY_COAT`),geometry:be});if(!n)return null;let r=[n],i=n=>A(e,de,{vertex:t===`jelly`?B.replace(`#version 300 es`,`#version 300 es
574
+ #define JELLY_COAT`):B,geometry:(e,r)=>ue(e,r,t,n),clear:!1,doubleSided:!0,depthWrite:n===`shell`}),a=i(`shell`);if(!a)return n.dispose(),null;if(r.push(a),t===`fur`){let t=A(e,ye,{vertex:ve,geometry:_e,clear:!1,doubleSided:!0,depthWrite:!1});if(!t){for(let e of r)e.dispose();return null}r.push(t)}let o=A(e,E,{vertex:T,geometry:w,clear:!1});if(!o){for(let e of r)e.dispose();return null}r.push(o);let s=A(e,ie,{vertex:t===`jelly`?I.replace(`#version 300 es`,`#version 300 es
575
+ #define JELLY_COAT`):I,geometry:re,clear:!1});if(!s){for(let e of r)e.dispose();return null}r.push(s);let c=i(`visor`);if(!c){for(let e of r)e.dispose();return null}return r.push(c),{render(e){for(let t of r)t.render(e)},viewport(e){for(let t of r)t.viewport(e)},dispose(){for(let e of r)e.dispose()}}}var G=new Map,K=new Set;function Se(e){if(K.has(e)||typeof document>`u`)return null;let t=document.createElement(`canvas`);t.width=1,t.height=1;let n=xe(t,e);return n?(t.addEventListener(`webglcontextlost`,t=>{t.preventDefault(),G.delete(e)}),{canvas:t,refs:0,renderer:n,size:0}):(K.add(e),null)}function Ce(e=`fur`){let t=G.get(e);if(!t){let n=Se(e);if(!n)return null;G.set(e,n),t=n}let n=t;n.refs+=1;let r=!1;return{drawInto(t,i,a){if(r||G.get(e)!==n)return;let o=i;o>n.size&&(n.size=o,n.canvas.width=o,n.canvas.height=o),n.renderer.viewport(o),n.renderer.render(a),t.clearRect(0,0,t.canvas.width,t.canvas.height),t.drawImage(n.canvas,0,n.canvas.height-o,o,o,0,0,t.canvas.width,t.canvas.height)},release(){r||(r=!0,--n.refs,n.refs<=0&&G.get(e)===n&&(n.renderer.dispose(),G.delete(e)))}}}var q=Math.PI/18;function J(e,t){let n=q/Math.max(1,Math.hypot(e,t));return[e*n,t===0?0:-t*n]}function Y(e,t,n){if(n<=0)return;let r=3.8,i=Math.sqrt(110-r*r),a=Math.exp(-3.8*n),o=Math.cos(i*n),s=Math.sin(i*n);for(let[n,c,l]of[[`x`,`vx`,t[0]],[`y`,`vy`,t[1]]]){let t=e[n]-l,u=e[c];e[n]=l+a*(t*o+(u+r*t)/i*s),e[c]=a*(u*o-(r*u+110*t)/i*s)}}function we(e,t){let n={x:0,y:0,vx:0,vy:0},r=[60,60],i=null,a=[0,0],o=!1,s=n=>{if(!t()||n.button!==0||i!==null)return;let s=e.getBoundingClientRect(),c=(n.clientX-s.left)/s.width*152+-16,l=(n.clientY-s.top)/s.height*152+-16;Math.hypot(c-60,l-60)>48||(r[0]=c,r[1]=l,a=[n.clientX,n.clientY],i=n.pointerId,o=!1,e.setPointerCapture(i))},c=r=>{if(r.pointerId!==i)return;if(!t()){l(r);return}let s=e.getBoundingClientRect(),c=(r.clientX-a[0])/s.width*152,u=(r.clientY-a[1])/s.height*152,d=Math.min(1,18/(Math.hypot(c,u)||1));n.x=c*d,n.y=u*d,n.vx=0,n.vy=0,o||=Math.hypot(r.clientX-a[0],r.clientY-a[1])>4},l=t=>{t.pointerId===i&&(i=null,e.hasPointerCapture(t.pointerId)&&e.releasePointerCapture(t.pointerId))},u=e=>{o&&=(e.preventDefault(),e.stopPropagation(),!1)};return e.addEventListener(`pointerdown`,s),e.addEventListener(`pointermove`,c),e.addEventListener(`pointerup`,l),e.addEventListener(`pointercancel`,l),e.addEventListener(`lostpointercapture`,l),e.addEventListener(`click`,u,!0),{step(e){return i===null&&Y(n,[0,0],e),[r[0],r[1],n.x,n.y]},dispose(){i!==null&&e.hasPointerCapture(i)&&e.releasePointerCapture(i),e.removeEventListener(`pointerdown`,s),e.removeEventListener(`pointermove`,c),e.removeEventListener(`pointerup`,l),e.removeEventListener(`pointercancel`,l),e.removeEventListener(`lostpointercapture`,l),e.removeEventListener(`click`,u,!0)}}}var X={x:0,y:0},Z=new Set,Te=!1;function Ee(e){X.x=e.clientX,X.y=e.clientY;for(let e of Z)e()}function De(){return X}function Oe(e){return!Te&&typeof window<`u`&&(Te=!0,X.x=window.innerWidth*.62,X.y=window.innerHeight*.28,window.addEventListener(`pointermove`,Ee,{passive:!0})),Z.add(e),()=>{Z.delete(e)}}var Q=e(n(),1),ke={high:{density:68,dprCap:2,thick:1},low:{density:40,dprCap:1,thick:1.15},medium:{density:55,dprCap:1.5,thick:1.05}},Ae=1.7,$=0,je=2.399963,Me=[-.42,-.72,.75],Ne=30,Pe=.5,Fe=e=>(e- -16)/152*100;function Ie({className:e,motion:t=`auto`,animationSpeed:n=1,turn:a,coat:l=`fur`,goggles:u=!1,gooseHelmet:d=!1,interactive:f=!0,look:g=null,kind:_=`round`,overrides:v,quality:y=`high`,size:b=260}){let x=(0,h.useRef)(null),S=(0,h.useRef)(null),C=(0,h.useRef)(0);C.current===0&&($+=1,C.current=$*je);let w=(0,h.useRef)(null),[T,E]=(0,h.useState)(!0),O=d&&o(_)?_:void 0,k=r[_],A=(0,h.useMemo)(()=>s(k),[k]),j=(0,h.useMemo)(()=>m(k),[k]),M=(0,h.useMemo)(()=>i(k),[k]),N=(0,h.useRef)({animationSpeed:n,motion:t,turn:a,goggles:u,helmetKind:O,blobs:A,extras:j,form:k,interactive:f,kind:_,look:g,overrides:v,quality:y,scale:M,size:b});return N.current={animationSpeed:n,motion:t,turn:a,goggles:u,helmetKind:O,blobs:A,extras:j,form:k,interactive:f,kind:_,look:g,overrides:v,quality:y,scale:M,size:b},(0,h.useEffect)(()=>{x.current?.()},[_,v,y,b,f,g,u,O,t,n,a]),(0,h.useEffect)(()=>{let e=S.current,t=w.current;if(!(e&&t))return;let n=e.getContext(`2d`),r=n?Ce(l):null;if(!(n&&r)){E(!1);return}let i=C.current,a=window.matchMedia(`(prefers-reduced-motion: reduce)`),o={x:0,y:0},s={x:0,y:0},u={vx:0,vy:0,x:0,y:0},d=0,f=!0,p=0,m=0,h=l===`jelly`?we(t,()=>N.current.interactive&&N.current.motion!==`pause`&&(N.current.motion===`play`||!a.matches)):null,g=_=>{d=0;let v=N.current,y=ke[v.quality],b=v.motion===`pause`||v.motion===`auto`&&a.matches,x=b?0:Math.min((_-(m||_))/1e3,.1);p+=x*Math.max(.1,Math.min(2,v.animationSpeed)),m=_;let S=Math.min(window.devicePixelRatio||1,y.dprCap),C=Math.max(1,Math.round(v.size*S));e.width!==C&&(e.width=C,e.height=C);let w=120*C/(Ae*152),T=v.helmetKind?c:null,E=v.overrides?.fur??v.form.fur*(T?.length??1);if((v.interactive||v.look)&&!b){let e,n,r,i;if(v.look)e=v.look.x,n=v.look.y,r=Math.hypot(e,n)||1,i=Math.min(1,r);else{let a=t.getBoundingClientRect(),o=De();e=o.x-(a.left+a.width*.5),n=o.y-(a.top+a.height*.48),r=Math.hypot(e,n)||1,i=.35+Math.min(1,r/(a.width*2.4||1))*.65}o.x+=(e/r*5.5*i-o.x)*.16,o.y+=(n/r*3.5*i-o.y)*.16,s.x+=(e/r*i-s.x)*.24,s.y+=(n/r*.9*i-s.y)*.24}Y(u,[o.x,o.y],x*Math.max(.1,Math.min(2,v.animationSpeed)));let O=ee(t,v.kind);r.drawInto(n,C,{blobs:v.blobs,clarity:v.overrides?.clarity??D.clarity,softness:v.overrides?.softness??D.softness,pull:h?.step(x*Math.max(.1,Math.min(2,v.animationSpeed))),body:O.body,deep:O.deep,density:Math.min(v.overrides?.density??y.density*(T?.density??1),w),extraMeta:v.extras.meta,extras:v.extras.geometry,eye:[v.form.eye.x,v.form.eye.y,v.form.eye.r],gaze:[s.x,s.y],goggles:v.goggles&&!v.helmetKind,gooseHelmet:!!v.helmetKind,helmetKind:v.helmetKind,turn:v.turn?J(v.turn.yaw/q,v.turn.pitch/q):J(s.x,s.y),fur:E,inflate:v.overrides?.inflate??(l===`jelly`?D.inflate:T?.inflate??Ne),lean:[o.x,o.y],light:Me,period:v.form.period,scale:v.scale,falloff:v.form.falloff,thick:v.overrides?.thick??y.thick*(T?.thick??1),time:p+i,tip:O.tip,wind:v.overrides?.wind??Pe,wobble:[u.x-o.x,u.y-o.y]}),f&&!b&&(d=requestAnimationFrame(g))},_=()=>{d||=(m=0,requestAnimationFrame(g))},v=new IntersectionObserver(([e])=>{f=e?.isIntersecting??!0,f?_():d&&=(cancelAnimationFrame(d),0)},{rootMargin:`120px`});v.observe(t),x.current=_;let y=Oe(_);return a.addEventListener(`change`,_),_(),()=>{x.current=null,v.disconnect(),h?.dispose(),y(),a.removeEventListener(`change`,_),d&&cancelAnimationFrame(d),r.release()}},[l]),T?(0,Q.jsxs)(`div`,{"aria-hidden":`true`,className:e,ref:w,style:{height:b,position:`relative`,width:b},children:[(0,Q.jsx)(`div`,{style:{background:`radial-gradient(closest-side, rgb(0 0 0 / 0.2), transparent)`,filter:`blur(4px)`,height:`${k.shadowRx*50/152}%`,left:`50%`,position:`absolute`,top:`${Fe(110)}%`,transform:`translate(-50%, -50%)`,width:`${k.shadowRx*2.5*100/152}%`}}),(0,Q.jsx)(`canvas`,{ref:S,style:{display:`block`,height:b,width:b,touchAction:l===`jelly`&&f&&t!==`pause`?`none`:void 0,cursor:l===`jelly`&&f?`grab`:void 0}})]}):(0,Q.jsx)(p,{className:e,goggles:u&&!O,kind:_,size:b})}export{Ie as FluffyEngenty};