fluidcad 0.0.22 → 0.0.23

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluidcad",
3
- "version": "0.0.22",
3
+ "version": "0.0.23",
4
4
  "description": "Parametric CAD modeling library using javascript",
5
5
  "author": "Marwan Aouida <contact@marwan.dev>",
6
6
  "homepage": "https://fluidcad.io",
@@ -58,8 +58,7 @@
58
58
  "chokidar": "^5.0.0",
59
59
  "color-name": "^2.1.0",
60
60
  "express": "^5.2.1",
61
- "occjs-fluidcad": "^3.0.0",
62
- "occjs-wrapper": "npm:occjs-fluidcad@3.0.0",
61
+ "occjs-wrapper": "../occjs-fluidcad",
63
62
  "stacktrace-parser": "^0.1.11",
64
63
  "tree-sitter-wasms": "^0.1.13",
65
64
  "tsx": "^4.21.0",
@@ -4842,23 +4842,30 @@ void main() {
4842
4842
  <span class="loading loading-spinner loading-sm"></span>
4843
4843
  <span class="loading-text">Loading FluidCAD...</span>
4844
4844
  </div>
4845
- `,yh.appendChild(xh);var Sh=xh.querySelector(`.loading-text`);function Ch(e){Sh.textContent=e,xh.classList.remove(`hidden`)}function wh(){xh.classList.add(`hidden`)}var $=new im(`fluidcad-viewer`);Pd(()=>$.rebuildSceneMesh());var Th=new dm(yh),Eh=new mm(yh),Dh=new km(yh,$.sceneContext),Oh=new Am(yh,()=>{Uh===`picking-active`&&Zh()}),kh=new Cm(yh,e=>$.highlightShape(e),e=>Dh.show(e),(e,t)=>$.setShapeVisibility(e,t),e=>$.isShapeHidden(e),(e,t)=>$.setShapeTransparency(e,t),e=>$.getShapeTransparency(e));Th.setOpenHandler(()=>{$.clearHighlight(),Eh.hide()}),Th.setCentroidHandler(e=>{e?$.showCentroid(e):$.clearCentroid()}),$.setSelectionHandler((e,t)=>{e?Th.isOpen?$.highlightShape(e):t?.type===`face`?$.highlightFace(e,t.index):t?.type===`edge`?$.highlightEdge(e,t.index):$.clearHighlight():$.clearHighlight(),Th.setSelectedShape(e),e!==null&&t!==null?t.type===`face`?Eh.showForFace(e,t.index):Eh.showForEdge(e,t.index):Eh.hide()});var Ah=document.createElement(`div`);Ah.id=`fluidcad-trim-indicator`,Ah.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-none hidden`,Ah.innerHTML=`
4845
+ `,yh.appendChild(xh);var Sh=xh.querySelector(`.loading-text`);function Ch(e){Sh.textContent=e,xh.classList.remove(`hidden`)}function wh(){xh.classList.add(`hidden`)}var $=new im(`fluidcad-viewer`);Pd(()=>$.rebuildSceneMesh());var Th=new dm(yh),Eh=new mm(yh),Dh=new km(yh,$.sceneContext),Oh=new Am(yh,()=>{Zh===`picking-active`&&ag(),Mh===`picking-active`&&Bh()}),kh=new Cm(yh,e=>$.highlightShape(e),e=>Dh.show(e),(e,t)=>$.setShapeVisibility(e,t),e=>$.isShapeHidden(e),(e,t)=>$.setShapeTransparency(e,t),e=>$.getShapeTransparency(e));Th.setOpenHandler(()=>{$.clearHighlight(),Eh.hide()}),Th.setCentroidHandler(e=>{e?$.showCentroid(e):$.clearCentroid()}),$.setSelectionHandler((e,t)=>{e?Th.isOpen?$.highlightShape(e):t?.type===`face`?$.highlightFace(e,t.index):t?.type===`edge`?$.highlightEdge(e,t.index):$.clearHighlight():$.clearHighlight(),Th.setSelectedShape(e),e!==null&&t!==null?t.type===`face`?Eh.showForFace(e,t.index):Eh.showForEdge(e,t.index):Eh.hide()});var Ah=document.createElement(`div`);Ah.id=`fluidcad-trim-pick-trigger`,Ah.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,Ah.innerHTML=`
4846
+ <button class="flex items-center gap-3 panel-bg border border-base-content/10 rounded-lg px-6 py-3 text-base-content/70 text-sm leading-none select-none cursor-pointer hover:border-base-content/20 transition-colors">
4847
+ <span class="[&>svg]:size-5">${Pp}</span>
4848
+ <span>Interactive Trimming</span>
4849
+ </button>
4850
+ `,yh.appendChild(Ah);var jh=document.createElement(`div`);jh.id=`fluidcad-trim-pick-active`,jh.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,jh.innerHTML=`
4846
4851
  <div class="flex items-center gap-3 panel-bg border border-base-content/10 rounded-lg px-6 py-3 text-base-content/70 text-sm leading-none select-none">
4847
4852
  <span class="[&>svg]:size-5">${Pp}</span>
4848
4853
  <span>Trimming Mode</span>
4854
+ <div class="h-4 w-px bg-base-content/10"></div>
4855
+ <button class="text-base-content/60 hover:text-base-content transition-colors cursor-pointer" id="exit-trim-pick">Exit</button>
4849
4856
  </div>
4850
- `,yh.appendChild(Ah);var jh=null,Mh=null;function Nh(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}if(!t||t.type!==`sketch`||!t.id)return!1;for(let n=e.length-1;n>=0;n--)if(e[n].parentId===t.id)return e[n].type===`trim2d`;return!1}function Ph(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}let n=t?.type===`sketch`?t:null;if(!n||!n.id||!n.object?.plane){Fh();return}let r=null;for(let t=e.length-1;t>=0;t--)if(e[t].parentId===n.id){r=e[t];break}if(!r||r.type!==`trim2d`||!r.sourceLocation){Fh();return}let i=r.sourceLocation.line;if(jh&&Mh===i){jh.updateEdges(e,n.id);return}Fh();let a=n.object.plane,o=r.sourceLocation,s=_h.fromSceneObjects(e,n.id,a);jh=new Mm($.sceneContext,a,s,e,n.id,e=>{fetch(`/api/insert-point`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({point:e,sourceLocation:o})})},e=>{$.clearHighlight(),Bh(),e&&($.highlightShape(e.shapeId),zh(e.endpoints))}),Mh=i,jh.activate(),Ah.classList.remove(`hidden`)}function Fh(){jh&&(jh.deactivate(),jh=null,Mh=null),Bh(),Ah.classList.add(`hidden`)}var Ih=16762232,Lh=1e-4,Rh=[];function zh(e){Bh(),e.length!==0&&($.sceneContext.scene.traverse(t=>{if(!t.userData.isVertexDot)return;let n=t.children[0];if(!n||!n.isMesh)return;let r=t.position;for(let t of e){let e=r.x-t[0],i=r.y-t[1],a=r.z-t[2];if(e*e+i*i+a*a<Lh){let e=n.material,t=e.clone();t.color.setHex(Ih),n.material=t,Rh.push({mesh:n,originalMaterial:e});break}}}),$.sceneContext.requestRender())}function Bh(){for(let{mesh:e,originalMaterial:t}of Rh)e.material.dispose(),e.material=t;Rh.length>0&&(Rh.length=0,$.sceneContext.requestRender())}var Vh=document.createElement(`div`);Vh.id=`fluidcad-region-pick-trigger`,Vh.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,Vh.innerHTML=`
4857
+ `,yh.appendChild(jh);var Mh=`idle`,Nh=null,Ph=null,Fh=null,Ih=null;function Lh(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}if(!t||t.type!==`sketch`||!t.id||!t.object?.plane)return{hasTrigger:!1};let n=null;for(let r=e.length-1;r>=0;r--)if(e[r].parentId===t.id){n=e[r];break}let r=n;return!r||r.type!==`trim2d`||r.object?.trigger!==`trim-picking`||!r.sourceLocation?{hasTrigger:!1}:{hasTrigger:!0,trimObj:n,sketchObj:t}}function Rh(e,t){Vh();let n=e.sketchObj.object.plane,r=e.trimObj.sourceLocation,i=e.sketchObj.id,a=_h.fromSceneObjects(t,i,n);Fh=new Mm($.sceneContext,n,a,t,i,e=>{fetch(`/api/insert-point`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({point:e,sourceLocation:r})})},e=>{$.clearHighlight(),Jh(),e&&($.highlightShape(e.shapeId),qh(e.endpoints))}),Ih=r.line,Fh.activate()}function zh(){if(Nh){if(!Nh.trimObj.object?.picking){fetch(`/api/add-pick`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sourceLocation:Nh.trimObj.sourceLocation})}),Mh=`picking-active`,Ah.classList.add(`hidden`),jh.classList.remove(`hidden`),$.isTrimming=!0;return}Ph&&Rh(Nh,Ph),Mh=`picking-active`,Ah.classList.add(`hidden`),jh.classList.remove(`hidden`),$.isTrimming=!0}}function Bh(){Vh(),$.isTrimming=!1;let e=Nh?.trimObj,t=e?.object?.picking,n=e?.object?.pickPoints;t&&(!n||n.length===0)&&e?.sourceLocation&&fetch(`/api/remove-pick`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sourceLocation:e.sourceLocation})}),Nh?(Mh=`icon-visible`,jh.classList.add(`hidden`),Ah.classList.remove(`hidden`)):(Mh=`idle`,jh.classList.add(`hidden`),Ah.classList.add(`hidden`))}function Vh(){Fh&&(Fh.deactivate(),Fh=null,Ih=null),Jh()}function Hh(){Vh(),Mh=`idle`,Ah.classList.add(`hidden`),jh.classList.add(`hidden`),Nh=null,Ph=null,$.isTrimming=!1}function Uh(e){let t=Lh(e);if(!t.hasTrigger){Hh();return}Nh={trimObj:t.trimObj,sketchObj:t.sketchObj},Ph=e;let n=t.trimObj.object?.picking;if(Mh===`picking-active`){if(n){let n=Nh.trimObj.sourceLocation.line;if(Fh&&Ih===n){Fh.updateEdges(e,t.sketchObj.id);return}Rh(Nh,e)}return}Mh=`icon-visible`,Ah.classList.remove(`hidden`),jh.classList.add(`hidden`)}Ah.querySelector(`button`).addEventListener(`click`,()=>{zh()}),jh.querySelector(`#exit-trim-pick`).addEventListener(`click`,()=>{Bh()});var Wh=16762232,Gh=1e-4,Kh=[];function qh(e){Jh(),e.length!==0&&($.sceneContext.scene.traverse(t=>{if(!t.userData.isVertexDot)return;let n=t.children[0];if(!n||!n.isMesh)return;let r=t.position;for(let t of e){let e=r.x-t[0],i=r.y-t[1],a=r.z-t[2];if(e*e+i*i+a*a<Gh){let e=n.material,t=e.clone();t.color.setHex(Wh),n.material=t,Kh.push({mesh:n,originalMaterial:e});break}}}),$.sceneContext.requestRender())}function Jh(){for(let{mesh:e,originalMaterial:t}of Kh)e.material.dispose(),e.material=t;Kh.length>0&&(Kh.length=0,$.sceneContext.requestRender())}var Yh=document.createElement(`div`);Yh.id=`fluidcad-region-pick-trigger`,Yh.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,Yh.innerHTML=`
4851
4858
  <button class="flex items-center gap-3 panel-bg border border-base-content/10 rounded-lg px-6 py-3 text-base-content/70 text-sm leading-none select-none cursor-pointer hover:border-base-content/20 transition-colors">
4852
4859
  <span class="[&>svg]:size-5">${zp}</span>
4853
4860
  <span>Pick Regions</span>
4854
4861
  </button>
4855
- `,yh.appendChild(Vh);var Hh=document.createElement(`div`);Hh.id=`fluidcad-region-pick-active`,Hh.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,Hh.innerHTML=`
4862
+ `,yh.appendChild(Yh);var Xh=document.createElement(`div`);Xh.id=`fluidcad-region-pick-active`,Xh.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,Xh.innerHTML=`
4856
4863
  <div class="flex items-center gap-3 panel-bg border border-base-content/10 rounded-lg px-6 py-3 text-base-content/70 text-sm leading-none select-none">
4857
4864
  <span>Region Picking Mode</span>
4858
4865
  <div class="h-4 w-px bg-base-content/10"></div>
4859
4866
  <button class="text-base-content/60 hover:text-base-content transition-colors cursor-pointer" id="exit-region-pick">Exit</button>
4860
4867
  </div>
4861
- `,yh.appendChild(Hh);var Uh=`idle`,Wh=null,Gh=null,Kh=null,qh=[`extrude`,`cut`,`cut-symmetric`,`revolve`,`sweep`];function Jh(e){let t=[`plane`,`axis`],n;for(let r=e.length-1;r>=0;r--){let i=e[r];if(!i.parentId&&!t.includes(i.type)){n=i;break}}if(!n)return{hasTrigger:!1};let r=n;if(!qh.includes(r.type)||r.object?.trigger!==`region-picking`||r.object?.thin)return{hasTrigger:!1};let i=e.indexOf(n),a;for(let t=i-1;t>=0;t--)if(e[t].type===`sketch`&&e[t].parentId===r.parentId){a=e[t];break}return{hasTrigger:!0,extrudeObj:n,sketchObj:a}}function Yh(e){Qh();let t=e.extrudeObj.object?.pickPlane??e.sketchObj.object.plane,n=e.extrudeObj.sourceLocation;Gh=new Rm($.sceneContext,t,e=>{fetch(`/api/insert-point`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({point:e,sourceLocation:n})})},e=>{fetch(`/api/set-pick-points`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({points:e,sourceLocation:n})})},e=>{}),Kh=n.line,Gh.activate()}function Xh(){if(Wh){if(!Wh.extrudeObj.object?.picking){fetch(`/api/add-pick`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sourceLocation:Wh.extrudeObj.sourceLocation})}),Uh=`picking-active`,Vh.classList.add(`hidden`),Hh.classList.remove(`hidden`),$.isRegionPicking=!0,$.toggleSketchMode(!1);return}Yh(Wh),Uh=`picking-active`,Vh.classList.add(`hidden`),Hh.classList.remove(`hidden`),$.isRegionPicking=!0,$.toggleSketchMode(!1),$.rebuildSceneMesh()}}function Zh(){Qh(),$.isRegionPicking=!1,$.toggleSketchMode(!0),$.rebuildSceneMesh();let e=Wh?.extrudeObj,t=e?.object?.picking,n=e?.object?.pickPoints;t&&(!n||n.length===0)&&e?.sourceLocation&&fetch(`/api/remove-pick`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sourceLocation:e.sourceLocation})}),Wh?(Uh=`icon-visible`,Hh.classList.add(`hidden`),Vh.classList.remove(`hidden`)):(Uh=`idle`,Hh.classList.add(`hidden`),Vh.classList.add(`hidden`))}function Qh(){Gh&&(Gh.deactivate(),Gh=null,Kh=null)}function $h(){Qh(),Uh=`idle`,Vh.classList.add(`hidden`),Hh.classList.add(`hidden`),Wh=null,$.isRegionPicking=!1,$.toggleSketchMode(!0)}function eg(e){let t=Jh(e),n=t.extrudeObj?.object?.pickPlane||t.sketchObj?.object?.plane;if(!t.hasTrigger||!t.extrudeObj?.sourceLocation||!n){$h();return}Wh={extrudeObj:t.extrudeObj,sketchObj:t.sketchObj};let r=t.extrudeObj.object?.picking;if(Uh===`picking-active`){if(r){let e=Wh.extrudeObj.sourceLocation.line;if(Gh&&Kh===e)return;Yh(Wh)}return}Uh=`icon-visible`,Vh.classList.remove(`hidden`),Hh.classList.add(`hidden`)}Vh.querySelector(`button`).addEventListener(`click`,()=>{Xh()}),Hh.querySelector(`#exit-region-pick`).addEventListener(`click`,()=>{Zh()});var tg=document.createElement(`div`);tg.id=`fluidcad-bezier-indicator`,tg.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,tg.innerHTML=`
4868
+ `,yh.appendChild(Xh);var Zh=`idle`,Qh=null,$h=null,eg=null,tg=[`extrude`,`cut`,`cut-symmetric`,`revolve`,`sweep`];function ng(e){let t=[`plane`,`axis`],n;for(let r=e.length-1;r>=0;r--){let i=e[r];if(!i.parentId&&!t.includes(i.type)){n=i;break}}if(!n)return{hasTrigger:!1};let r=n;if(!tg.includes(r.type)||r.object?.trigger!==`region-picking`||r.object?.thin)return{hasTrigger:!1};let i=e.indexOf(n),a;for(let t=i-1;t>=0;t--)if(e[t].type===`sketch`&&e[t].parentId===r.parentId){a=e[t];break}return{hasTrigger:!0,extrudeObj:n,sketchObj:a}}function rg(e){og();let t=e.extrudeObj.object?.pickPlane??e.sketchObj.object.plane,n=e.extrudeObj.sourceLocation;$h=new Rm($.sceneContext,t,e=>{fetch(`/api/insert-point`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({point:e,sourceLocation:n})})},e=>{fetch(`/api/set-pick-points`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({points:e,sourceLocation:n})})},e=>{}),eg=n.line,$h.activate()}function ig(){if(Qh){if(!Qh.extrudeObj.object?.picking){fetch(`/api/add-pick`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sourceLocation:Qh.extrudeObj.sourceLocation})}),Zh=`picking-active`,Yh.classList.add(`hidden`),Xh.classList.remove(`hidden`),$.isRegionPicking=!0,$.toggleSketchMode(!1);return}rg(Qh),Zh=`picking-active`,Yh.classList.add(`hidden`),Xh.classList.remove(`hidden`),$.isRegionPicking=!0,$.toggleSketchMode(!1),$.rebuildSceneMesh()}}function ag(){og(),$.isRegionPicking=!1,$.toggleSketchMode(!0),$.rebuildSceneMesh();let e=Qh?.extrudeObj,t=e?.object?.picking,n=e?.object?.pickPoints;t&&(!n||n.length===0)&&e?.sourceLocation&&fetch(`/api/remove-pick`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sourceLocation:e.sourceLocation})}),Qh?(Zh=`icon-visible`,Xh.classList.add(`hidden`),Yh.classList.remove(`hidden`)):(Zh=`idle`,Xh.classList.add(`hidden`),Yh.classList.add(`hidden`))}function og(){$h&&($h.deactivate(),$h=null,eg=null)}function sg(){og(),Zh=`idle`,Yh.classList.add(`hidden`),Xh.classList.add(`hidden`),Qh=null,$.isRegionPicking=!1,$.toggleSketchMode(!0)}function cg(e){let t=ng(e),n=t.extrudeObj?.object?.pickPlane||t.sketchObj?.object?.plane;if(!t.hasTrigger||!t.extrudeObj?.sourceLocation||!n){sg();return}Qh={extrudeObj:t.extrudeObj,sketchObj:t.sketchObj};let r=t.extrudeObj.object?.picking;if(Zh===`picking-active`){if(r){let e=Qh.extrudeObj.sourceLocation.line;if($h&&eg===e)return;rg(Qh)}return}Zh=`icon-visible`,Yh.classList.remove(`hidden`),Xh.classList.add(`hidden`)}Yh.querySelector(`button`).addEventListener(`click`,()=>{ig()}),Xh.querySelector(`#exit-region-pick`).addEventListener(`click`,()=>{ag()});var lg=document.createElement(`div`);lg.id=`fluidcad-bezier-indicator`,lg.className=`absolute top-4 left-1/2 -translate-x-1/2 z-[999] pointer-events-auto hidden`,lg.innerHTML=`
4862
4869
  <div class="flex items-center gap-3 panel-bg border border-base-content/10 rounded-lg px-6 py-3 text-base-content/70 text-sm leading-none select-none">
4863
4870
  <span>Bezier Drawing Mode</span>
4864
4871
  <div class="h-4 w-px bg-base-content/10"></div>
@@ -4871,15 +4878,15 @@ void main() {
4871
4878
  <span class="text-xs">Grid</span>
4872
4879
  </label>
4873
4880
  </div>
4874
- `,yh.appendChild(tg),tg.querySelector(`[data-snap="vertex"]`).addEventListener(`change`,e=>{ng&&(ng.snapController.snapToVertices=e.target.checked)}),tg.querySelector(`[data-snap="grid"]`).addEventListener(`change`,e=>{ng&&(ng.snapController.snapToGrid=e.target.checked)});var ng=null,rg=null;function ig(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}if(!t||t.type!==`sketch`||!t.id)return!1;for(let n=e.length-1;n>=0;n--)if(e[n].parentId===t.id)return e[n].type===`bezier`;return!1}function ag(e,t){for(let n=e.length-1;n>=0;n--){let r=e[n];if(r.parentId===t&&r.type===`bezier`){let e=r.object?.startPoint,t=r.object?.resolvedPoints;return e?[e,...t||[]]:[]}}return[]}function og(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}let n=t?.type===`sketch`?t:null;if(!n||!n.id||!n.object?.plane){sg();return}let r=null;for(let t=e.length-1;t>=0;t--)if(e[t].parentId===n.id){r=e[t];break}if(!r||r.type!==`bezier`||!r.sourceLocation){sg();return}let i=r.sourceLocation.line,a=n.object.plane,o=ag(e,n.id),s=_h.fromSceneObjects(e,n.id,a);if(ng&&rg===i){ng.updateExistingPoles(o),ng.snapController.updateSnapManager(s);return}sg();let c=r.sourceLocation,l=new vh(s,a),u=tg.querySelector(`[data-snap="vertex"]`),d=tg.querySelector(`[data-snap="grid"]`);u&&(l.snapToVertices=u.checked),d&&(l.snapToGrid=d.checked),ng=new dh($.sceneContext,a,l,o,e=>{fetch(`/api/insert-point`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({point:e,sourceLocation:c})})},e=>{fetch(`/api/set-pick-points`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({points:e,sourceLocation:c})})}),rg=i,ng.activate(),tg.classList.remove(`hidden`)}function sg(){ng&&(ng.deactivate(),ng=null,rg=null),tg.classList.add(`hidden`)}var cg=document.createElement(`div`);cg.className=`absolute bottom-6 left-6 z-[100]`,cg.innerHTML=`
4881
+ `,yh.appendChild(lg),lg.querySelector(`[data-snap="vertex"]`).addEventListener(`change`,e=>{ug&&(ug.snapController.snapToVertices=e.target.checked)}),lg.querySelector(`[data-snap="grid"]`).addEventListener(`change`,e=>{ug&&(ug.snapController.snapToGrid=e.target.checked)});var ug=null,dg=null;function fg(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}if(!t||t.type!==`sketch`||!t.id)return!1;for(let n=e.length-1;n>=0;n--)if(e[n].parentId===t.id)return e[n].type===`bezier`;return!1}function pg(e,t){for(let n=e.length-1;n>=0;n--){let r=e[n];if(r.parentId===t&&r.type===`bezier`){let e=r.object?.startPoint,t=r.object?.resolvedPoints;return e?[e,...t||[]]:[]}}return[]}function mg(e){let t=null;for(let n=e.length-1;n>=0;n--)if(bh(e[n],e)){t=e[n];break}let n=t?.type===`sketch`?t:null;if(!n||!n.id||!n.object?.plane){hg();return}let r=null;for(let t=e.length-1;t>=0;t--)if(e[t].parentId===n.id){r=e[t];break}if(!r||r.type!==`bezier`||!r.sourceLocation){hg();return}let i=r.sourceLocation.line,a=n.object.plane,o=pg(e,n.id),s=_h.fromSceneObjects(e,n.id,a);if(ug&&dg===i){ug.updateExistingPoles(o),ug.snapController.updateSnapManager(s);return}hg();let c=r.sourceLocation,l=new vh(s,a),u=lg.querySelector(`[data-snap="vertex"]`),d=lg.querySelector(`[data-snap="grid"]`);u&&(l.snapToVertices=u.checked),d&&(l.snapToGrid=d.checked),ug=new dh($.sceneContext,a,l,o,e=>{fetch(`/api/insert-point`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({point:e,sourceLocation:c})})},e=>{fetch(`/api/set-pick-points`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({points:e,sourceLocation:c})})}),dg=i,ug.activate(),lg.classList.remove(`hidden`)}function hg(){ug&&(ug.deactivate(),ug=null,dg=null),lg.classList.add(`hidden`)}var gg=document.createElement(`div`);gg.className=`absolute bottom-6 left-6 z-[100]`,gg.innerHTML=`
4875
4882
  <button class="btn btn-ghost btn-square btn-sm text-base-content/60" title="Import File">
4876
4883
  <span class="[&>svg]:size-5">${Fp}</span>
4877
4884
  </button>
4878
- `,yh.appendChild(cg);var lg=document.createElement(`div`);lg.className=`absolute bottom-16 left-6 z-[100] panel-bg border border-base-content/10 rounded-lg px-4 py-3 text-sm text-base-content/80 hidden`,yh.appendChild(lg);var ug=null;function dg(e,t){t?(lg.innerHTML=`
4885
+ `,yh.appendChild(gg);var _g=document.createElement(`div`);_g.className=`absolute bottom-16 left-6 z-[100] panel-bg border border-base-content/10 rounded-lg px-4 py-3 text-sm text-base-content/80 hidden`,yh.appendChild(_g);var vg=null;function yg(e,t){t?(_g.innerHTML=`
4879
4886
  <div class="flex items-center gap-2">
4880
4887
  <span>${e} <code class="bg-base-content/10 px-1.5 py-0.5 rounded text-base-content/90">${t}</code></span>
4881
4888
  <button class="btn btn-ghost btn-square btn-xs text-base-content/60 import-toast-copy" title="Copy">
4882
4889
  <span class="[&>svg]:size-3.5">${Ip}</span>
4883
4890
  </button>
4884
4891
  </div>
4885
- `,lg.querySelector(`.import-toast-copy`).addEventListener(`click`,()=>{navigator.clipboard.writeText(t);let e=lg.querySelector(`.import-toast-copy`);e.setAttribute(`title`,`Copied!`),setTimeout(()=>e.setAttribute(`title`,`Copy`),1500)})):lg.textContent=e,lg.classList.remove(`hidden`),ug&&clearTimeout(ug),ug=setTimeout(()=>{lg.classList.add(`hidden`),ug=null},6e3)}var fg=document.createElement(`input`);fg.type=`file`,fg.accept=`.step,.stp`,fg.style.display=`none`,yh.appendChild(fg),cg.querySelector(`button`).addEventListener(`click`,()=>{fg.click()}),fg.addEventListener(`change`,async()=>{let e=fg.files?.[0];if(e){fg.value=``,Ch(`Importing file...`);try{let t=await e.arrayBuffer(),n=new Uint8Array(t),r=``;for(let e=0;e<n.length;e++)r+=String.fromCharCode(n[e]);let i=btoa(r),a=await fetch(`/api/import-file`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({fileName:e.name,data:i})}),o=await a.json();!a.ok||!o.success?dg(`Import failed: ${o.error||`Unknown error`}`):dg(`Imported! Use:`,`load('${o.fileName}')`)}catch{dg(`Import failed: network error`)}finally{wh()}}});async function pg(e,t,n){try{let r=await(await Tm($.sceneContext,n)).arrayBuffer(),i=new Uint8Array(r),a=``;for(let e=0;e<i.length;e++)a+=String.fromCharCode(i[e]);e.send(JSON.stringify({type:`screenshot-result`,requestId:t,success:!0,data:btoa(a)}))}catch(n){e.send(JSON.stringify({type:`screenshot-result`,requestId:t,success:!1,error:n.message||String(n)}))}}function mg(){let e=`ws://${window.location.host}`,t=new WebSocket(e);t.addEventListener(`message`,e=>{let n=JSON.parse(e.data);switch(n.type){case`init-complete`:Ch(`Loading model...`);break;case`processing-file`:Ch(`Loading model...`);break;case`scene-rendered`:{wh();let e=n.rollbackStop!=null&&n.rollbackStop<n.result.length-1;$.isTrimming=!e&&Nh(n.result),$.isBezierDrawing=!e&&ig(n.result),$.updateView(n.result,e),n.absPath&&$.setFileName(n.absPath),e?(Fh(),$h(),sg()):(Ph(n.result),eg(n.result),og(n.result)),kh.update(n.result,n.rollbackStop??n.result.length-1,n.absPath),n.breakpointHit!==void 0&&Oh.setActive(n.breakpointHit);break}case`highlight-shape`:$.highlightShape(n.shapeId),Th.setSelectedShape(n.shapeId);break;case`clear-highlight`:$.clearHighlight(),Th.setSelectedShape(null),Eh.hide();break;case`show-shape-properties`:$.clearHighlight(),Eh.hide(),Th.show(n.shapeId);break;case`take-screenshot`:pg(t,n.requestId,n.options);break}}),t.addEventListener(`close`,()=>{setTimeout(mg,1e3)})}mg();
4892
+ `,_g.querySelector(`.import-toast-copy`).addEventListener(`click`,()=>{navigator.clipboard.writeText(t);let e=_g.querySelector(`.import-toast-copy`);e.setAttribute(`title`,`Copied!`),setTimeout(()=>e.setAttribute(`title`,`Copy`),1500)})):_g.textContent=e,_g.classList.remove(`hidden`),vg&&clearTimeout(vg),vg=setTimeout(()=>{_g.classList.add(`hidden`),vg=null},6e3)}var bg=document.createElement(`input`);bg.type=`file`,bg.accept=`.step,.stp`,bg.style.display=`none`,yh.appendChild(bg),gg.querySelector(`button`).addEventListener(`click`,()=>{bg.click()}),bg.addEventListener(`change`,async()=>{let e=bg.files?.[0];if(e){bg.value=``,Ch(`Importing file...`);try{let t=await e.arrayBuffer(),n=new Uint8Array(t),r=``;for(let e=0;e<n.length;e++)r+=String.fromCharCode(n[e]);let i=btoa(r),a=await fetch(`/api/import-file`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({fileName:e.name,data:i})}),o=await a.json();!a.ok||!o.success?yg(`Import failed: ${o.error||`Unknown error`}`):yg(`Imported! Use:`,`load('${o.fileName}')`)}catch{yg(`Import failed: network error`)}finally{wh()}}});async function xg(e,t,n){try{let r=await(await Tm($.sceneContext,n)).arrayBuffer(),i=new Uint8Array(r),a=``;for(let e=0;e<i.length;e++)a+=String.fromCharCode(i[e]);e.send(JSON.stringify({type:`screenshot-result`,requestId:t,success:!0,data:btoa(a)}))}catch(n){e.send(JSON.stringify({type:`screenshot-result`,requestId:t,success:!1,error:n.message||String(n)}))}}function Sg(){let e=`ws://${window.location.host}`,t=new WebSocket(e);t.addEventListener(`message`,e=>{let n=JSON.parse(e.data);switch(n.type){case`init-complete`:Ch(`Loading model...`);break;case`processing-file`:Ch(`Loading model...`);break;case`scene-rendered`:{wh();let e=n.rollbackStop!=null&&n.rollbackStop<n.result.length-1;$.isTrimming=!e&&Mh===`picking-active`,$.isBezierDrawing=!e&&fg(n.result),$.updateView(n.result,e),n.absPath&&$.setFileName(n.absPath),e?(Hh(),sg(),hg()):(Uh(n.result),cg(n.result),mg(n.result)),kh.update(n.result,n.rollbackStop??n.result.length-1,n.absPath),n.breakpointHit!==void 0&&Oh.setActive(n.breakpointHit);break}case`highlight-shape`:$.highlightShape(n.shapeId),Th.setSelectedShape(n.shapeId);break;case`clear-highlight`:$.clearHighlight(),Th.setSelectedShape(null),Eh.hide();break;case`show-shape-properties`:$.clearHighlight(),Eh.hide(),Th.show(n.shapeId);break;case`take-screenshot`:xg(t,n.requestId,n.options);break}}),t.addEventListener(`close`,()=>{setTimeout(Sg,1e3)})}Sg();
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>FluidCAD Viewer</title>
7
- <script type="module" crossorigin src="/assets/index-C0JwQ8Bk.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-CqP_mgZk.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-gPoNOiIs.css">
9
9
  </head>
10
10
  <body class="m-0 p-0 overflow-hidden w-full h-full bg-base-100 text-base-content">