brep-io-kernel 1.0.266 → 1.0.267

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 (32) hide show
  1. package/README.md +3 -5
  2. package/dist/about.html +2 -2
  3. package/dist/apiExamples/BREP_Booleans.html +2 -2
  4. package/dist/apiExamples/BREP_Export.html +2 -2
  5. package/dist/apiExamples/BREP_Primitives.html +2 -2
  6. package/dist/apiExamples/BREP_Transforms.html +2 -2
  7. package/dist/apiExamples/Embeded_2D_Sketcher.html +2 -2
  8. package/dist/apiExamples/Embeded_CAD.html +2 -2
  9. package/dist/apiExamples/Embeded_CAD_Integration_Test.html +2 -2
  10. package/dist/assets/{apiExample_BREP_Booleans-BYmpqcsp.js → apiExample_BREP_Booleans-CTe2EMfJ.js} +1 -1
  11. package/dist/assets/{apiExample_BREP_Export-uBjod_wt.js → apiExample_BREP_Export-drwwX-N0.js} +1 -1
  12. package/dist/assets/{apiExample_BREP_Primitives-6305hZzi.js → apiExample_BREP_Primitives-DmkRC9x9.js} +1 -1
  13. package/dist/assets/{apiExample_BREP_Transforms-BzoYBAov.js → apiExample_BREP_Transforms-BuSQlmou.js} +1 -1
  14. package/dist/assets/{apiExample_Embeded_2D_Sketcher-D1NLjBBJ.js → apiExample_Embeded_2D_Sketcher-uhVSKDmJ.js} +1 -1
  15. package/dist/assets/{apiExample_Embeded_CAD-CyBvK6VA.js → apiExample_Embeded_CAD-DHa-5wYS.js} +1 -1
  16. package/dist/assets/{apiExample_Embeded_CAD_Integration_Test-GmK-MuGv.js → apiExample_Embeded_CAD_Integration_Test-ChPFgcn1.js} +1 -1
  17. package/dist/assets/{brep-kernel-PNIMTlaV.js → brep-kernel-DJpirUxq.js} +6 -2
  18. package/dist/assets/{browserTests-B-7L1X5b.js → browserTests-Co7TxSP6.js} +3 -3
  19. package/dist/assets/{index.es-BCqdB02m.js → index.es-f-EIT528.js} +1 -1
  20. package/dist/assets/{javascript-hVMGvX5S.js → javascript-kCxntZPl.js} +1 -1
  21. package/dist/assets/{main-cad-3Myw0wlX.js → main-cad-BckkeW6Q.js} +10 -6
  22. package/dist/assets/{test-D2BDjo1w.js → test-CZQN4gj3.js} +3 -3
  23. package/dist/cad.html +1 -1
  24. package/dist/help/index.html +2 -2
  25. package/dist/help/search-index.json +1 -1
  26. package/dist/test.html +1 -1
  27. package/dist/viewer.html +1 -1
  28. package/dist-kernel/brep-kernel.js +6 -2
  29. package/dist-kernel/help/index.html +2 -2
  30. package/dist-kernel/help/search-index.json +1 -1
  31. package/package.json +2 -4
  32. package/src/UI/toolbarButtons/scriptRunnerButton.js +6 -2
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/main-cad-3Myw0wlX.js","assets/featureDialogs-BlENEp3D.js","assets/browserStorage-CvgF8ovw.js","assets/preload-helper-ZNr0Qq7Q.js","assets/FeatureRegistry-Byo0zhcC.js","assets/deepClone-Dj59xCHB.js","assets/PartHistory-DJNowO8n.js","assets/AssemblyConstraintRegistry-DbpKYepy.js","assets/annUtils-CqMdNOP0.js","assets/ListEntityBase-DIaWtqmZ.js","assets/droppedWorkspaceFiles-8o-ZYOrf.js","assets/AnnotationRegistry-PNrk9ZTv.js","assets/main-cad-C3E_anfF.css"])))=>i.map(i=>d[i]);
2
- var Ko=Object.defineProperty;var l=(e,t)=>Ko(e,"name",{value:t,configurable:!0});import{b as Jo,g as Bn,D as Yr,a as Zo,r as Gn,c as Xr,d as Ja,e as tr,f as Wn,h as Kr,i as Jr,j as qo,k as Qo,l as es,m as jn,n as Zr,o as ts,p as Xt,q as qr,s as ns,t as rs,u as as,v as os,w as ss,x as is,P as Ut,F as ls,y as Kt,z as cs,A as Qr,B as ds,C as us,E as fs,G as ps,H as _s,I as hs,J as Vn,V as ea,K as ta}from"./main-cad-3Myw0wlX.js";import{q as j}from"./browserStorage-CvgF8ovw.js";import{P as Y,S as An,z as Za}from"./PartHistory-DJNowO8n.js";import{C as qa,B as M,o as ae,E as ms,p as gs,q as na,t as Er,u as ra,v as xs,w as yr,x as Es,y as fn,z as st,T as We,_ as aa,G as Sr,H as ys,I as oa,P as Ss,K as ws,L as Qa,M as eo,N as ze,O as vs,Q as wt,R as bs,U as Jt,J as Fs,j as wr,i as Ps,h as to,V as sa,W as As,X as Ts,Y as Cs}from"./FeatureRegistry-Byo0zhcC.js";import{aI as L,aL as Se,V as $,G as Fe,aK as nr,aH as C,bh as Oe,bi as Ns,bj as no,M as Rs,aN as Is,bk as Os,bl as ro,bm as Ds,bn as Ms,bo as ks,bp as $s,bq as Ls,br as Bs,aJ as kt,bs as vt,bt as Gs,bu as Ws,bv as js,bw as vr,bx as Vs,by as Us,bz as br,bA as ao,bB as oo,ba as so,b9 as ia,bC as io,B as lo,Y as ne,z as Zt,d as Tn,F as Wt,f as Fr,s as Pr,q as we,X as Re,e as zs,L as Hs,O as co,af as rr,bD as la,be as Ys,ad as Xs,ag as Ks,ah as Js,bE as Zs,bF as qs,bG as ca,bH as Qs,b8 as ei,b5 as ti,aT as uo,a$ as ni,Q as ri,bI as da}from"./featureDialogs-BlENEp3D.js";import{_ as ai}from"./preload-helper-ZNr0Qq7Q.js";import{L as pn,_ as at,b as oi,R as Ar,e as Tr}from"./AnnotationRegistry-PNrk9ZTv.js";import"./droppedWorkspaceFiles-8o-ZYOrf.js";import"./deepClone-Dj59xCHB.js";import"./annUtils-CqMdNOP0.js";import"./AssemblyConstraintRegistry-DbpKYepy.js";import"./ListEntityBase-DIaWtqmZ.js";const Vr=class Vr{constructor(t={}){this.options={captureStack:!!t.captureStack,withTimestamp:t.withTimestamp!==!1,levels:t.levels||null,maxEntries:Number.isFinite(t.maxEntries)?t.maxEntries:1/0},this._orig=(typeof window<"u"?window.console:console)||{},this._installed=!1,this._capturing=!0,this._logs=[],this._nextId=1,this._proxy=this._buildProxy(),this.install()}install(){if(this._installed)return;const t=typeof window<"u"?window:globalThis;this._prevConsole=t.console,t.console=this._proxy,this._installed=!0}restore(){if(!this._installed)return;const t=typeof window<"u"?window:globalThis;t.console=this._prevConsole||this._orig,this._installed=!1}pause(){this._capturing=!1}resume(){this._capturing=!0}getLogs(t={}){const{level:n,since:r,until:a}=t;return this._logs.filter(o=>!(n&&o.level!==n||r&&o.time&&o.time<r||a&&o.time&&o.time>a)).slice()}clearLogs(){this._logs.length=0}get logs(){return this.getLogs()}getLogsAll(){return this.getLogs()}_buildProxy(){const t=this._orig,n={},r=new Set([...Object.getOwnPropertyNames(t),...Object.keys(t)]);["log","info","warn","error","debug","trace","group","groupCollapsed","groupEnd","table","time","timeEnd","timeLog","count","countReset","assert","clear","dir","dirxml"].forEach(o=>r.add(o));for(const o of r){const s=this._safeGetDescriptor(t,o);if(s)if(typeof s.value=="function")n[o]=this._wrapMethod(o,t[o]);else if(s.get||s.set)Object.defineProperty(n,o,{configurable:!0,enumerable:s.enumerable,get:s.get?s.get.bind(t):void 0,set:s.set?s.set.bind(t):void 0});else try{n[o]=t[o]}catch{}}return Object.defineProperty(n,"__capturing__",{value:!0,enumerable:!1}),n}_safeGetDescriptor(t,n){try{return Object.getOwnPropertyDescriptor(t,n)}catch{return null}}_wrapMethod(t,n){const r=this,a=!r.options.levels||r.options.levels.includes(t);function o(...s){const c=t==="assert"?!s[0]:!0;if(r._capturing&&a&&c){const d={id:r._nextId++,level:t,args:s};if(r.options.withTimestamp&&(d.time=new Date),r.options.captureStack){const u=new Error().stack||"";d.stack=u.split(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/main-cad-BckkeW6Q.js","assets/featureDialogs-BlENEp3D.js","assets/browserStorage-CvgF8ovw.js","assets/preload-helper-ZNr0Qq7Q.js","assets/FeatureRegistry-Byo0zhcC.js","assets/deepClone-Dj59xCHB.js","assets/PartHistory-DJNowO8n.js","assets/AssemblyConstraintRegistry-DbpKYepy.js","assets/annUtils-CqMdNOP0.js","assets/ListEntityBase-DIaWtqmZ.js","assets/droppedWorkspaceFiles-8o-ZYOrf.js","assets/AnnotationRegistry-PNrk9ZTv.js","assets/main-cad-C3E_anfF.css"])))=>i.map(i=>d[i]);
2
+ var Ko=Object.defineProperty;var l=(e,t)=>Ko(e,"name",{value:t,configurable:!0});import{b as Jo,g as Bn,D as Yr,a as Zo,r as Gn,c as Xr,d as Ja,e as tr,f as Wn,h as Kr,i as Jr,j as qo,k as Qo,l as es,m as jn,n as Zr,o as ts,p as Xt,q as qr,s as ns,t as rs,u as as,v as os,w as ss,x as is,P as Ut,F as ls,y as Kt,z as cs,A as Qr,B as ds,C as us,E as fs,G as ps,H as _s,I as hs,J as Vn,V as ea,K as ta}from"./main-cad-BckkeW6Q.js";import{q as j}from"./browserStorage-CvgF8ovw.js";import{P as Y,S as An,z as Za}from"./PartHistory-DJNowO8n.js";import{C as qa,B as M,o as ae,E as ms,p as gs,q as na,t as Er,u as ra,v as xs,w as yr,x as Es,y as fn,z as st,T as We,_ as aa,G as Sr,H as ys,I as oa,P as Ss,K as ws,L as Qa,M as eo,N as ze,O as vs,Q as wt,R as bs,U as Jt,J as Fs,j as wr,i as Ps,h as to,V as sa,W as As,X as Ts,Y as Cs}from"./FeatureRegistry-Byo0zhcC.js";import{aI as L,aL as Se,V as $,G as Fe,aK as nr,aH as C,bh as Oe,bi as Ns,bj as no,M as Rs,aN as Is,bk as Os,bl as ro,bm as Ds,bn as Ms,bo as ks,bp as $s,bq as Ls,br as Bs,aJ as kt,bs as vt,bt as Gs,bu as Ws,bv as js,bw as vr,bx as Vs,by as Us,bz as br,bA as ao,bB as oo,ba as so,b9 as ia,bC as io,B as lo,Y as ne,z as Zt,d as Tn,F as Wt,f as Fr,s as Pr,q as we,X as Re,e as zs,L as Hs,O as co,af as rr,bD as la,be as Ys,ad as Xs,ag as Ks,ah as Js,bE as Zs,bF as qs,bG as ca,bH as Qs,b8 as ei,b5 as ti,aT as uo,a$ as ni,Q as ri,bI as da}from"./featureDialogs-BlENEp3D.js";import{_ as ai}from"./preload-helper-ZNr0Qq7Q.js";import{L as pn,_ as at,b as oi,R as Ar,e as Tr}from"./AnnotationRegistry-PNrk9ZTv.js";import"./droppedWorkspaceFiles-8o-ZYOrf.js";import"./deepClone-Dj59xCHB.js";import"./annUtils-CqMdNOP0.js";import"./AssemblyConstraintRegistry-DbpKYepy.js";import"./ListEntityBase-DIaWtqmZ.js";const Vr=class Vr{constructor(t={}){this.options={captureStack:!!t.captureStack,withTimestamp:t.withTimestamp!==!1,levels:t.levels||null,maxEntries:Number.isFinite(t.maxEntries)?t.maxEntries:1/0},this._orig=(typeof window<"u"?window.console:console)||{},this._installed=!1,this._capturing=!0,this._logs=[],this._nextId=1,this._proxy=this._buildProxy(),this.install()}install(){if(this._installed)return;const t=typeof window<"u"?window:globalThis;this._prevConsole=t.console,t.console=this._proxy,this._installed=!0}restore(){if(!this._installed)return;const t=typeof window<"u"?window:globalThis;t.console=this._prevConsole||this._orig,this._installed=!1}pause(){this._capturing=!1}resume(){this._capturing=!0}getLogs(t={}){const{level:n,since:r,until:a}=t;return this._logs.filter(o=>!(n&&o.level!==n||r&&o.time&&o.time<r||a&&o.time&&o.time>a)).slice()}clearLogs(){this._logs.length=0}get logs(){return this.getLogs()}getLogsAll(){return this.getLogs()}_buildProxy(){const t=this._orig,n={},r=new Set([...Object.getOwnPropertyNames(t),...Object.keys(t)]);["log","info","warn","error","debug","trace","group","groupCollapsed","groupEnd","table","time","timeEnd","timeLog","count","countReset","assert","clear","dir","dirxml"].forEach(o=>r.add(o));for(const o of r){const s=this._safeGetDescriptor(t,o);if(s)if(typeof s.value=="function")n[o]=this._wrapMethod(o,t[o]);else if(s.get||s.set)Object.defineProperty(n,o,{configurable:!0,enumerable:s.enumerable,get:s.get?s.get.bind(t):void 0,set:s.set?s.set.bind(t):void 0});else try{n[o]=t[o]}catch{}}return Object.defineProperty(n,"__capturing__",{value:!0,enumerable:!1}),n}_safeGetDescriptor(t,n){try{return Object.getOwnPropertyDescriptor(t,n)}catch{return null}}_wrapMethod(t,n){const r=this,a=!r.options.levels||r.options.levels.includes(t);function o(...s){const c=t==="assert"?!s[0]:!0;if(r._capturing&&a&&c){const d={id:r._nextId++,level:t,args:s};if(r.options.withTimestamp&&(d.time=new Date),r.options.captureStack){const u=new Error().stack||"";d.stack=u.split(`
3
3
  `).slice(2).join(`
4
4
  `)}r.options.maxEntries!==1/0&&r._logs.length>=r.options.maxEntries&&r._logs.shift(),r._logs.push(d)}try{if(typeof n=="function")return n.apply(r._orig,s)}catch(d){try{return r._orig&&typeof r._orig.log=="function"?r._orig.log("ConsoleCapture forwarding error:",d):void 0}catch{}}}l(o,"wrapped");try{Object.defineProperty(o,"name",{value:`capture_${t}`})}catch{}return o}};l(Vr,"ConsoleCapture");let ar=Vr;const ie=!!globalThis?.process?.versions?.node&&typeof window>"u";function ce(){if(!ie)return q;if(typeof require=="function"){const t=require("node:path");return(t.default??t).posix}const e=globalThis?.module;if(e&&typeof e.createRequire=="function"){const n=e.createRequire(globalThis.__filename||globalThis.process.cwd())("node:path");return(n.default??n).posix}return q}l(ce,"getNodePosixSync");const fo="/",si=":";function je(e){if(typeof e!="string")throw new TypeError("Path must be a string")}l(je,"_assertString");function Cn(e){return e.startsWith(fo)}l(Cn,"_isAbsolute");function po(e,t){const n=e.split("/"),r=[];for(let a=0;a<n.length;a++){const o=n[a];!o||o==="."||(o===".."?r.length&&r[r.length-1]!==".."?r.pop():t&&r.push(".."):r.push(o))}return r.join("/")}l(po,"_normalizeString");function _o(e){if(je(e),e==="")return".";const t=Cn(e),n=e.endsWith("/");let r=po(e,!t);return r===""&&!t&&(r="."),r!==""&&n&&(r+="/"),(t?"/":"")+r}l(_o,"_normalize");function ii(...e){let t="";for(let n=0;n<e.length;n++){const r=e[n];je(r),r!==""&&(t===""?t=r:t+="/"+r)}return _o(t)}l(ii,"_join");function or(...e){let t="",n=!1;for(let a=e.length-1;a>=0;a--){const o=e[a];if(o!==void 0&&(je(o),o!==""&&(t=o+"/"+t,o.startsWith("/")))){n=!0;break}}n||(t="/"+t,n=!0);const r=po(t,!1);return(n?"/":"")+r||(n?"/":".")}l(or,"_resolve");function li(e,t){if(je(e),je(t),e===t||(e=or(e),t=or(t),e===t))return"";const n=e.slice(1).split("/").filter(Boolean),r=t.slice(1).split("/").filter(Boolean);let a=0;const o=Math.min(n.length,r.length);for(;a<o&&n[a]===r[a];a++);const s=n.slice(a).map(()=>".."),i=r.slice(a);return s.concat(i).join("/")||""}l(li,"_relative");function ho(e){if(je(e),e.length===0)return".";const t=Cn(e),n=e.endsWith("/")?e.length-1:e.length;let r=-1;for(let a=n-1;a>=0;--a)if(e.charCodeAt(a)===47){r=a;break}return r===-1?t?"/":".":t&&r===0?"/":e.slice(0,r)}l(ho,"_dirname");function mo(e,t=""){if(je(e),t!==void 0&&typeof t!="string")throw new TypeError("ext must be a string");let n=e.length;if(n===0)return"";for(;n>0&&e.charCodeAt(n-1)===47;)n--;if(n===0)return"/";let r=0;for(let o=n-1;o>=0;--o)if(e.charCodeAt(o)===47){r=o+1;break}let a=e.slice(r,n);return t&&a.endsWith(t)&&t!==""&&t!==a&&(a=a.slice(0,a.length-t.length)),a}l(mo,"_basename");function go(e){je(e);let t=-1,n=0,r=-1,a=0;for(let o=e.length-1;o>=0;--o){const s=e.charCodeAt(o);if(s===47){if(r!==-1){n=o+1;break}continue}r===-1&&(r=o+1),s===46?t===-1?t=o:a!==1&&(a=1):t!==-1&&(a=-1)}return t===-1||r===-1||a===0||t===n?"":e.slice(t,r)}l(go,"_extname");function ci(e){je(e);const t=Cn(e)?"/":"",n=ho(e),r=mo(e),a=go(r),o=a?r.slice(0,r.length-a.length):r;return{root:t,dir:n,base:r,ext:a,name:o}}l(ci,"_parse");function di(e){const t=e.dir||e.root||"",n=e.base||(e.name||"")+(e.ext||"");return t?t.endsWith("/")?t+n:t+"/"+n:n||"."}l(di,"_format");function ui(e){return e}l(ui,"_toNamespacedPath");const q={sep:fo,delimiter:si,normalize:_o,join:ii,resolve:or,isAbsolute:Cn,relative:li,dirname:ho,basename:mo,extname:go,parse:ci,format:di,toNamespacedPath:ui,posix:null,win32:null};q.posix=q;const _n={get sep(){return ie?ce().sep:q.sep},get delimiter(){return ie?ce().delimiter:q.delimiter},normalize:l((...e)=>ie?ce().normalize(...e):q.normalize(...e),"normalize"),join:l((...e)=>ie?ce().join(...e):q.join(...e),"join"),resolve:l((...e)=>ie?ce().resolve(...e):q.resolve(...e),"resolve"),isAbsolute:l((...e)=>ie?ce().isAbsolute(...e):q.isAbsolute(...e),"isAbsolute"),relative:l((...e)=>ie?ce().relative(...e):q.relative(...e),"relative"),dirname:l((...e)=>ie?ce().dirname(...e):q.dirname(...e),"dirname"),basename:l((...e)=>ie?ce().basename(...e):q.basename(...e),"basename"),extname:l((...e)=>ie?ce().extname(...e):q.extname(...e),"extname"),parse:l((...e)=>ie?ce().parse(...e):q.parse(...e),"parse"),format:l((...e)=>ie?ce().format(...e):q.format(...e),"format"),toNamespacedPath:l((...e)=>ie?ce().toNamespacedPath(...e):q.toNamespacedPath(...e),"toNamespacedPath"),posix:null,win32:null};_n.posix=_n;const fi=new Proxy({},{get(){throw new Error("POSIX-only path module: use the named export `posix` with your VFS.")}});_n.win32=fi;const Ie=_n,Un=.01,ua="src/tests/fixtures/sketchSolverTopology";function Ee(e,t){if(!e)throw new Error(t)}l(Ee,"assert$y");function hn(e,t){const n=e.points.find(r=>Number(r.id)===Number(t));if(!n)throw new Error(`Point ${t} not found`);return n}l(hn,"getPoint$1");function pi(e,t){const n=e.constraints.find(r=>Number(r.id)===Number(t));if(!n)throw new Error(`Constraint ${t} not found`);return n}l(pi,"getConstraint$1");function fa(e,t,n){const r=hn(e,t),a=hn(e,n);return Math.hypot(a.x-r.x,a.y-r.y)}l(fa,"dist$1");function pa(e,t){const n=t.map(a=>hn(e,a));let r=0;for(let a=0;a<n.length;a++){const o=n[a],s=n[(a+1)%n.length];r+=o.x*s.y-s.x*o.y}return r*.5}l(pa,"signedArea$1");function _a(e){const t=(e.points||[]).map(a=>Number(a.id)).sort((a,o)=>a-o),n=(e.geometries||[]).map(a=>({id:Number(a.id),type:String(a.type),construction:!!a.construction,points:(a.points||[]).map(o=>Number(o))})).sort((a,o)=>a.id-o.id),r=(e.constraints||[]).map(a=>({id:Number(a.id),type:String(a.type),points:(a.points||[]).map(o=>Number(o))})).sort((a,o)=>a.id-o.id);return{pointIds:t,geometries:n,constraints:r}}l(_a,"topologySnapshot$1");function _i(e,t){const n=new Set((e.points||[]).map(r=>Number(r.id)));for(const r of e.geometries||[])for(const a of r.points||[])Ee(n.has(Number(a)),`${t}: geometry ${r.id} references missing point ${a}`);for(const r of e.constraints||[])for(const a of r.points||[])Ee(n.has(Number(a)),`${t}: constraint ${r.id} references missing point ${a}`)}l(_i,"assertTopologyIntegrity$1");function hi(e,t="fixture"){const n=String(e||"").trim();return n&&n.toLowerCase().replace(/[^a-z0-9._-]+/g,"_").replace(/^_+|_+$/g,"").slice(0,120)||t}l(hi,"sanitizeName");function zn(e,t,n,r){if(!Number.isFinite(e)||!Number.isFinite(t)||Math.abs(e-t)>n)throw new Error(`${r}. Expected ${t}, got ${e}`)}l(zn,"assertNear$1");function mi(e,t={}){if(typeof e!="string"||!e.trim())return null;const n=Object.keys(t||{}),r=n.map(a=>Number(t[a]));if(!r.every(a=>Number.isFinite(a)))return null;try{const o=Function(...n,`"use strict"; return (${e});`)(...r),s=Number(o);return Number.isFinite(s)?s:null}catch{return null}}l(mi,"evaluateExpressionWithVars");function xo(e,{maxPasses:t=8,stopWhenConstraintsClear:n=!0}={}){const r=Math.max(1,Number(t)||1);let a=null;for(let o=0;o<r;o++){e.solveSketch("full");const s=e.sketchObject,i=JSON.stringify(s?.points||[]),c=Array.isArray(s?.constraints)?s.constraints.some(d=>typeof d?.error=="string"&&d.error.length>0):!1;if(n&&!c||i===a)break;a=i}}l(xo,"solveWithSettle");function gi(e,t,n){const r=t&&typeof t=="object"?t:null;if(!r)throw new Error(`${n}: expressionValues edit requires an object`);for(const a of e.sketchObject?.constraints||[]){if(typeof a?.valueExpr!="string"||!a.valueExpr.length)continue;const o=mi(a.valueExpr,r);if(!Number.isFinite(o))continue;const s=a?.type==="⟺"&&a?.displayStyle==="diameter"&&a?.valueExprMode==="diameter";a.value=s?Number(o)*.5:Number(o)}}l(gi,"applyExpressionValuesToConstraints");function xi(e,t,n){for(const r of t||[])if(!(!r||typeof r!="object")){if(Object.prototype.hasOwnProperty.call(r,"expressionValues"))gi(e,r.expressionValues,n);else{const a=Number(r.constraintId),o=Number(r.value);if(!Number.isFinite(a))throw new Error(`${n}: edit has invalid constraintId`);if(!Number.isFinite(o))throw new Error(`${n}: edit for constraint ${a} has invalid value`);const s=pi(e.sketchObject,a);s.value=o}xo(e,{maxPasses:Number.isFinite(Number(r.maxPasses))?Number(r.maxPasses):8,stopWhenConstraintsClear:r.stopWhenConstraintsClear!==!1})}}l(xi,"applyEdits");function Ei({before:e,after:t,expect:n,contextLabel:r}){if(_i(t,r),n?.topologyUnchanged!==!1){const o=JSON.stringify(_a(e)),s=JSON.stringify(_a(t));Ee(o===s,`${r}: topology changed`)}for(const o of n?.distances||[]){const s=Number(o.a),i=Number(o.b),c=Number(o.value),d=Number.isFinite(Number(o.tol))?Number(o.tol):Un;Ee(Number.isFinite(s)&&Number.isFinite(i),`${r}: invalid distance pair`),zn(fa(t,s,i),c,d,`${r}: distance [${s},${i}] mismatch`)}for(const o of n?.anchors||[]){const s=Number(o.pointId),i=Number.isFinite(Number(o.tol))?Number(o.tol):Un,c=hn(t,s);Number.isFinite(Number(o.x))&&zn(c.x,Number(o.x),i,`${r}: anchor ${s} x drift`),Number.isFinite(Number(o.y))&&zn(c.y,Number(o.y),i,`${r}: anchor ${s} y drift`)}for(const o of n?.coincidentPairs||[]){const s=Number(o.a),i=Number(o.b),c=Number.isFinite(Number(o.tol))?Number(o.tol):Un;Ee(Number.isFinite(s)&&Number.isFinite(i),`${r}: invalid coincident pair`),Ee(fa(t,s,i)<=c,`${r}: coincident pair [${s},${i}] broke`)}for(const o of n?.orientationLoops||[]){const s=Array.isArray(o?.pointIds)?o.pointIds.map(u=>Number(u)):[];Ee(s.length>=3,`${r}: orientation loop needs at least 3 points`);const i=Number.isFinite(Number(o.minAbsArea))?Number(o.minAbsArea):1,c=pa(e,s),d=pa(t,s);Ee(Math.abs(d)>i,`${r}: loop collapsed`),o.preserveSign!==!1&&Ee(Math.sign(d)===Math.sign(c),`${r}: loop orientation flipped`)}}l(Ei,"runExpectations");async function yi(e,t){const r=`sketch fixture ${e?.name||Ie.basename(t)}`;Ee(e&&typeof e=="object",`${r}: fixture is not an object`),Ee(Array.isArray(e.edits),`${r}: missing edits array`);let a=null;if(e.sketch&&typeof e.sketch=="object")a=e.sketch;else if(typeof e.sourcePartFile=="string"&&e.sourcePartFile.trim().length){const c=e.sourcePartFile.trim(),d=await j.promises.readFile(c,"utf8"),u=JSON.parse(d),f=Array.isArray(u?.features)?u.features:[];let p=null;if(e.sourceFeatureId!=null){const _=String(e.sourceFeatureId);p=f.find(h=>h?.type==="S"&&(String(h?.inputParams?.id??"")===_||String(h?.inputParams?.featureID??"")===_))||null}p||(p=f.find(_=>_?.type==="S"&&_?.persistentData?.sketch)||null),a=p?.persistentData?.sketch||null}Ee(a&&typeof a=="object",`${r}: missing sketch or sourcePartFile sketch`);const o=new qa({sketch:JSON.parse(JSON.stringify(a))});xo(o,{maxPasses:Number.isFinite(Number(e.initialSolvePasses))?Number(e.initialSolvePasses):4,stopWhenConstraintsClear:!0});const s=JSON.parse(JSON.stringify(o.sketchObject));xi(o,e.edits,r);const i=o.sketchObject;Ei({before:s,after:i,expect:e.expect||{},contextLabel:r})}l(yi,"runFixture");async function Si(e){if(!(typeof process<"u"&&process.versions&&process.versions.node))return 0;const t=new Set((e||[]).map(o=>o?._sourceFile).filter(o=>typeof o=="string"&&o.length>0));let n=[];try{n=await j.promises.readdir(ua)}catch{return 0}const r=n.filter(o=>typeof o=="string"&&o.toLowerCase().endsWith(".json")).sort((o,s)=>o.localeCompare(s));let a=0;for(const o of r){const s=Ie.join(ua,o);if(t.has(s))continue;let i=null;try{const p=await j.promises.readFile(s,"utf8");i=JSON.parse(p)}catch(p){const _=p?.message||String(p);throw new Error(`Failed to read sketch fixture ${s}: ${_}`)}const c=String(o).replace(/\.[^.]+$/,""),u=`test_sketch_solver_fixture_${hi(i?.name||c,`fixture_${a}`)}`,f=l(async function(){await yi(i,s)},"sketchSolverFixtureTest");try{Object.defineProperty(f,"name",{value:u,configurable:!0})}catch{}e.push({test:f,printArtifacts:!1,exportFaces:!1,exportSolids:!1,resetHistory:!0,_sourceFile:s}),t.add(s),a+=1}return a}l(Si,"registerSketchSolverTopologyFixtureTests");async function wi(e){const t=await e.newFeature("P.CO");t.inputParams.radiusTop=3,t.inputParams.radiusBottom=.5,t.inputParams.height=5.2,t.inputParams.resolution=20;const n=await e.newFeature("P.CU");n.inputParams.sizeX=2,n.inputParams.sizeY=2,n.inputParams.sizeZ=20;const r=await e.newFeature("B");return r.inputParams.targetSolid=n.inputParams.featureID,r.inputParams.boolean={targets:[t.inputParams.featureID],operation:"SUBTRACT"},e}l(wi,"test_boolean_subtract");async function vi(e){const t=await e.newFeature("P.CU");t.inputParams.sizeX=10,t.inputParams.sizeY=10,t.inputParams.sizeZ=10;const n=await e.newFeature("P.CU");return n.inputParams.sizeX=10,n.inputParams.sizeY=10,n.inputParams.sizeZ=10,n.inputParams.transform={position:[5,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},n.inputParams.boolean={operation:"UNION",targets:[t.inputParams.featureID]},e}l(vi,"test_boolean_operation_target_name_preserved");async function bi(e){const t=(e?.features||[]).filter(i=>i?.type==="P.CU");if(t.length<2)throw new Error("[boolean target name] Expected at least two primitive cube features.");const n=t[0]?.inputParams?.featureID,r=t[1]?.inputParams?.featureID;if(!n||!r)throw new Error("[boolean target name] Missing feature IDs for cube setup.");const a=(e?.scene?.children||[]).filter(i=>i?.type==="SOLID");if(a.length!==1)throw new Error(`[boolean target name] Expected exactly one solid after union, got ${a.length}.`);const o=a[0];if(String(o?.name||"")!==String(n))throw new Error(`[boolean target name] Expected result name "${n}", got "${String(o?.name||"")}".`);if(e?.scene?.getObjectByName?.(r))throw new Error(`[boolean target name] Tool-named solid "${r}" should have been replaced.`)}l(bi,"afterRun_boolean_operation_target_name_preserved");function bt(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(bt,"assert$x");async function Fi(){const e=new M.Cube({x:10,y:10,z:10,name:"BASE"}),t=new M.Cube({x:6,y:6,z:6,name:"TOOL"});e.setFaceMetadata("BASE_NX",{sourceFeatureId:"BASE_FEATURE",marker:"base-nx"}),t.setFaceMetadata("TOOL_PX",{sourceFeatureId:"TOOL_FEATURE",marker:"tool-px"}),e.addCenterline([-5,0,0],[5,0,0],"BASE_AXIS"),t.addCenterline([0,-3,0],[0,3,0],"TOOL_AXIS"),t.bakeTRS({position:[7,2,2],rotationEuler:[0,0,0],scale:[1,1,1]}),e.union=()=>{throw new Error("forced union failure for metadata fallback test")};const n={scene:{getObjectByName(){return null}}},r=await M.applyBooleanOperation(n,e,{operation:"UNION",targets:[t]},"BOOL_META"),a=Array.isArray(r?.added)?r.added[0]:null;bt(a,"Expected boolean to return a result solid.");const o=a.getFaceMetadata("BASE_NX");bt(o&&o.sourceFeatureId==="BASE_FEATURE","Base face provenance should survive union fallback."),bt(o&&o.marker==="base-nx","Base face custom metadata should survive union fallback.");const s=Array.isArray(a._auxEdges)?a._auxEdges:[];bt(s.some(i=>i?.name==="BASE_AXIS"&&i?.centerline),"Base centerline should survive union fallback."),bt(s.some(i=>i?.name==="TOOL_AXIS"&&i?.centerline),"Tool centerline should survive union fallback.")}l(Fi,"test_boolean_face_metadata_preserved");function ee(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(ee,"assert$w");function Nn(e,t,n=0){const r=typeof e?.getFace=="function"?e.getFace(t):[];let a=Number.POSITIVE_INFINITY;for(const o of r)for(const s of[o?.p1,o?.p2,o?.p3])!Array.isArray(s)||s.length<3||(a=Math.min(a,Number(s[n])));return a}l(Nn,"faceAxisMin");function Rn(e,t,n=0){const r=typeof e?.getFace=="function"?e.getFace(t):[];let a=Number.NEGATIVE_INFINITY;for(const o of r)for(const s of[o?.p1,o?.p2,o?.p3])!Array.isArray(s)||s.length<3||(a=Math.max(a,Number(s[n])));return a}l(Rn,"faceAxisMax");function In(e,t){const n=new M.Cube({x:1,y:1,z:1,name:e}),r=new M.Cube({x:1,y:1,z:1,name:t});return r.bakeTRS({position:[1,0,0],rotationEuler:[0,0,0],scale:[1,1,1]}),{base:n,tool:r}}l(In,"makeTouchingCubePair");function Cr(){return{scene:{getObjectByName(){return null}}}}l(Cr,"makeFakePartHistory");async function Eo(e){const{base:t,tool:n}=In("BASE","TOOL"),r=Object.getPrototypeOf(t),a=r.union;let o=null,s=null;r.union=l(function(c){return o===null&&(o=Rn(this,"BASE_PX",0),s=Nn(c,"TOOL_NX",0)),a.call(this,c)},"patchedUnion");try{await M.applyBooleanOperation(Cr(),t,{operation:"UNION",targets:[n],...e},"BOOL_OVERLAP_UNION")}finally{r.union=a}return{observedBasePXMax:o,observedToolNXMin:s}}l(Eo,"captureUnionConditionedFaces");async function yo(e){const{base:t,tool:n}=In("TARGET","CUTTER"),r=Object.getPrototypeOf(t),a=r.subtract;let o=null;r.subtract=l(function(i){return o===null&&(o=Nn(i,"CUTTER_NX",0)),a.call(this,i)},"patchedSubtract");try{await M.applyBooleanOperation(Cr(),n,{operation:"SUBTRACT",targets:[t],...e},"BOOL_OVERLAP_SUBTRACT")}finally{r.subtract=a}return o}l(yo,"captureSubtractOperandMinX");async function Pi(e){const t=new M.Cube({x:1,y:1,z:1,name:"TARGET_Z"}),n=new M.Cube({x:1,y:1,z:2,name:"CUTTER_Z"}),r=Object.getPrototypeOf(t),a=r.subtract;let o=null,s=null;r.subtract=l(function(c){return o===null&&(o=Nn(c,"CUTTER_Z_NZ",2),s=Rn(c,"CUTTER_Z_NZ",2)),a.call(this,c)},"patchedSubtract");try{await M.applyBooleanOperation(Cr(),n,{operation:"SUBTRACT",targets:[t],...e},"BOOL_OVERLAP_SUBTRACT_CAP")}finally{r.subtract=a}return{observedMinZ:o,observedMaxZ:s}}l(Pi,"captureSubtractOperandMinZForEntryCap");async function Ai(){const{observedBasePXMax:e}=await Eo({});ee(Number.isFinite(e),"Expected union test to observe the conditioned base face."),ee(e>1+1e-7,`Expected default union edge-point conditioning to push BASE_PX into the target solid, got maxX=${e}`)}l(Ai,"test_boolean_overlap_conditioning_union_enabled_by_default");async function Ti(){const{observedBasePXMax:e,observedToolNXMin:t}=await Eo({overlapConditioningEnabled:!1});ee(Number.isFinite(e)&&Number.isFinite(t),"Expected disabled union test to observe the faces."),ee(Math.abs(e-1)<=1e-12,`Expected disabled union conditioning to leave BASE_PX at x=1, got maxX=${e}`),ee(Math.abs(t-1)<=1e-12,`Expected disabled union conditioning to leave TOOL_NX at x=1, got minX=${t}`)}l(Ti,"test_boolean_overlap_conditioning_union_can_be_disabled");async function Ci(){const e=await yo({});ee(Number.isFinite(e),"Expected subtract test to observe the conditioned cutter face."),ee(e>1+1e-7,`Expected default subtract edge-point conditioning to push CUTTER_NX outside the target solid, got minX=${e}`)}l(Ci,"test_boolean_overlap_conditioning_subtract_enabled_by_default");async function Ni(){const{observedMinZ:e,observedMaxZ:t}=await Pi({});ee(Number.isFinite(e)&&Number.isFinite(t),"Expected subtract cap test to observe the conditioned cutter cap face."),ee(e<0-1e-7,`Expected subtract conditioning to expand CUTTER_Z_NZ outward beyond z=0, got minZ=${e}`),ee(Math.abs(t-e)<=1e-12,`Expected CUTTER_Z_NZ to remain planar after conditioning, got minZ=${e}, maxZ=${t}`)}l(Ni,"test_boolean_overlap_conditioning_subtract_expands_tool_entry_cap_outward");async function Ri(){const e=await yo({overlapConditioningEnabled:!1});ee(Number.isFinite(e),"Expected disabled subtract test to observe the cutter face."),ee(Math.abs(e-1)<=1e-12,`Expected disabled subtract conditioning to leave CUTTER_NX at x=1, got minX=${e}`)}l(Ri,"test_boolean_overlap_conditioning_subtract_can_be_disabled");async function Ii(){const{base:e,tool:t}=In("BASE_API","TOOL_API"),n=e.union(t);ee(n,"Expected direct union to return a result solid."),ee(Rn(e,"BASE_API_PX",0)===1,"Direct union should not mutate the source solid.");const r=new M.Cube({x:1,y:1,z:1,name:"TARGET_API"}),a=new M.Cube({x:1,y:1,z:1,name:"CUTTER_API"});a.bakeTRS({position:[1,0,0],rotationEuler:[0,0,0],scale:[1,1,1]});const o=r.subtract(a);ee(o,"Expected direct subtract to return a result solid."),ee(Nn(a,"CUTTER_API_NX",0)===1,"Direct subtract should not mutate the cutter solid.")}l(Ii,"test_boolean_overlap_conditioning_direct_api_enabled_by_default");async function Oi(){const{base:e,tool:t}=In("BASE_API_OFF","TOOL_API_OFF"),n=Object.getPrototypeOf(e),r=n.union;let a=null;n.union=l(function(s,i){return a=Rn(this,"BASE_API_OFF_PX",0),r.call(this,s,i)},"patchedUnion");try{e.union(t,{overlapConditioningEnabled:!1})}finally{n.union=r}ee(Math.abs(a-1)<=1e-12,`Expected disabled direct union conditioning to leave BASE_API_OFF_PX at x=1, got ${a}`)}l(Oi,"test_boolean_overlap_conditioning_direct_api_can_be_disabled");async function Di(e){const t=await e.newFeature("P.CU");t.inputParams.sizeX=20,t.inputParams.sizeY=20,t.inputParams.sizeZ=20;const n=await e.newFeature("CHAMFER");return n.inputParams.edges=[`${t.inputParams.featureID}_PZ`],n.inputParams.distance=3,n.inputParams.inflate=5e-4,n.inputParams.direction="INSET",e}l(Di,"test_Chamfer");function b(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(b,"assert$v");const Mi={points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:-2.504334,y:-3.287135,fixed:!1,construction:!1,externalReference:!1},{id:2,x:6.391665,y:6.452413,fixed:!1,construction:!1,externalReference:!1},{id:3,x:-2.504334,y:-3.287135,fixed:!1,construction:!1,externalReference:!1},{id:6,x:6.391665,y:6.452413,fixed:!1,construction:!1,externalReference:!1},{id:7,x:-2.504333,y:6.452412,fixed:!1,construction:!1,externalReference:!1},{id:8,x:-2.504333,y:6.452412,fixed:!1,construction:!1,externalReference:!1},{id:15,x:1.803917,y:3.614373,fixed:!1,construction:!1,externalReference:!1},{id:16,x:1.803917,y:3.614373,fixed:!1,construction:!1,externalReference:!1},{id:17,x:1.764345,y:-4.025491,fixed:!1,construction:!1,externalReference:!1},{id:18,x:6.391665,y:4.346518,fixed:!1,construction:!1,externalReference:!1}],geometries:[{id:3,type:"line",points:[6,7],construction:!1},{id:4,type:"line",points:[8,3],construction:!1},{id:9,type:"line",points:[1,17],construction:!1},{id:10,type:"line",points:[16,17],construction:!1},{id:11,type:"line",points:[18,15],construction:!1},{id:12,type:"line",points:[18,2],construction:!1}],constraints:[{id:0,type:"⏚",points:[0],status:"solved",error:null,_previousSolveValue:null,previousPointValues:"0:0,0,1;"},{id:1,type:"≡",points:[1,3],status:"",error:null,_previousSolveValue:null,previousPointValues:"1:-2.504334,-3.287135,0;3:-2.504334,-3.287135,0;"},{id:3,type:"≡",points:[2,6],status:"solved",error:null,_previousSolveValue:null,previousPointValues:"2:6.391665,6.452413,0;6:6.391665,6.452413,0;"},{id:4,type:"≡",points:[7,8],status:"",error:null,_previousSolveValue:null,previousPointValues:"7:-2.504333,6.452412,0;8:-2.504333,6.452412,0;"},{id:7,type:"⟂",points:[6,7,8,3],status:"",error:null,value:270,_previousSolveValue:270,previousPointValues:"6:5.357399948061701,6.756693642653996,0;7:-2.8534559480617006,6.093104357346005,0;8:-2.853456,6.093105,0;3:-2.150647,-2.603049,0;"},{id:8,type:"│",points:[8,3],labelX:0,labelY:0,displayStyle:"",value:null,valueNeedsSetup:!0,status:"",error:null,_previousSolveValue:null,previousPointValues:"8:-2.504327,6.4524,0;3:-2.504327,-3.27361,0;"},{id:12,type:"≡",points:[15,16],status:"solved",error:null,_previousSolveValue:null,previousPointValues:"15:1.803917,3.614373,0;16:1.803917,3.614373,0;"}]},ki=["E3:S2:PROFILE_START|F4_FILLET_E3_S2_G10_SW_E3_S2_G11_SW_e44b5ee8_3_TUBE_Outer[0]","E3:S2:G11_SW|E3:S2:PROFILE_START[0]","E3:S2:G10_SW|E3:S2:PROFILE_START[0]","E3:S2:PROFILE_START|F4_FILLET_E3_S2_G11_SW_E3_S2_G12_SW_78da4f1c_5_TUBE_Outer[0]","E3:S2:G12_SW|E3:S2:PROFILE_START[0]","E3:S2:PROFILE_START|F4_FILLET_E3_S2_G12_SW_E3_S2_G3_SW_90d5733b_1_TUBE_Outer[0]","E3:S2:G3_SW|E3:S2:PROFILE_START[0]","E3:S2:PROFILE_START|F4_FILLET_E3_S2_G3_SW_E3_S2_G4_SW_6a443286_2_TUBE_Outer[0]","E3:S2:G4_SW|E3:S2:PROFILE_START[0]","E3:S2:PROFILE_START|F4_FILLET_E3_S2_G4_SW_E3_S2_G9_SW_6e866edc_4_TUBE_Outer[0]","E3:S2:G9_SW|E3:S2:PROFILE_START[0]","E3:S2:PROFILE_START|F4_FILLET_E3_S2_G10_SW_E3_S2_G9_SW_478767db_0_TUBE_Outer[0]"],Nr="E3:S2:PROFILE_START|F4_FILLET_E3_S2_G11_SW_E3_S2_G12_SW_78da4f1c_5_TUBE_Outer[0]";function nt(e,t){return Math.hypot(Number(e[0])-Number(t[0]),Number(e[1])-Number(t[1]),Number(e[2])-Number(t[2]))}l(nt,"pointDistance$1");function jt(e,t){return[Number(e[0])-Number(t[0]),Number(e[1])-Number(t[1]),Number(e[2])-Number(t[2])]}l(jt,"subtractPoints");function So(e,t){return Number(e[0])*Number(t[0])+Number(e[1])*Number(t[1])+Number(e[2])*Number(t[2])}l(So,"dotPoints");function ha(e){const t=Math.hypot(Number(e[0]),Number(e[1]),Number(e[2]));return t>1e-12?[Number(e[0])/t,Number(e[1])/t,Number(e[2])/t]:[0,0,0]}l(ha,"normalizePoint");function $i(e,t=!1){if(!Array.isArray(e)||e.length<2)return 1e-6;const n=t?e.length:e.length-1;let r=0,a=0,o=0;for(let i=0;i<n;i+=1){const c=e[i],d=e[(i+1)%e.length],u=nt(c,d);u>1e-12&&(r+=u,a=Math.max(a,u),o+=1)}if(o===0)return 1e-6;const s=r/o;return Math.max(1e-6,s*.5,a*.1)}l($i,"computeChamferTangentSampleDistance");function Li(e,t,n){const r=jt(t,e),a=jt(n,e),o=[r[1]*a[2]-r[2]*a[1],r[2]*a[0]-r[0]*a[2],r[0]*a[1]-r[1]*a[0]];return .5*Math.hypot(o[0],o[1],o[2])}l(Li,"triangleArea3");function Bi(e,t,n,r=!1){if(!Array.isArray(e)||e.length<2||t>=e.length)return[0,0,0];const a=e.length,o=Number.isFinite(n)?Math.max(1e-6,n):1e-6;let s=t,i=t;if(r){let f=0,p=0;for(;p+1<a&&f<o;){const x=(s+a-1)%a;f+=nt(e[s],e[x]),s=x,p+=1}let _=0,h=0;for(;h+1<a&&_<o;){const x=(i+1)%a;_+=nt(e[x],e[i]),i=x,h+=1}}else{let f=0;for(;s>0&&f<o;)f+=nt(e[s],e[s-1]),s-=1;let p=0;for(;i+1<a&&p<o;)p+=nt(e[i+1],e[i]),i+=1}const c=jt(e[i],e[s]);if(So(c,c)>1e-14)return ha(c);const d=r?(t+a-1)%a:t>0?t-1:0,u=r?(t+1)%a:Math.min(a-1,t+1);return ha(jt(e[u],e[d]))}l(Bi,"computeChamferStableTangent");function Gi(e,t,n){const r=[e?.a,e?.b,e?.c].map(u=>[Number(u?.[0]),Number(u?.[1]),Number(u?.[2])]),a=Array.isArray(t?.userData?.polylineLocal)?t.userData.polylineLocal:[];b(r.length===3,"Expected chamfer section debug entry to expose exactly three points."),b(r.every(u=>u.every(f=>Number.isFinite(f))),"Expected chamfer section debug entry to expose finite point coordinates."),b(a.length>=2,"Expected chamfer regression edge to expose a polyline.");const o=a.length-1,s=a[o],i=$i(a,!1),c=Bi(a,o,i,!1);b(Math.hypot(...c)>1e-9,"Expected endpoint tangent for chamfer section entry to be finite.");const d=r.reduce((u,f)=>nt(f,s)<nt(u,s)?f:u,r[0]);return Math.max(...r.map(u=>Math.abs(So(jt(u,d),c))))}l(Gi,"maxSectionEntryDistanceFromEndpointPlane");function Rr(e,t,{distance:n,inflate:r=0,direction:a="INSET",name:o="CPP_CHAMFER_NATIVE_TOOL",debugCrossSections:s=!1}={}){const i=Se(e);b(i,"Expected solid to expose an authoring snapshot for native chamfer testing.");const c=String(t?.faces?.[0]?.name||""),d=String(t?.faces?.[1]?.name||"");b(c&&d,"Expected chamfer test edge to expose two adjacent face names.");const u=Array.isArray(t?.userData?.polylineLocal)?t.userData.polylineLocal:Array.isArray(t?.points)?t.points:[];return b(u.length>=2,"Expected chamfer test edge to expose a polyline."),L.buildChamferAuthoringState({snapshot:i,faceAName:c,faceBName:d,polyline:u,distance:n,inflate:r,direction:a,name:o,debugCrossSections:s})}l(Rr,"buildNativeChamferToolSnapshot");function wo(e){return Array.isArray(e?.faceNameToID)?e.faceNameToID.map(t=>String(Array.isArray(t)?t[0]:"")):[]}l(wo,"snapshotFaceNames");async function zt(e=new Y){e.expressions=`resolution = 32;
5
5
  `,e.configurator={fields:[],values:{}};const t=await e.newFeature("D");Object.assign(t.inputParams,{id:"D1",transform:{position:[.2565036028836988,5.286649371275551,-3.590228990331272],rotationEuler:[-32.818971321018715,30.63210260878807,-2.671532847188412],scale:[1,1,1]}});const n=await e.newFeature("S");Object.assign(n.inputParams,{id:"S2",sketchPlane:"D1:XY",editSketch:null,dumpSketchDiagnostics:null,curveResolution:"resolution"}),n.persistentData={sketch:Mi};const r=await e.newFeature("E");Object.assign(r.inputParams,{id:"E3",profile:"S2:PROFILE",consumeProfileSketch:!0,distance:10,distanceBack:10,boolean:{targets:[],operation:"NONE",overlapConditioningEnabled:!0}});const a=await e.newFeature("F");Object.assign(a.inputParams,{id:"F4",edges:["E3:S2:G10_SW|E3:S2:G9_SW[0]","E3:S2:G12_SW|E3:S2:G3_SW[0]","E3:S2:G3_SW|E3:S2:G4_SW[0]","E3:S2:G10_SW|E3:S2:G11_SW[0]","E3:S2:G4_SW|E3:S2:G9_SW[0]","E3:S2:G11_SW|E3:S2:G12_SW[0]"],radius:1,resolution:"resolution",inflate:"0.2",nudgeFaceDistance:".0001",direction:"AUTO",debug:"NONE",simplifyResult:!0,cleanupNativeTinyFaceIslands:!0,reverseEndCapNudge:!1,mergeCoplanarEndCaps:!0,reassignSliverTriangles:!0,collapseTinyTriangles:!0,cleanupPostCollapseTinyFaceIslands:!0}),await e.runHistory();const o=(e.scene?.children||[]).find(i=>i?.type==="SOLID"&&i?.name==="E3");b(o,"Expected foldback fixture to produce solid E3.");const s=(o.children||[]).find(i=>i?.type==="EDGE"&&i?.name==="E3:S2:PROFILE_START|F4_FILLET_E3_S2_G10_SW_E3_S2_G11_SW_e44b5ee8_3_TUBE_Outer[0]");return b(s,"Expected foldback fixture to expose the fillet outer edge for chamfer testing."),{solid:o,edge:s}}l(zt,"buildFoldbackFixture");function On(e,t){const n=Array.isArray(e?.children)?e.children:[];return t.map(r=>n.find(a=>a?.type==="EDGE"&&String(a?.name||"")===String(r)))}l(On,"resolveFixtureEdgesByName");async function Wi(){if(typeof L?.buildChamferWorkflowAuthoringState!="function"||typeof L?.buildChamferAuthoringState!="function")return;const e=new ae({x:20,y:20,z:20,name:"CPP_CHAMFER_CUBE"});e.visualize();const t=(e.children||[]).find(d=>d?.type==="EDGE"&&d?.faces?.length===2);b(t,"Expected visualized cube to expose a boundary edge for chamfer testing.");const n=Rr(e,t,{distance:3,inflate:5e-4,direction:"INSET",name:"CPP_CHAMFER_SINGLE_EDGE_TOOL"});b(n?.chamferBuildMode==="CHAIN_HULL","Expected native chamfer tool to be built from chained hull segments.");const r=wo(n);b(r.length>0,"Expected native chained-hull chamfer tool to expose faces.");const a=String(t.faces[0]?.name||""),o=String(t.faces[1]?.name||""),s=`CHAMFER_${a}|${o}`;b(r.includes(`${s}_SIDE_A`)&&r.includes(`${s}_SIDE_B`)&&r.includes(`${s}_BEVEL`)&&r.includes(`${s}_CAP0`)&&r.includes(`${s}_CAP1`),"Expected native chained-hull chamfer tool to restore the legacy semantic chamfer face names.");const i=await e.chamfer({distance:3,edges:[t],direction:"INSET",inflate:5e-4,debug:!0,featureID:"CPP_CHAMFER"});b(i&&i.getTriangleCount()>0,"Expected native chamfer result to contain triangles.");const c=Array.isArray(i.__debugChamferSolids)?i.__debugChamferSolids[0]:null;b(c,"Expected native chamfer path to retain the built chamfer tool solid for debug inspection."),b(c.getTriangleCount()>0,"Expected debug chamfer tool solid to contain triangles.")}l(Wi,"test_cppChamfer_single_edge_builds_native_named_tool_and_result");async function ji(){if(typeof L?.buildChamferWorkflowAuthoringState!="function")return;const e=new ae({x:20,y:20,z:20,name:"CPP_CHAMFER_AUTO_CUBE"});e.visualize();const t=(e.children||[]).find(a=>a?.type==="EDGE"&&a?.faces?.length===2);b(t,"Expected visualized cube to expose a boundary edge for AUTO chamfer testing.");const n=await e.chamfer({distance:2,edges:[t],direction:"AUTO",inflate:5e-4,debug:!0,featureID:"CPP_CHAMFER_AUTO"});b(n&&n.getTriangleCount()>0,"Expected AUTO native chamfer result to contain triangles.");const r=Array.isArray(n.__debugChamferSolids)?n.__debugChamferSolids[0]:null;b(r,"Expected AUTO native chamfer path to retain the built chamfer tool."),b(r.getTriangleCount()>0,"Expected AUTO native chamfer tool to contain triangles.")}l(ji,"test_cppChamfer_auto_direction_uses_native_classifier");async function Vi(e=new Y){if(typeof L?.buildChamferWorkflowAuthoringState!="function"||typeof L?.buildChamferAuthoringState!="function")return;const{solid:t,edge:n}=await zt(e),r=Rr(t,n,{distance:.5,inflate:.1,direction:"INSET",name:"CPP_CHAMFER_FOLDBACK_TOOL",debugCrossSections:!0});b(r?.chamferBuildMode==="CHAIN_HULL","Expected foldback regression tool to use chained hull construction.");const a=wo(r),o=`CHAMFER_${String(n.faces[0]?.name||"")}|${String(n.faces[1]?.name||"")}`;b(a.includes(`${o}_SIDE_A`)&&a.includes(`${o}_SIDE_B`)&&a.includes(`${o}_BEVEL`)&&a.includes(`${o}_CAP0`)&&a.includes(`${o}_CAP1`),"Expected foldback regression tool to restore the legacy semantic chamfer face names.");const s=Array.isArray(r?.debugCrossSectionSnapshots)?r.debugCrossSectionSnapshots:[];b(s.length>=4,`Expected foldback regression tool to emit several cross sections; received ${s.length}.`);for(const i of s){const c=i?.a||[],d=i?.b||[],u=i?.c||[];b(Li(c,d,u)>1e-8,`Expected foldback regression cross section ${i?.name||"<unknown>"} to remain a valid triangle.`)}}l(Vi,"test_cppChamfer_stabilizes_tiny_terminal_segments_before_offsetting");async function Ui(e=new Y){if(typeof L?.buildChamferWorkflowAuthoringState!="function")return;const{solid:t}=await zt(e),n=On(t,ki);b(n.every(i=>i),"Expected tangent-cap regression fixture to expose all requested chamfer edges.");const r=await t.chamfer({distance:.5,edges:n,direction:"AUTO",inflate:.1,debug:!0,featureID:"CPP_CHAMFER_TANGENT_CAPS"});b(r&&r.getTriangleCount()>0,"Expected tangent-cap chamfer regression to produce geometry.");const a=r.__chamferDirectionDecision||{};b(Number(a.tangentCapBridges)>=1,`Expected native chamfer workflow to add at least one tangent cap bridge; received ${a.tangentCapBridges}.`);const s=(Array.isArray(r.__debugChamferSolids)?r.__debugChamferSolids:[]).filter(i=>String(i?.name||"").includes("TANGENT_CAP_BRIDGE"));b(s.length>=1,"Expected tangent-cap regression to emit a debug bridge solid."),b(s.every(i=>typeof i?.getTriangleCount=="function"&&i.getTriangleCount()>0),"Expected each tangent cap bridge debug solid to contain triangles."),b(s.some(i=>{const c=new Set(typeof i?.getFaceNames=="function"?i.getFaceNames():[]);return Array.from(c).some(d=>String(d||"").includes("_SOURCE_CAP"))&&Array.from(c).some(d=>String(d||"").includes("_TARGET_CAP"))}),"Expected tangent cap bridge debug geometry to expose source/target cap faces from the extension prism.")}l(Ui,"test_cppChamfer_bridges_nearly_tangent_adjacent_end_caps");async function zi(e=new Y){if(typeof L?.buildChamferWorkflowAuthoringState!="function"||typeof L?.buildChamferAuthoringState!="function")return;const{solid:t}=await zt(e),n=On(t,[Nr])[0];b(n,"Expected end-cap plane regression fixture to expose the target chamfer edge.");for(const r of[.101,-.101]){const a=Rr(t,n,{distance:.5,inflate:r,direction:"INSET",name:`CPP_CHAMFER_CAP_PLANE_${r>0?"POS":"NEG"}`,debugCrossSections:!0}),o=Array.isArray(a?.debugCrossSectionSnapshots)?a.debugCrossSectionSnapshots:[],s=o[o.length-1];b(s,"Expected chamfer debug snapshot to expose the terminal cross section.");const i=Gi(s,n);b(Number.isFinite(i)&&i<=1e-4,`Expected terminal chamfer cross section to stay on the endpoint tangent plane after inflate=${r}; max deviation=${i}.`)}}l(zi,"test_cppChamfer_projects_open_end_caps_back_to_endpoint_plane");async function Hi(e=new Y){if(typeof L?.buildChamferWorkflowAuthoringState!="function")return;const{solid:t}=await zt(e),n=On(t,[Nr])[0];b(n,"Expected cross-section debug fixture to expose the target chamfer edge.");const r=Array.isArray(n?.userData?.polylineLocal)?n.userData.polylineLocal.length:0;b(r>=2,"Expected cross-section debug fixture edge to expose sampled polyline points.");const a=await t.chamfer({distance:.5,edges:[n],direction:"AUTO",inflate:.101,debug:!0,featureID:"CPP_CHAMFER_DEBUG_SECTIONS"}),s=(Array.isArray(a.__debugChamferSolids)?a.__debugChamferSolids:[]).filter(g=>/_SECTION_\d+$/.test(String(g?.name||"")));b(s.length>=Math.max(2,r-1),`Expected debug cross-section faces for nearly every edge sample; expected about ${r}, received ${s.length}.`),b(s.every(g=>Array.isArray(g?._triVerts)&&g._triVerts.length===3),"Expected every chamfer cross-section debug solid to contain exactly one triangle."),b(s.every(g=>{const v=typeof g?.getFaceNames=="function"?g.getFaceNames():[];return Array.isArray(v)&&v.length===1&&/_SECTION_\d+$/.test(String(v[0]||""))}),"Expected each chamfer cross-section debug solid to expose a single named section face.");const i=s[0];b(i,"Expected at least one chamfer cross-section debug solid.");const c=[];for(const g of i._triVerts||[]){const v=Number(g);c.push([Number(i._vertProperties[v*3+0]),Number(i._vertProperties[v*3+1]),Number(i._vertProperties[v*3+2])])}for(const g of i._auxEdges||[])for(const v of g?.points||[]){const F=c.some(N=>Math.abs(Number(v[0])-N[0])<=1e-12&&Math.abs(Number(v[1])-N[1])<=1e-12&&Math.abs(Number(v[2])-N[2])<=1e-12);b(F,"Expected every cross-section edge endpoint to use the exact stored triangle vertex.")}i.visualize({showEdges:!0,authoringOnly:!0});const d=(i.children||[]).filter(g=>g?.type==="FACE"),u=(i.children||[]).filter(g=>g?.type==="EDGE"),f=(i.children||[]).filter(g=>g?.type==="VERTEX");b(d.length===1,`Expected the first cross-section to visualize one face, received ${d.length}.`),b(u.length===3,`Expected the first cross-section to visualize three edges, received ${u.length}.`),b(f.length===3,`Expected the first cross-section to visualize three vertices, received ${f.length}.`);const p=d[0];b(p,"Expected the first cross-section visualization to expose its section face.");const _=String(p.name||""),h=typeof i.getFaceMetadata=="function"?i.getFaceMetadata(_)||{}:{};b(h?.debugSketchFace===!0,"Expected the cross-section face to carry sketch-face metadata."),b(u.every(g=>g?.faces?.length===1&&String(g.faces[0]?.name||"")===_),"Expected each chamfer cross-section edge to be attached to the single section face.");const x=u.map(g=>String(g?.name||""));b(x.some(g=>/_EDGE_A_B$/.test(g)),"Expected the cross-section to include edge A-B."),b(x.some(g=>/_EDGE_B_C$/.test(g)),"Expected the cross-section to include edge B-C."),b(x.some(g=>/_EDGE_C_A$/.test(g)),"Expected the cross-section to include edge C-A."),b(u.every(g=>g?.userData?.auxEdge!==!0),"Expected cross-section edges to behave like normal boundary edges, not aux helpers."),b(u.every(g=>g?.material?.dashed===!1),"Expected cross-section edges to render as full triangle sides, not dashed helper segments.");const E=Array.isArray(p?.userData?.boundaryLoopsWorld)?p.userData.boundaryLoopsWorld:[];b(E.length===1,`Expected one boundary loop on the cross-section face, received ${E.length}.`),b(Array.isArray(E[0]?.pts)&&E[0].pts.length===3,"Expected the cross-section boundary loop to contain exactly the triangle vertices.");try{i.updateMatrixWorld(!0),p.updateMatrixWorld(!0)}catch{}const m=new ms;m.inputParams={featureID:"CPP_CHAMFER_SECTION_EXTRUDE",profile:p,distance:.5,distanceBack:0,boolean:{targets:[],operation:"NONE"}};const y=await m.run(e),w=Array.isArray(y?.added)?y.added[0]:null;b(w&&typeof w.getTriangleCount=="function"&&w.getTriangleCount()>0,"Expected a chamfer cross-section face to extrude directly like a sketch face.")}l(Hi,"test_cppChamfer_debug_emits_cross_section_face_per_sample");async function Yi(e=new Y){if(typeof L?.buildChamferWorkflowAuthoringState!="function")return;const{solid:t}=await zt(e),n=On(t,[Nr])[0];b(n,"Expected sketch-profile debug fixture to expose the target chamfer edge.");const r=new gs;r.inputParams={featureID:"CPP_CHAMFER_DEBUG_PROFILE",edges:[n],distance:.5,inflate:.101,direction:"AUTO",debug:!0};const a=await r.run(e),s=(Array.isArray(a?.added)?a.added:[]).find(d=>d?.type==="SKETCH"&&/_SECTION_\d+$/.test(String(d?.name||"")));b(s,"Expected chamfer debug cross sections to be added to the scene as sketch-style groups.");const i=(s.children||[]).find(d=>d?.type==="FACE"&&/:PROFILE$/.test(String(d?.name||"")));b(i,"Expected the sketch-style chamfer section to expose a :PROFILE face child."),b(Array.isArray(i?.edges)&&i.edges.length===3,`Expected the chamfer debug sketch profile to expose three boundary edges, received ${i?.edges?.length||0}.`),b(i.edges.every(d=>d?.userData?.auxEdge!==!0),"Expected chamfer debug sketch profile edges to behave like normal sketch boundaries.");const c=s?.userData?.sketchBasis;b(Array.isArray(c?.origin)&&Array.isArray(c?.x)&&Array.isArray(c?.y),"Expected chamfer debug sketch sections to expose a sketch basis.")}l(Yi,"test_cppChamfer_debug_sections_materialize_as_sketch_profiles");function Ht(e,t){const n=e[0]-t[0],r=e[1]-t[1],a=e[2]-t[2];return n*n+r*r+a*a}l(Ht,"pointDistanceSq");function qe(e,t,n=1e-12){if(Ht(e,t)>n*n)throw new Error(`Expected point ${JSON.stringify(e)} near ${JSON.stringify(t)} (eps=${n})`)}l(qe,"assertPointNear");async function Xi(){const e=[[0,0,0],[1,.35,0],[2,-.5,0],[3,.45,0],[4,0,0]],t=na(e,{fitStrength:1});if(!Array.isArray(t)||t.length!==e.length)throw new Error("Curve fit should return one output point per input point.");if(qe(t[0],e[0],1e-12),qe(t[t.length-1],e[e.length-1],1e-12),Er(e,t))throw new Error("Fitted polyline should not locally reverse direction against the source edge.");let n=0;for(let a=1;a<e.length-1;a++)Ht(e[a],t[a])>1e-12&&n++;if(n<=0)throw new Error("At least one interior point should be snapped to the fitted curve.");const r=na(e,{fitStrength:0});for(let a=0;a<e.length;a++)qe(r[a],e[a],1e-12)}l(Xi,"test_edge_smooth_curve_fit");function vo(e,t){const n=Array.isArray(e)?e:[],r=Array.isArray(t)?t:[],a=n.length;if(a!==r.length||a<3)return!0;for(let o=0;o<a;o++){const s=(o+1)%a,i=n[o],c=n[s],d=r[o],u=r[s],f=[c[0]-i[0],c[1]-i[1],c[2]-i[2]],p=[u[0]-d[0],u[1]-d[1],u[2]-d[2]],_=Math.hypot(f[0],f[1],f[2]),h=Math.hypot(p[0],p[1],p[2]);if(!(_>1e-12)||!(h>1e-12))continue;if((f[0]*p[0]+f[1]*p[1]+f[2]*p[2])/(_*h)<-1e-6)return!0}return!1}l(vo,"hasLocalBacktrackingAgainstSourceClosed");async function Ki(){const e=[[1,0,0],[.45,.95,.02],[-.55,.8,-.03],[-1,0,0],[-.45,-.85,.03],[.55,-.75,-.02]],t=ra(e,{fitStrength:1});if(!Array.isArray(t)||t.length!==e.length)throw new Error("Closed-loop curve fit should return one output point per input point.");if(vo(e,t))throw new Error("Closed-loop fitted polyline should not locally reverse direction.");let n=0;for(let a=0;a<e.length;a++)Ht(e[a],t[a])>1e-12&&n++;if(n<=0)throw new Error("Closed-loop fit should move at least one loop point.");const r=ra(e,{fitStrength:0});for(let a=0;a<e.length;a++)qe(r[a],e[a],1e-12)}l(Ki,"test_edge_smooth_curve_fit_closed_loop");async function Ji(){const e=[0,0,0,1,0,0,1,1,0,0,1,0],t=[0,1,2,0,2,3],n=new Map;n.set(1,{x:.2,y:.8,z:0,count:1});const r=xs(e,t,n,{minArea2Ratio:.04,minNormalDot:.1,minArea2Abs:1e-24});if((Number(r?.movedVertices)||0)!==1)throw new Error("Constrained edge smoothing should move the target vertex.");if((Number(r?.constrainedVertices)||0)<=0)throw new Error("Constrained edge smoothing should scale back fold-causing targets.");const a=e[3],o=e[4];if(!Number.isFinite(a)||!Number.isFinite(o))throw new Error("Constrained edge smoothing produced invalid coordinates.");if(Math.abs(a-.2)<1e-9&&Math.abs(o-.8)<1e-9)throw new Error("Constrained smoothing should not apply a fold-causing target at full displacement.");const s=l((i,c,d)=>{const u=i*3,f=c*3,p=d*3,_=e[f+0]-e[u+0],h=e[f+1]-e[u+1],x=e[p+0]-e[u+0],E=e[p+1]-e[u+1];return _*E-h*x},"triNormalZ");if(!(s(0,1,2)>0))throw new Error("Primary triangle normal flipped after constrained smoothing.");if(!(s(0,2,3)>0))throw new Error("Adjacent triangle normal flipped after constrained smoothing.")}l(Ji,"test_edge_smooth_constraints_prevent_triangle_foldback");function Ir(e,t={}){const n=!!t.closedLoop,r=Array.isArray(e)?e.map(s=>[s[0],s[1],s[2]]):[],a=[];for(const s of r)a.push(s[0],s[1],s[2]);const o=l((s,i)=>{const c=s.slice(),d=i.map(_=>[_[0],_[1],_[2]]),u={type:"EDGE",name:"MOCK_EDGE_0",userData:{faceA:"FACE_A",faceB:"FACE_B",polylineLocal:d.map(_=>[_[0],_[1],_[2]]),closedLoop:n},closedLoop:n,parent:null,parentSolid:null},f={type:"SOLID",name:"MOCK_SOLID",_vertProperties:c,_triVerts:[0,1,2,0,2,3,0,3,4],_triIDs:[0,0,0],_vertKeyToIndex:new Map,_dirty:!1,_faceIndex:null,_manifold:null,traverse(_){typeof _=="function"&&_(u)},visualize(){},_manifoldize(){},getBoundaryEdgePolylines(){return[{name:u.name,faceA:u.userData.faceA,faceB:u.userData.faceB,indices:d.map((_,h)=>h),positions:d.map(_=>[_[0],_[1],_[2]]),closedLoop:n}]},clone(){return o(c,d)}},p={type:"FACE",name:"MOCK_FACE_0",edges:[u],parent:f,parentSolid:f,userData:{faceName:"MOCK_FACE_0"}};return u.parent=f,u.parentSolid=f,f.__testFace=p,f},"createSolid");return o(a,r)}l(Ir,"makeMockSolidFromPolyline");async function Zi(){const e=[[1,0,0],[.45,.95,.02],[-.55,.8,-.03],[-1,0,0],[-.45,-.85,.03],[.55,-.75,-.02]],t=Ir(e,{closedLoop:!0}),n=new yr;n.inputParams={edges:[t],fitStrength:1,id:"EDGE_SMOOTH_CLOSED_LOOP_TEST"};const r=await n.run();if(!r||!Array.isArray(r.added)||r.added.length!==1)throw new Error("EdgeSmoothFeature should add one smoothed solid when selecting a closed-loop edge set.");if(!Array.isArray(r.removed)||r.removed.length!==1||r.removed[0]!==t)throw new Error("Closed-loop smoothing should replace exactly the selected source solid.");const a=r.added[0],o=Array.isArray(a?._vertProperties)?a._vertProperties:[];if(o.length<e.length*3)throw new Error("Closed-loop smoothing output is missing expected vertex properties.");const s=[];for(let c=0;c<e.length;c++){const d=c*3;s.push([o[d+0],o[d+1],o[d+2]])}if(vo(e,s))throw new Error("Closed-loop feature smoothing should not create local edge backtracking.");let i=0;for(let c=0;c<e.length;c++)Ht(e[c],s[c])>1e-12&&i++;if(i<=0)throw new Error("Closed-loop feature smoothing should move at least one edge point.");if(!n.persistentData||n.persistentData.totalFittedEdges<1)throw new Error("Feature metadata should record the closed-loop edge as fitted.")}l(Zi,"test_edge_smooth_closed_loop_feature_selection");async function qi(){const e=[[0,0,0],[1,.4,0],[2,-.45,0],[3,.35,0],[4,0,0]],t=Ir(e),n=new yr;n.inputParams={edges:[t],fitStrength:1,id:"EDGE_SMOOTH_SOLID_TEST"};const r=await n.run();if(!r||!Array.isArray(r.added)||r.added.length!==1)throw new Error("EdgeSmoothFeature should add one smoothed solid when selecting a whole solid.");if(!Array.isArray(r.removed)||r.removed.length!==1||r.removed[0]!==t)throw new Error("EdgeSmoothFeature should remove exactly the selected source solid.");const a=r.added[0],o=Array.isArray(a?._vertProperties)?a._vertProperties:[];if(o.length<15)throw new Error("Smoothed solid is missing expected vertex properties.");const s=[];for(let c=0;c<5;c++){const d=c*3;s.push([o[d+0],o[d+1],o[d+2]])}if(qe(s[0],e[0],1e-12),qe(s[s.length-1],e[e.length-1],1e-12),Er(e,s))throw new Error("Whole-solid smoothing should not create local edge backtracking.");let i=0;for(let c=1;c<e.length-1;c++)Ht(e[c],s[c])>1e-12&&i++;if(i<=0)throw new Error("Whole-solid smoothing should move at least one interior edge point.");if(!n.persistentData||n.persistentData.selectedSolidCount<1)throw new Error("Feature metadata should record at least one selected solid.")}l(qi,"test_edge_smooth_whole_solid_selection");async function Qi(){const e=[[0,0,0],[1,.3,0],[2,-.35,0],[3,.25,0],[4,0,0]],t=Ir(e),n=t.__testFace;if(!n||n.type!=="FACE")throw new Error("Mock setup should provide a face selection target.");const r=new yr;r.inputParams={edges:[n],fitStrength:1,id:"EDGE_SMOOTH_FACE_TEST"};const a=await r.run();if(!a||!Array.isArray(a.added)||a.added.length!==1)throw new Error("EdgeSmoothFeature should add one smoothed solid when selecting a face.");if(!Array.isArray(a.removed)||a.removed.length!==1||a.removed[0]!==t)throw new Error("EdgeSmoothFeature should remove exactly the source solid for face selection.");const o=a.added[0],s=Array.isArray(o?._vertProperties)?o._vertProperties:[];if(s.length<15)throw new Error("Face-selected smoothing output is missing expected vertex properties.");const i=[];for(let c=0;c<5;c++){const d=c*3;i.push([s[d+0],s[d+1],s[d+2]])}if(qe(i[0],e[0],1e-12),qe(i[i.length-1],e[e.length-1],1e-12),Er(e,i))throw new Error("Face-selected smoothing should not create local edge backtracking.");if(!r.persistentData||r.persistentData.selectedFaceCount<1)throw new Error("Feature metadata should record at least one selected face.")}l(Qi,"test_edge_smooth_face_selection");const sr=-4,ir=15.7,qt=1e-4,el=l(()=>({points:[{id:0,x:-2,y:-2,fixed:!0},{id:1,x:2,y:-2,fixed:!1},{id:2,x:2,y:2,fixed:!1},{id:3,x:-2,y:2,fixed:!1}],geometries:[{id:100,type:"line",points:[0,1],construction:!1},{id:101,type:"line",points:[1,2],construction:!1},{id:102,type:"line",points:[2,3],construction:!1},{id:103,type:"line",points:[3,0],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]}),"makeRectSketch$3");function tl(e){const n=e?.geometry?.getAttribute?.("position");if(!n)return[];const r=[],a=new $;for(let o=0;o<n.count;o++)a.set(n.getX(o),n.getY(o),n.getZ(o)).applyMatrix4(e.matrixWorld),r.push([a.x,a.y,a.z]);return r}l(tl,"collectWorldVerticesFromFaceObject");function ma(e){const t=[];for(const n of Array.isArray(e)?e:[])Array.isArray(n?.p1)&&t.push(n.p1),Array.isArray(n?.p2)&&t.push(n.p2),Array.isArray(n?.p3)&&t.push(n.p3);return t}l(ma,"collectTriangleVertices");function ga(e,t,n){let r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY,o=0,s=0;for(const i of e){const d=i[0]*t.x+i[1]*t.y+i[2]*t.z-n;d<r&&(r=d),d>a&&(a=d),o+=d,s+=1}return{mean:s?o/s:0,spread:s?a-r:0,count:s}}l(ga,"analyzeProjectedOffsets");async function nl(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch=el();const r=await e.newFeature("E");return r.inputParams.profile=n.inputParams.featureID,r.inputParams.consumeProfileSketch=!1,r.inputParams.distance=sr,r.inputParams.distanceBack=ir,e}l(nl,"test_extrude_negative_distance_cap_alignment");async function rl(e){const t=e.features.find(h=>h?.type==="E"),n=e.features.find(h=>h?.type==="S");if(!t?.inputParams?.featureID)throw new Error("[extrude-negative] missing extrude feature id");if(!n?.inputParams?.featureID)throw new Error("[extrude-negative] missing sketch feature id");const r=e.scene.getObjectByName(t.inputParams.featureID);if(!r||typeof r.getFaces!="function")throw new Error("[extrude-negative] extrude solid missing from scene");const a=e.scene.getObjectByName(n.inputParams.featureID),o=a?.children?.find?.(h=>h?.type==="FACE")||a?.children?.find?.(h=>h?.userData?.faceName);if(!o||typeof o.getAverageNormal!="function")throw new Error("[extrude-negative] profile face missing from sketch");const s=o.getAverageNormal().clone();if(s.lengthSq()<1e-20)throw new Error("[extrude-negative] profile normal is degenerate");s.normalize();const i=tl(o);if(!i.length)throw new Error("[extrude-negative] profile face has no vertices");const c=i.reduce((h,x)=>h+x[0]*s.x+x[1]*s.y+x[2]*s.z,0)/i.length,d=r.getFaces(!1),u=d.find(h=>String(h?.faceName||"").endsWith("_START")),f=d.find(h=>String(h?.faceName||"").endsWith("_END"));if(!u||!f){const h=d.map(x=>String(x?.faceName||""));throw new Error(`[extrude-negative] missing start/end caps. Faces: ${h.join(", ")}`)}const p=ga(ma(u.triangles),s,c),_=ga(ma(f.triangles),s,c);if(p.count===0||_.count===0)throw new Error("[extrude-negative] cap triangles are empty");if(p.spread>qt)throw new Error(`[extrude-negative] start cap not planar on expected axis (spread=${p.spread})`);if(_.spread>qt)throw new Error(`[extrude-negative] end cap not planar on expected axis (spread=${_.spread})`);if(Math.abs(p.mean- -ir)>qt)throw new Error(`[extrude-negative] start cap offset mismatch: got ${p.mean}, expected ${-ir}`);if(Math.abs(_.mean-sr)>qt)throw new Error(`[extrude-negative] end cap offset mismatch: got ${_.mean}, expected ${sr}`)}l(rl,"afterRun_extrude_negative_distance_cap_alignment");const al="src/tests/partFiles/slowsketch.json";async function ol(e){const t=await j.promises.readFile(al,"utf8");return await e.reset(),await e.fromJSON(t),e.currentHistoryStepId="E4",e}l(ol,"test_extrude_intersect_coplanar_face_merge");async function sl(e){const t=e.getObjectByName("E2");if(!t||typeof t.getFaceNames!="function")throw new Error("Expected intersect result solid E2 to exist after E4.");const n=new Set(t.getFaceNames()||[]);if(!n.has("E2:S1:PROFILE_START"))throw new Error("Expected E2:S1:PROFILE_START to survive the intersect result.");if(n.has("E4:S3:G9_SW"))throw new Error("Expected coplanar sidewall E4:S3:G9_SW to merge into E2:S1:PROFILE_START.");const r=t.getFaceMetadata?.("E2:S1:PROFILE_START")||{};if(r.faceType!=="STARTCAP"||r.sourceFeatureId!=="E2")throw new Error("Expected merged host face metadata on E2:S1:PROFILE_START to be preserved.");const a=t.getFace?.("E2:S1:PROFILE_START")||[];if(a.length<=42)throw new Error(`Expected merged host face to gain triangles from the coplanar fragment, got ${a.length}.`);console.log(`✓ E4 intersect merged coplanar sidewall into PROFILE_START (${a.length} triangles)`)}l(sl,"afterRun_extrude_intersect_coplanar_face_merge");function Ft(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Ft,"assert$u");async function il(e){const t=await e.newFeature("P.CY"),n=String(t?.inputParams?.featureID||"");Ft(n,"Cylinder feature should have a featureID."),await e.runHistory();const r=e?.scene?.getObjectByName?.(n)||null;Ft(r,"Expected cylinder solid in the scene."),Ft(typeof r.getFaceMetadata=="function","Expected solid face metadata API.");const a=r.getFaceMetadata(`${n}_S`),o=r.getFaceMetadata(`${n}_T`);Ft(a?.sourceFeatureId===n,"Cylinder side face should be seeded with sourceFeatureId."),Ft(o?.sourceFeatureId===n,"Cylinder top face should be seeded with sourceFeatureId.")}l(il,"test_face_source_feature_seed");async function ll(e){const t=await e.newFeature("P.CO");t.inputParams.radiusTop=3,t.inputParams.radiusBottom=.5,t.inputParams.height=5.2,t.inputParams.resolution=20;const n=await e.newFeature("E");return n.inputParams.profile=`${t.inputParams.featureID}_T`,n.inputParams.distance=0,n.inputParams.distanceBack=5,n.inputParams.boolean={targets:[t.inputParams.featureID],operation:"UNION"},e}l(ll,"test_ExtrudeFace");function Hn(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Hn,"assert$t");async function cl(e){const t=await e.newFeature("P.CU");t.inputParams.id="FACE_EDGE_SRC",t.inputParams.sizeX=12,t.inputParams.sizeY=8,t.inputParams.sizeZ=10;const n=await e.newFeature("E");return n.inputParams.id="FACE_EDGE_EXTRUDE",n.inputParams.profile="FACE_EDGE_SRC_PY",n.inputParams.consumeProfileSketch=!0,n.inputParams.distance=4,n.inputParams.distanceBack=0,n.inputParams.boolean={targets:[],operation:"NONE"},e}l(cl,"test_extrude_solid_face_uses_boundary_edge_sidewalls");async function dl(e){const t=(e?.scene?.children||[]).find(a=>a?.type==="SOLID"&&a.name==="FACE_EDGE_EXTRUDE");Hn(t&&typeof t.getFaceNames=="function","[extrude-face-sidewalls] Expected extrude result solid.");const n=t.getFaceNames().map(a=>String(a||"")),r=n.filter(a=>a.startsWith("FACE_EDGE_EXTRUDE:")&&a.endsWith("_SW"));Hn(r.length===4,`[extrude-face-sidewalls] Expected 4 boundary-edge sidewalls, found ${r.length}: ${r.join(", ")}`),Hn(!n.includes("FACE_EDGE_EXTRUDE:FACE_EDGE_SRC_PY_SW"),"[extrude-face-sidewalls] Solid face extrusion should not collapse all boundary edges into the default sidewall.")}l(dl,"afterRun_extrude_solid_face_uses_boundary_edge_sidewalls");function R(e,t){if(!e)throw new Error(t)}l(R,"assert$s");function gt(e){if(!e||typeof e!="object")return[];if(typeof e.getFaceNames=="function")try{return e.getFaceNames()}catch{}return e._faceNameToID instanceof Map?Array.from(e._faceNameToID.keys()):[]}l(gt,"getSolidFaceNames$1");function ul(e,t){if(!e||typeof e!="object")return null;if(e._faceNameToID instanceof Map&&e._faceNameToID.has(t))return e._faceNameToID.get(t);if(e._idToFaceName instanceof Map){for(const[n,r]of e._idToFaceName.entries())if(r===t)return n}return null}l(ul,"getTrackedFaceId");function Dn(e,t,n){const r=t.map(s=>ul(e,s)),a=t.filter((s,i)=>r[i]==null);R(a.length===0,`${n} Missing face tracking IDs for: ${a.join(", ")}`);const o=new Set(r.map(s=>String(s)));R(o.size===t.length,`${n} Expected distinct face IDs for ${t.join(", ")}, got ${r.join(", ")}`)}l(Dn,"assertDistinctTrackedFaces");function fl(){return{points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:2,y:2,fixed:!1,construction:!1,externalReference:!1},{id:2,x:8,y:2,fixed:!1,construction:!1,externalReference:!1},{id:3,x:8,y:2,fixed:!1,construction:!1,externalReference:!1},{id:4,x:8,y:8,fixed:!1,construction:!1,externalReference:!1},{id:5,x:8,y:8,fixed:!1,construction:!1,externalReference:!1},{id:6,x:2,y:8,fixed:!1,construction:!1,externalReference:!1},{id:7,x:2,y:8,fixed:!1,construction:!1,externalReference:!1},{id:8,x:2,y:2,fixed:!1,construction:!1,externalReference:!1}],geometries:[{id:1,type:"line",points:[1,2],construction:!1},{id:2,type:"line",points:[3,4],construction:!1},{id:3,type:"line",points:[5,6],construction:!1},{id:4,type:"line",points:[7,8],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]},{id:1,type:"≡",points:[2,3]},{id:2,type:"≡",points:[4,5]},{id:3,type:"≡",points:[6,7]},{id:4,type:"≡",points:[8,1]}]}}l(fl,"makeRectangleSketch");function pl(){return{points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:-10.143414,y:-11.050455,fixed:!1,construction:!1,externalReference:!1},{id:2,x:-10.143414,y:-11.050455,fixed:!1,construction:!1,externalReference:!1},{id:3,x:-5.723277,y:-15.107781,fixed:!1,construction:!1,externalReference:!1},{id:4,x:-5.723277,y:-15.107781,fixed:!1,construction:!1,externalReference:!1},{id:5,x:2.636873,y:-6.000049,fixed:!1,construction:!1,externalReference:!1},{id:6,x:2.636873,y:-6.000049,fixed:!1,construction:!1,externalReference:!1},{id:7,x:12.999972,y:-6.000047,fixed:!1,construction:!1,externalReference:!1},{id:8,x:12.999972,y:-6.000047,fixed:!1,construction:!1,externalReference:!1},{id:9,x:12.999973,y:0,fixed:!1,construction:!1,externalReference:!1},{id:10,x:12.999973,y:0,fixed:!1,construction:!1,externalReference:!1},{id:11,x:0,y:0,fixed:!0,construction:!1,externalReference:!1}],geometries:[{id:1,type:"line",points:[0,1],construction:!1},{id:2,type:"line",points:[2,3],construction:!1},{id:3,type:"line",points:[4,5],construction:!1},{id:4,type:"line",points:[6,7],construction:!1},{id:5,type:"line",points:[8,9],construction:!1},{id:6,type:"line",points:[10,11],construction:!1}],constraints:[{id:0,type:"⏚",points:[0],status:"solved",error:null},{id:1,type:"≡",points:[1,2],status:"solved",error:null},{id:2,type:"≡",points:[3,4],status:"solved",error:null},{id:3,type:"≡",points:[5,6],status:"solved",error:null},{id:4,type:"≡",points:[7,8],status:"solved",error:null},{id:5,type:"≡",points:[9,10],status:"solved",error:null},{id:6,type:"≡",points:[0,11],status:"solved",error:null}]}}l(pl,"makeSixEdgeGeneratedSketch20260609165436");function bo(){return{points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:-7.158141,y:-7.907776,fixed:!1,construction:!1,externalReference:!1},{id:2,x:8.426984,y:5.71041,fixed:!1,construction:!1,externalReference:!1},{id:3,x:-7.158141,y:-7.907776,fixed:!1,construction:!1,externalReference:!1},{id:4,x:7.560362,y:-8.787576,fixed:!1,construction:!1,externalReference:!1},{id:5,x:7.560362,y:-8.787576,fixed:!1,construction:!1,externalReference:!1},{id:6,x:8.426984,y:5.71041,fixed:!1,construction:!1,externalReference:!1},{id:7,x:-6.291516,y:6.590214,fixed:!1,construction:!1,externalReference:!1},{id:8,x:-6.291516,y:6.590214,fixed:!1,construction:!1,externalReference:!1},{id:9,x:-1.237185,y:.019114,fixed:!1,construction:!1,externalReference:!1},{id:10,x:-2.794092,y:-2.205038,fixed:!1,construction:!1,externalReference:!1},{id:11,x:7.560362,y:-8.787576,fixed:!1,construction:!1,externalReference:!1},{id:12,x:7.484115,y:-11.495576,fixed:!1,construction:!1,externalReference:!1},{id:13,x:-7.437728,y:-13.144076,fixed:!1,construction:!1,externalReference:!1},{id:14,x:-2.88781,y:-12.825321,fixed:!1,construction:!1,externalReference:!1},{id:15,x:-4.301049,y:-12.388265,fixed:!1,construction:!1,externalReference:!1},{id:16,x:-5.585603,y:-11.991006,fixed:!1,construction:!1,externalReference:!1},{id:17,x:2.463262,y:-12.023261,fixed:!1,construction:!1,externalReference:!1},{id:18,x:.123113,y:-13.639996,fixed:!1,construction:!1,externalReference:!1},{id:19,x:-1.794938,y:-14.965129,fixed:!1,construction:!1,externalReference:!1},{id:20,x:5.529604,y:-10.376861,fixed:!1,construction:!1,externalReference:!1},{id:21,x:3.628537,y:-11.397603,fixed:!1,construction:!1,externalReference:!1},{id:22,x:2.463262,y:-12.023261,fixed:!1,construction:!1,externalReference:!1}],geometries:[{id:1,type:"line",points:[1,4],construction:!0},{id:2,type:"line",points:[5,2],construction:!1},{id:3,type:"line",points:[6,7],construction:!1},{id:4,type:"line",points:[8,3],construction:!1},{id:5,type:"circle",points:[9,10],construction:!1},{id:6,type:"bezier",points:[11,12,20,21,22,17,18,19,14,15,16,13,1],construction:!1},{id:7,type:"line",points:[11,12],construction:!0},{id:8,type:"line",points:[1,13],construction:!0},{id:9,type:"line",points:[15,14],construction:!0},{id:10,type:"line",points:[15,16],construction:!0},{id:11,type:"line",points:[18,17],construction:!0},{id:12,type:"line",points:[18,19],construction:!0},{id:13,type:"line",points:[21,20],construction:!0},{id:14,type:"line",points:[21,22],construction:!0}],constraints:[]}}l(bo,"makeGeneratedHistoryBaseSketch");function Fo(){return{points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:-3.800787,y:-3.701602,fixed:!1,construction:!1,externalReference:!1},{id:2,x:3.150132,y:3.59845,fixed:!1,construction:!1,externalReference:!1},{id:3,x:-3.800787,y:-3.701602,fixed:!1,construction:!1,externalReference:!1},{id:4,x:3.150132,y:-3.701602,fixed:!1,construction:!1,externalReference:!1},{id:5,x:3.150132,y:-3.701602,fixed:!1,construction:!1,externalReference:!1},{id:6,x:3.150132,y:3.59845,fixed:!1,construction:!1,externalReference:!1},{id:7,x:-3.800787,y:3.59845,fixed:!1,construction:!1,externalReference:!1},{id:8,x:-3.800787,y:3.59845,fixed:!1,construction:!1,externalReference:!1}],geometries:[{id:1,type:"line",points:[1,4],construction:!1},{id:2,type:"line",points:[5,2],construction:!1},{id:3,type:"line",points:[6,7],construction:!1},{id:4,type:"line",points:[8,3],construction:!1}],constraints:[]}}l(Fo,"makeGeneratedHistoryS22Sketch");function Or(e="E2",t="S1"){return[`${e}:${t}:PROFILE_START`,`${e}:${t}:PROFILE_END`,`${e}:${t}:G1_SW`,`${e}:${t}:G2_SW`,`${e}:${t}:G3_SW`,`${e}:${t}:G4_SW`]}l(Or,"expectedExtrudeFaceNames");async function Dr(e,t="S1"){const n=await e.newFeature("S");return Object.assign(n.inputParams,{id:t,sketchPlane:null,curveResolution:32}),n.persistentData={sketch:fl()},n}l(Dr,"addRectangleSketch");async function _l(e){await Dr(e,"S1");const t=await e.newFeature("E");Object.assign(t.inputParams,{id:"E2",profile:"S1:PROFILE",consumeProfileSketch:!0,distance:10,distanceBack:1,boolean:{targets:[],operation:"NONE"}}),await e.runHistory({throwOnFeatureError:!0});const n=e.getObjectByName("E2");R(n,"[extrude sidewalls] Expected extrude output E2.");const r=gt(n),a=Or("E2","S1");for(const o of a)R(r.includes(o),`[extrude sidewalls] Missing face ${o}. Faces: ${r.join(", ")}`);return R(r.length===a.length,`[extrude sidewalls] Expected exactly 6 faces, received ${r.length}: ${r.join(", ")}`),Dn(n,a,"[extrude sidewalls]"),console.log("✓ Rectangle extrude keeps one side wall face per sketch edge"),e}l(_l,"test_extrude_rectangle_profile_has_one_sidewall_per_sketch_edge");async function hl(e){e.expressions=`//Examples:
@@ -1937,7 +1937,7 @@ facet normal 0.0 0.0 1.0
1937
1937
  endloop
1938
1938
  endfacet
1939
1939
  endsolid Test_Cube
1940
- `;function P(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(P,"assert$g");async function np(){const e={type:"SOLID",owningFeatureID:"BODY_OWNER",getFaceMetadata(u){return u==="FACE_FROM_META"?{sourceFeatureId:"FACE_OWNER"}:null},getEdgeMetadata(u){return u==="EDGE_FROM_META"?{sourceFeatureId:"EDGE_OWNER"}:null}},t={type:"FACE",name:"FACE_FROM_META",parentSolid:e,parent:e},n={type:"EDGE",name:"EDGE_FROM_META",parentSolid:e,parent:e},r={type:"FACE",name:"FACE_FALLBACK",parentSolid:e,parent:e},a={type:"EDGE",userData:{splineFeatureId:"SP_001"}},o={type:"LINE2",userData:{},parent:a},i={type:"EDGE",name:"SK_001:G5",userData:{},parent:{type:"SKETCH",name:"SK_001",userData:{sketchFeatureId:"SK_001"}}},d={type:"FACE",name:"OF_001:FACE_A:PROFILE",userData:{},parent:{type:"SKETCH",name:"OF_001:FACE_A",userData:{sketchFeatureId:"OF_001"}}};P(Wn(t)==="FACE_OWNER","Face metadata owner should win."),P(Wn(n)==="EDGE_OWNER","Edge metadata owner should use precise edge metadata."),P(Wn(r)==null,"Faces without precise provenance should not fall back to solid owner."),P(Kr(a)==="SP_001","Spline owner should resolve from spline metadata."),P(Kr(o)==="SP_001","Spline owner should resolve through parent geometry."),P(Jr(i)==="SK_001","Sketch owner should resolve through sketch group metadata."),P(Jr(d)==="OF_001","Sketch-like owner should resolve from group metadata."),P(qo([{object:t}])==="FACE_OWNER","Single-selection resolution should unwrap selection objects."),P(Qo([{object:o}])==="SP_001","Spline selection resolution should unwrap selection objects."),P(es([{object:i}])==="SK_001","Sketch-like selection resolution should unwrap selection objects."),P(jn([{object:t}],["FACE"])===!0,"Single face selection should match FACE."),P(Zr([{object:a}])===!0,"Single spline selection should match spline helper."),P(ts([{object:d}])===!0,"Single sketch-like selection should match sketch-like helper."),P(jn([{object:n}],["FACE","PLANE"])===!1,"Edge selection should not match the face-only toolbar filter."),P(Zr([{object:a},{object:n}])===!1,"Multiple selections should not match spline helper."),P(jn([{object:t},{object:n}],["FACE","EDGE"])===!1,"Multiple selections should not match.")}l(np,"test_selection_owning_feature_resolution");async function rp(){const e=typeof globalThis.window<"u",t=globalThis.window;e||(globalThis.window={DEBUG_MODE:!1});let n;try{({selectionMethods:n}=await ai(()=>import("./main-cad-3Myw0wlX.js").then(i=>i.M),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12])))}finally{if(e)globalThis.window=t;else try{delete globalThis.window}catch{globalThis.window=void 0}}const r={linewidth:3},a={isLine2:!0,material:r},o={renderer:{domElement:{clientWidth:640,clientHeight:480,getBoundingClientRect:l(()=>({width:640,height:480}),"getBoundingClientRect")}},scene:{traverse(i){i(a)}}};o._syncLineMaterialResolutionForPicking=n._syncLineMaterialResolutionForPicking,n._syncLineMaterialResolutionForPicking.call(o),P(r.resolution,"Expected Line2 material to receive a resolution before raycasting."),P(r.resolution.width===640,`Expected repaired width 640, got ${r.resolution.width}`),P(r.resolution.height===480,`Expected repaired height 480, got ${r.resolution.height}`),delete r.resolution;let s=!1;n._withDoubleSidedPicking.call(o,()=>(s=!!r.resolution,[])),P(s,"Expected picking wrapper to repair Line2 material resolution before raycasting.")}l(rp,"test_selection_line2_resolution_repair");async function ap(){let e=null;const t={type:"FakeMaterial",color:{set(){}},clone(){return e={type:"FakeHoverMaterial",color:{set(){}},disposed:!1,dispose(){this.disposed=!0}},e}},n={type:"EDGE",name:"hover-restore-edge",material:t,userData:{}};ne.attach(n),n.hovered=!0,P(e,"Expected hover to create a temporary material."),P(n.material===e,"Expected hover material to be assigned while hovered."),ne._clearHover(n),P(n.material===t,"Expected base material to be restored before hover material disposal."),P(e.disposed===!0,"Expected temporary hover material to be disposed after restore.")}l(ap,"test_selection_hover_material_restores_before_dispose");async function op(){let e="#00009e",t=null;const n={type:"SharedFaceMaterial",isMaterial:!0,color:{set(o){e=o},getHex(){return e}},clone(){let o=e;return t={type:"HoverFaceMaterial",isMaterial:!0,color:{set(s){o=s},getHex(){return o}},disposed:!1,dispose(){this.disposed=!0},get currentColor(){return o}},t},get currentColor(){return e}},r={type:"FACE",name:"E2:S1:PROFILE_END_START",material:n,userData:{}},a={type:"FACE",name:"E2:S1:G2_SW_END",material:n,userData:{}};ne.attach(r),ne.attach(a),r.hovered=!0,P(t,"Expected solid face hover to create a temporary material."),P(r.material===t,"Expected profile-named solid face hover to assign only the temporary material."),P(a.material===n,"Expected sibling face to keep the shared base material."),P(n.currentColor==="#00009e",`Expected shared face material color to remain unchanged, got ${n.currentColor}.`),P(t.currentColor===ne.hoverColor,`Expected hover material color ${ne.hoverColor}, got ${t.currentColor}.`),r.hovered=!1,P(r.material===n,"Expected profile-named solid face hover clear to restore the base material."),P(t.disposed===!0,"Expected profile-named solid face hover material to be disposed.")}l(op,"test_selection_profile_named_solid_face_hover_does_not_tint_shared_face_material");async function sp(){const e=l((s,i)=>{let c=s;return{type:i,needsUpdate:!1,color:{set(u){c=u},getHex(){return c}},clone(){throw new Error("Sketch hover should not clone/replace materials.")},get currentColor(){return c}}},"makeSketchMaterial"),t=e("#009dff","FakeSketchLineMaterial"),n=e("#00009e","FakeSketchFaceMaterial"),a={type:"FACE",name:"S1:PROFILE",material:n,userData:{__baseMaterial:{type:"MeshStandardMaterial",color:158},__defaultMaterial:{type:"MeshStandardMaterial",color:158}},parent:{type:"SKETCH",userData:{sketchFeatureId:"S1"}}},o={type:"EDGE",name:"S1:G100",material:t,userData:{sketchFeatureId:"S1",sketchGeometryId:100,__baseMaterial:{type:"LineMaterial",color:40447},__defaultMaterial:{type:"LineMaterial",color:40447}}};ne.attach(o),P(o.userData.__baseMaterial===t,"Expected cloned plain edge base material to be replaced with the live material."),o.hovered=!0,P(o.material===t,"Expected sketch edge hover to keep the same material object."),P(t.currentColor===ne.hoverColor,`Expected edge hover color ${ne.hoverColor}, got ${t.currentColor}`),P(t.needsUpdate===!0,"Expected edge hover tint to mark material for update."),o.hovered=!1,P(o.material===t,"Expected sketch edge hover clear to keep the same material object."),P(t.currentColor==="#009dff",`Expected sketch edge hover clear to restore original color, got ${t.currentColor}`),ne.attach(a),P(a.userData.__baseMaterial===n,"Expected cloned plain face base material to be replaced with the live material."),a.hovered=!0,P(a.material===n,"Expected sketch face hover to keep the same material object."),P(n.currentColor===ne.hoverColor,`Expected face hover color ${ne.hoverColor}, got ${n.currentColor}`),a.hovered=!1,P(a.material===n,"Expected sketch face hover clear to keep the same material object."),P(n.currentColor==="#00009e",`Expected sketch face hover clear to restore original color, got ${n.currentColor}`)}l(sp,"test_selection_sketch_hover_tints_material_in_place");async function ip(){let e="#009dff";const t={needsUpdate:!1,color:{set(r){e=r},getHex(){return e}},clone(){throw new Error("SelectionFilter hover should tint sketch materials in place.")},get currentColor(){return e}},n={type:"EDGE",name:"S1:G101",uuid:"selection-filter-empty-hover-edge",material:t,userData:{sketchFeatureId:"S1",sketchGeometryId:101}};Zt.clearHover(),Zt.setHoverObjects([n],{ignoreFilter:!0}),P(n.hovered===!0,"Expected SelectionFilter to mark the sketch edge hovered."),P(t.currentColor===ne.hoverColor,`Expected sketch edge hover color ${ne.hoverColor}, got ${t.currentColor}`),Zt.setHoverObjects([],{ignoreFilter:!0}),P(n.hovered===!1,"Expected an empty hover update to clear the hovered flag."),P(t.currentColor==="#009dff",`Expected empty hover update to restore sketch material color, got ${t.currentColor}`),P(Zt._hovered.size===0,"Expected SelectionFilter hovered target set to be empty after clear.")}l(ip,"test_selection_filter_empty_hover_clears_in_place_sketch_hover");function Z(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Z,"assert$f");function lp(e,t){const n=[];for(const[o,s,i]of t)n.push(...o,...s,...i);const r=new Tn;r.setAttribute("position",new Wt(n,3)),r.computeBoundingBox(),r.computeBoundingSphere();const a=new Fr(r,new Pr);return a.type="FACE",a.name=e,a.userData={faceName:e},a}l(lp,"makeFaceMesh");function yn(e){const t=new Fe;t.type="SOLID",t.name="TEST_SOLID";for(const[n,r]of e)t.add(lp(n,r));return t.updateMatrixWorld(!0),t}l(yn,"buildSolidWithFaces");function Le(e,t,n,r,a=0){return[[[e,t,a],[n,t,a],[n,r,a]],[[e,t,a],[n,r,a],[e,r,a]]]}l(Le,"makeQuad");async function cp(){const e=yn([["FACE_A",Le(0,0,1,1,0)],["FACE_B",Le(.5,0,1.5,1,0)],["FACE_OFF_PLANE",Le(0,0,1,1,.01)]]),t=wr(e,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(t.faceCount===3,`Expected 3 planar faces, got ${t.faceCount}`),Z(t.overlaps.length===1,`Expected exactly one overlap pair, got ${t.overlaps.length}`),Z(t.overlaps[0].faceA==="FACE_A",`Expected FACE_A first, got ${t.overlaps[0].faceA}`),Z(t.overlaps[0].faceB==="FACE_B",`Expected FACE_B second, got ${t.overlaps[0].faceB}`),Z(Math.abs(t.overlaps[0].overlapArea-.5)<1e-6,`Expected overlap area close to 0.5, got ${t.overlaps[0].overlapArea}`),Z(t.highlightedFaceNames.includes("FACE_A")&&t.highlightedFaceNames.includes("FACE_B"),"Expected both overlapping faces to be highlighted."),Z(!t.highlightedFaceNames.includes("FACE_OFF_PLANE"),"Expected off-plane face to be ignored.")}l(cp,"test_solid_overlap_diagnostics_detects_coplanar_overlap");async function dp(){const e=yn([["FACE_A",Le(0,0,1,1,0)],["FACE_TOUCH_ONLY",Le(1,0,2,1,0)]]),t=wr(e,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(t.overlaps.length===0,`Expected no overlap pairs, got ${t.overlaps.length}`),Z(t.highlightedFaceNames.length===0,"Expected no highlighted faces for boundary-only contact.")}l(dp,"test_solid_overlap_diagnostics_ignores_boundary_touching_faces");async function up(){const e=yn([["A_FACE_1",Le(0,0,1,1,0)],["A_FACE_2",Le(2,0,3,1,0)]]);e.name="SOLID_A";const t=yn([["B_FACE_1",Le(.5,0,1.5,1,0)],["B_FACE_2",Le(5,0,6,1,0)]]);t.name="SOLID_B";const n=wr(e,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(n.overlaps.length===0,"Single-solid analysis should not report cross-solid pairs.");const r=Ps(e,t,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(r.overlaps.length===1,`Expected one cross-solid overlap pair, got ${r.overlaps.length}`),Z(r.overlaps[0].solidA==="SOLID_A",`Expected solidA label SOLID_A, got ${r.overlaps[0].solidA}`),Z(r.overlaps[0].solidB==="SOLID_B",`Expected solidB label SOLID_B, got ${r.overlaps[0].solidB}`),Z(r.overlaps[0].faceA==="A_FACE_1",`Expected A_FACE_1, got ${r.overlaps[0].faceA}`),Z(r.overlaps[0].faceB==="B_FACE_1",`Expected B_FACE_1, got ${r.overlaps[0].faceB}`),Z(Math.abs(r.overlaps[0].overlapArea-.5)<1e-6,`Expected cross-solid overlap area close to 0.5, got ${r.overlaps[0].overlapArea}`),Z(Array.isArray(r.highlightedBySolid[r.solidAKey]?.faceNames)&&r.highlightedBySolid[r.solidAKey].faceNames.includes("A_FACE_1"),"Expected SOLID_A highlight set to include A_FACE_1."),Z(Array.isArray(r.highlightedBySolid[r.solidBKey]?.faceNames)&&r.highlightedBySolid[r.solidBKey].faceNames.includes("B_FACE_1"),"Expected SOLID_B highlight set to include B_FACE_1.")}l(up,"test_solid_overlap_diagnostics_detects_cross_solid_overlap");function Vo(){return{points:[{id:10,x:-5,y:-5,fixed:!1},{id:11,x:5,y:-5,fixed:!1},{id:12,x:5,y:5,fixed:!1},{id:13,x:-5,y:5,fixed:!1},{id:20,x:-3,y:-3,fixed:!1},{id:21,x:3,y:-3,fixed:!1},{id:22,x:3,y:3,fixed:!1},{id:23,x:-3,y:3,fixed:!1}],geometries:[{id:200,type:"line",points:[10,11],construction:!1},{id:201,type:"line",points:[11,12],construction:!1},{id:202,type:"line",points:[12,13],construction:!1},{id:203,type:"line",points:[13,10],construction:!1},{id:210,type:"line",points:[20,21],construction:!1},{id:211,type:"line",points:[21,22],construction:!1},{id:212,type:"line",points:[22,23],construction:!1},{id:213,type:"line",points:[23,20],construction:!1}],constraints:[]}}l(Vo,"makeCenteredRingSketch");function hr(e,t){let n=0,r=0;const a=Array.isArray(e)?e:[];for(const o of a){const s=t==="x"?[-o[0],o[1],o[2]]:[o[0],-o[1],o[2]];let i=1/0;for(const c of a){const d=Math.hypot(c[0]-s[0],c[1]-s[1],c[2]-s[2]);d<i&&(i=d)}i>n&&(n=i),r+=i}return{max:n,mean:a.length?r/a.length:0}}l(hr,"nearestMirrorError");async function fp(e){const t=await e.newFeature("P.CY");t.inputParams.id="SMOOTH_SRC",t.inputParams.radius=5,t.inputParams.height=12,t.inputParams.resolution=16;const n=await e.newFeature("SWS");return n.inputParams.targetSolid=t.inputParams.featureID,n.inputParams.subdivisionLoops=1,e}l(fp,"test_smooth_with_subdivision_replaces_source_solid");async function pp(e){const t=(e.features||[]).find(d=>String(d?.type||"").toUpperCase()==="SWS");if(!t)throw new Error("[smooth with subdivision] Feature entry was not created.");const n=t.persistentData||{};if(!(Number(n.sourceTriangleCount)>0))throw new Error("[smooth with subdivision] Source triangle count was not captured.");if(!(Number(n.outputTriangleCount)>Number(n.sourceTriangleCount)))throw new Error("[smooth with subdivision] Expected subdivision to increase triangle count.");const r=(e.scene?.children||[]).filter(d=>d?.type==="SOLID");if(r.length!==1)throw new Error(`[smooth with subdivision] Expected one replacement solid, found ${r.length}.`);const a=r[0],o=a?.userData?.smoothWithSubdivision||null;if(!o)throw new Error("[smooth with subdivision] Output solid is missing feature metadata.");if(Number(o.subdivisionLoops)!==1)throw new Error("[smooth with subdivision] Output solid metadata has the wrong subdivision loop count.");if(!(Number(o.outputTriangleCount)>Number(o.sourceTriangleCount)))throw new Error("[smooth with subdivision] Output solid metadata did not record increased triangle count.");const s=new Set(["SMOOTH_SRC_B","SMOOTH_SRC_T","SMOOTH_SRC_S"]),i=new Set((typeof a.getFaceNames=="function"?a.getFaceNames():[]).map(d=>String(d||"").trim()).filter(d=>d.length>0));if(i.size!==s.size)throw new Error(`[smooth with subdivision] Expected ${s.size} retained face names, found ${i.size}.`);for(const d of s)if(!i.has(d))throw new Error(`[smooth with subdivision] Missing retained face name "${d}".`);const c=typeof a.getFaceMetadata=="function"?a.getFaceMetadata("SMOOTH_SRC_S"):null;if(!c||c.type!=="cylindrical")throw new Error("[smooth with subdivision] Cylindrical side face metadata was not preserved.");if(Number(c.radius)!==5||Number(c.height)!==12)throw new Error("[smooth with subdivision] Cylindrical side face metadata has the wrong dimensions.")}l(pp,"afterRun_smooth_with_subdivision_replaces_source_solid");async function _p(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch=Vo();const r=await e.newFeature("E");r.inputParams.profile=n.inputParams.featureID,r.inputParams.consumeProfileSketch=!1,r.inputParams.distance=6;const a=await e.newFeature("SWS");return a.inputParams.targetSolid=r.inputParams.featureID,a.inputParams.subdivisionLoops=1,e}l(_p,"test_smooth_with_subdivision_preserves_centered_ring_symmetry");async function hp(e){const t=(e.features||[]).find(c=>c?.type==="E");if(!t?.inputParams?.featureID)throw new Error("[smooth with subdivision symmetry] Missing extrude feature.");const n=e.scene.getObjectByName(t.inputParams.featureID);if(!n||typeof n.getMesh!="function")throw new Error("[smooth with subdivision symmetry] Smoothed solid missing from scene.");const r=n.getMesh(),a=[];try{for(let c=0;c<r.vertProperties.length;c+=3)a.push([r.vertProperties[c+0],r.vertProperties[c+1],r.vertProperties[c+2]])}finally{try{r?.delete?.()}catch{}}const o=hr(a,"x"),s=hr(a,"y"),i=1e-5;if(o.max>i||s.max>i)throw new Error(`[smooth with subdivision symmetry] Expected centered ring symmetry. mirrorX.max=${o.max}, mirrorY.max=${s.max}`)}l(hp,"afterRun_smooth_with_subdivision_preserves_centered_ring_symmetry");async function mp(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch=Vo();const r=await e.newFeature("E");r.inputParams.profile=n.inputParams.featureID,r.inputParams.consumeProfileSketch=!1,r.inputParams.distance=6;const a=await e.newFeature("P.CU");a.inputParams.sizeX=20,a.inputParams.sizeY=20,a.inputParams.sizeZ=20,a.inputParams.transform={position:[-20,-10,-10],rotationEuler:[0,0,0],scale:[1,1,1]};const o=await e.newFeature("B");o.inputParams.targetSolid=r.inputParams.featureID,o.inputParams.boolean={operation:"SUBTRACT",targets:[a.inputParams.featureID]};const s=await e.newFeature("P");s.inputParams.orientation="YZ";const i=await e.newFeature("M");i.inputParams.solids=[r.inputParams.featureID],i.inputParams.mirrorPlane=s.inputParams.featureID;const c=await e.newFeature("B");c.inputParams.targetSolid=r.inputParams.featureID,c.inputParams.boolean={operation:"UNION",targets:[`${i.inputParams.featureID}:${r.inputParams.featureID}:M`]};const d=await e.newFeature("SWS");return d.inputParams.targetSolid=r.inputParams.featureID,d.inputParams.subdivisionLoops=1,e}l(mp,"test_smooth_with_subdivision_preserves_mirrored_union_symmetry");async function gp(e){const t=(e.features||[]).find(i=>i?.type==="E");if(!t?.inputParams?.featureID)throw new Error("[smooth with subdivision mirrored symmetry] Missing extrude feature.");const n=e.scene.getObjectByName(t.inputParams.featureID);if(!n||typeof n.getMesh!="function")throw new Error("[smooth with subdivision mirrored symmetry] Smoothed mirrored-union solid missing.");const r=n.getMesh(),a=[];try{for(let i=0;i<r.vertProperties.length;i+=3)a.push([r.vertProperties[i+0],r.vertProperties[i+1],r.vertProperties[i+2]])}finally{try{r?.delete?.()}catch{}}const o=hr(a,"x");if(o.max>1e-5)throw new Error(`[smooth with subdivision mirrored symmetry] Expected mirrored-union symmetry. mirrorX.max=${o.max}`)}l(gp,"afterRun_smooth_with_subdivision_preserves_mirrored_union_symmetry");async function xp(e){const t=await e.newFeature("P.CO");t.inputParams.radiusTop=3,t.inputParams.radiusBottom=.5,t.inputParams.height=5.2,t.inputParams.resolution=20;const n=await e.newFeature("P");n.inputParams.orientation="YZ";const r=await e.newFeature("S");r.inputParams.sketchPlane=n.inputParams.featureID,r.persistentData.sketch={points:[{id:0,x:0,y:0,fixed:!0},{id:1,x:8,y:20,fixed:!1},{id:10,x:-.5,y:-.5,fixed:!1},{id:11,x:.5,y:-.5,fixed:!1},{id:12,x:.5,y:.5,fixed:!1},{id:13,x:-.5,y:.5,fixed:!1}],geometries:[{id:100,type:"line",points:[0,1],construction:!1},{id:200,type:"line",points:[10,11],construction:!1},{id:201,type:"line",points:[11,12],construction:!1},{id:202,type:"line",points:[12,13],construction:!1},{id:203,type:"line",points:[13,10],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]};const a=await e.newFeature("SW");a.inputParams.profile=`${t.inputParams.featureID}_T`,a.inputParams.path=[`${r.inputParams.featureID}:G100`],a.inputParams.orientationMode="translate";const o=await e.newFeature("B");return o.inputParams.targetSolid=t.inputParams.featureID,o.inputParams.boolean={targets:[a.inputParams.featureID],operation:"UNION"},e}l(xp,"test_SweepFace");async function Ep(e){const t=await e.newFeature("P");t.inputParams.orientation="YZ";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch={points:[{id:10,x:-5,y:-5,fixed:!1},{id:11,x:5,y:-5,fixed:!1},{id:12,x:5,y:5,fixed:!1},{id:13,x:-5,y:5,fixed:!1},{id:20,x:-3,y:-3,fixed:!1},{id:21,x:3,y:-3,fixed:!1},{id:22,x:3,y:3,fixed:!1},{id:23,x:-3,y:3,fixed:!1},{id:30,x:-1,y:-1,fixed:!1},{id:31,x:1,y:-1,fixed:!1},{id:32,x:1,y:1,fixed:!1},{id:33,x:-1,y:1,fixed:!1}],geometries:[{id:200,type:"line",points:[10,11],construction:!1},{id:201,type:"line",points:[11,12],construction:!1},{id:202,type:"line",points:[12,13],construction:!1},{id:203,type:"line",points:[13,10],construction:!1},{id:210,type:"line",points:[20,21],construction:!1},{id:211,type:"line",points:[21,22],construction:!1},{id:212,type:"line",points:[22,23],construction:!1},{id:213,type:"line",points:[23,20],construction:!1},{id:220,type:"line",points:[30,31],construction:!1},{id:221,type:"line",points:[31,32],construction:!1},{id:222,type:"line",points:[32,33],construction:!1},{id:223,type:"line",points:[33,30],construction:!1}],constraints:[]};const r=await e.newFeature("P");r.inputParams.orientation="XY";const a=await e.newFeature("S");a.inputParams.sketchPlane=r.inputParams.featureID,a.persistentData.sketch={points:[{id:0,x:0,y:0,fixed:!0},{id:1,x:12,y:0,fixed:!1}],geometries:[{id:100,type:"line",points:[0,1],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]};const o=await e.newFeature("SW");return o.inputParams.profile=n.inputParams.featureID,o.inputParams.path=[`${a.inputParams.featureID}:G100`],o.inputParams.orientationMode="pathAlign",o.inputParams.consumeProfileSketch=!1,e}l(Ep,"test_SweepFace_pathAlign_multi_loop_islands");async function yp(e){const t=(e?.features||[]).find(c=>String(c?.type||"").toUpperCase()==="SW"),n=Number(t?.persistentData?.profileIslandCount)||0,r=Array.isArray(t?.persistentData?.profileIslandEdgeCounts)?t.persistentData.profileIslandEdgeCounts:[];if(n>1){if(r.length!==n)throw new Error("[sweep_path_align_multi_loop_islands] Missing per-island edge counts.");if(r.some(c=>!(Number(c)>0)))throw new Error("[sweep_path_align_multi_loop_islands] One or more profile islands lost edge data.")}const a=(e?.scene?.children||[]).filter(c=>String(c?.type||"").toUpperCase()==="SOLID");if(!a.length)throw new Error("[sweep_path_align_multi_loop_islands] Expected sweep to produce a solid.");const o=a.find(c=>String(c?.name||"").startsWith("SW"))||a[0];let s=null;try{s=o.getMesh()}catch(c){throw new Error(`[sweep_path_align_multi_loop_islands] Sweep solid is not manifold: ${c?.message||c}`)}let i=0;try{i=typeof s?.numTri=="function"?Number(s.numTri())||0:(s?.triVerts?.length||0)/3}finally{try{s&&typeof s.delete=="function"&&s.delete()}catch{}}if(!(i>0))throw new Error("[sweep_path_align_multi_loop_islands] Sweep solid has no triangles.")}l(yp,"afterRun_sweepFace_pathAlign_multi_loop_islands");const Sp=1e-6;function La(e){return(Array.isArray(e?.children)?e.children:[]).find(n=>n&&n.type==="SKETCH")||null}l(La,"findSketchGroup");function Ba(e){return e&&(Array.isArray(e.children)?e.children:[]).find(n=>n&&n.type==="FACE")||null}l(Ba,"findSketchFace");function wp(e){return e?(Array.isArray(e.children)?e.children:[]).filter(n=>n&&n.type==="EDGE"):[]}l(wp,"findSketchEdges");function ut(e,t){if(!e)throw new Error(t)}l(ut,"expectTruthy");function vp(e,t,n){if(!Number.isFinite(e)||Math.abs(e-t)>Sp)throw new Error(`${n} expected ${t}, got ${e}`)}l(vp,"expectApprox");async function bp(e){e.expressions='textLabel = "BREP";';const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("TEXT");return n.inputParams.text="textLabel",n.inputParams.textHeight=10,n.inputParams.curveResolution=12,n.inputParams.placementPlane=t.inputParams.featureID,e}l(bp,"test_textToFace");async function Fp(e){const t=Array.isArray(e.features)?e.features.find(x=>x&&x.type==="TEXT"):null;if(ut(t,"[text_to_face] No TEXT feature found"),String(t?.previouseExpressions?.text??"")!=="BREP")throw new Error("[text_to_face] Text expression did not resolve to BREP");const n=t?.persistentData?.fontFile;if(typeof n!="string"||!n.startsWith("data:"))throw new Error("[text_to_face] Missing persistentData.fontFile data URL");const r=t?.persistentData?.fontFileKey;if(typeof r!="string"||!r.startsWith("font:"))throw new Error("[text_to_face] Missing or invalid persistentData.fontFileKey");const a=La(e.scene);ut(a,"[text_to_face] No SKETCH group found");const o=Ba(a);ut(o,"[text_to_face] No FACE found on SKETCH group");const s=wp(a);if(!s.length)throw new Error("[text_to_face] No sketch edges found");const i=o?.userData?.boundaryLoopsWorld;if(!Array.isArray(i)||!i.length)throw new Error("[text_to_face] Missing boundaryLoopsWorld on face");const c=o?.userData?.profileGroups;if(!Array.isArray(c)||!c.length)throw new Error("[text_to_face] Missing profileGroups on face");const d=ne.getBaseMaterial(o)||o.material;if(!d)throw new Error("[text_to_face] Face has no material");if(d.side!==M.THREE.DoubleSide)throw new Error("[text_to_face] Face material is not DoubleSide");if(!d.polygonOffset)throw new Error("[text_to_face] Face material polygonOffset not enabled");const u=ne.getBaseMaterial(s[0])||s[0].material;if(!u)throw new Error("[text_to_face] Edge has no material");if(u.depthTest!==!1)throw new Error("[text_to_face] Edge material depthTest should be false");if(s[0].renderOrder<2)throw new Error("[text_to_face] Edge renderOrder should be elevated");try{if(typeof o.getAverageNormal=="function"){const x=o.getAverageNormal();vp(Number(x.length()),1,"[text_to_face] Face normal not normalized")}}catch{}const f="__text_to_face_removed_font_test__";t.inputParams.font=f,t.inputParams.fontFile="",t.persistentData=t.persistentData||{},t.persistentData.fontFile=n,t.persistentData.fontFileKey=`font:${f}`,await e.runHistory();const p=Array.isArray(e.features)?e.features.find(x=>x&&x.type==="TEXT"):null;if(ut(p,"[text_to_face] No TEXT feature found after persisted-font fallback run"),p?.persistentData?.fontFileKey!==`font:${f}`)throw new Error("[text_to_face] Persisted font fallback did not preserve missing font id key");if(typeof p?.persistentData?.fontFile!="string"||!p.persistentData.fontFile.startsWith("data:"))throw new Error("[text_to_face] Persisted font fallback lost font data URL");const _=La(e.scene);ut(_,"[text_to_face] No SKETCH group found after persisted-font fallback run");const h=Ba(_);ut(h,"[text_to_face] No FACE found after persisted-font fallback run")}l(Fp,"afterRun_textToFace");async function Pp(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch={points:[{id:0,x:0,y:0,fixed:!0},{id:1,x:0,y:40,fixed:!1},{id:2,x:25,y:40,fixed:!1},{id:10,x:-2,y:-2,fixed:!1},{id:11,x:2,y:-2,fixed:!1},{id:12,x:2,y:2,fixed:!1},{id:13,x:-2,y:2,fixed:!1}],geometries:[{id:200,type:"line",points:[0,1],construction:!1},{id:201,type:"line",points:[1,2],construction:!1},{id:300,type:"line",points:[10,11],construction:!1},{id:301,type:"line",points:[11,12],construction:!1},{id:302,type:"line",points:[12,13],construction:!1},{id:303,type:"line",points:[13,10],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]};const r=`${n.inputParams.featureID}:`,a=await e.newFeature("TU");a.inputParams.path=[`${r}G200`,`${r}G201`],a.inputParams.radius=4,a.inputParams.innerRadius=0,a.inputParams.resolution=32;const o=await e.newFeature("TU");return o.inputParams.path=[`${r}G200`,`${r}G201`],o.inputParams.radius=5,o.inputParams.innerRadius=2,o.inputParams.resolution=48,e}l(Pp,"test_tube");async function Ap(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID;const r=6,a=20,o=[],s=[];for(let u=0;u<r;u++){const f=u/r*2*Math.PI;o.push({id:u,x:Math.cos(f)*a,y:Math.sin(f)*a,fixed:!1})}for(let u=0;u<r;u++){const f=(u+1)%r;s.push({id:200+u,type:"line",points:[u,f],construction:!1})}n.persistentData.sketch={points:o,geometries:s,constraints:[{id:0,type:"⏚",points:[0]}]};const i=`${n.inputParams.featureID}:`,c=await e.newFeature("TU");c.inputParams.path=s.map(u=>`${i}G${u.id}`),c.inputParams.radius=3,c.inputParams.innerRadius=0,c.inputParams.resolution=24;const d=await e.newFeature("TU");return d.inputParams.path=s.map(u=>`${i}G${u.id}`),d.inputParams.radius=4,d.inputParams.innerRadius=1,d.inputParams.resolution=24,d.inputParams.transform={position:[0,0,10],rotation:[0,0,0],scale:[1,1,1]},e}l(Ap,"test_tube_closedLoop");function an(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(an,"assert$e");function Tp(){const e={id:"sheet-1",name:"Instruction Sheet",elements:[{id:"table-1",type:"table"}]},t={id:"sheet-2",name:"Formboard Sheet",elements:[{id:"line-1",type:"line",groupId:"wire-harness-formboard:abc"}]};an(Xt([e],"")===null,"Expected unrelated sheets to be ignored when reusing a formboard target."),an(Xt([e,t],"")?.id==="sheet-2","Expected an existing formboard sheet to be reused."),an(Xt([e,t],"sheet-1")?.id==="sheet-2","Expected preferred non-formboard sheets to be ignored in favor of the actual formboard sheet."),an(Xt([e,t],"sheet-2")?.id==="sheet-2","Expected the preferred sheet to be reused when it already contains a formboard.")}l(Tp,"test_wire_harness_formboard_reuses_only_formboard_sheet");function xe(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(xe,"assert$d");function Ga(e,t){return{name:e,userData:{isPortRoot:!0,portData:{objectName:e,name:t,kind:"termination",point:[0,0,0],direction:[1,0,0]}}}}l(Ga,"createFakePort");async function Cp(){const e=Ga("PORT_A","Port A"),t=Ga("PORT_B","Port B"),n=new Map([[e.name,e],[t.name,t]]),r={scene:{traverse(i){i(e),i(t)},getObjectByName(i){return n.get(String(i))||null}},getObjectByName(i){return n.get(String(i))||null}},a=qr(r,{from:"Port A",to:"Port B"});xe(a.ok===!0,"Expected endpoint labels to resolve."),xe(a.fromRef==="PORT_A","Expected from endpoint to resolve to PORT_A."),xe(a.toRef==="PORT_B","Expected to endpoint to resolve to PORT_B."),xe(Array.isArray(a.portRefs)&&a.portRefs.length===2,"Expected both endpoint refs to be returned.");const o=qr(r,{from:"Port A",to:"Missing"});xe(o.ok===!1,"Expected unresolved endpoint lookup to fail."),xe(o.portRefs.length===1&&o.portRefs[0]==="PORT_A","Expected partial resolution to preserve the valid endpoint.");const s=ns(r,[{id:"WIRE1",from:"Port A",to:"Port B",diameter:1.25}]);xe(Array.isArray(s.segments)&&s.segments.length===0,"Expected payload to expose a segments array."),xe(Array.isArray(s.connections)&&s.connections.length===1,"Expected payload to expose one valid connection."),xe(s.connections[0].id==="WIRE1","Expected payload connection id to match."),xe(s.connections[0].startPoint==="PORT_A","Expected payload startPoint to use resolved port object names."),xe(s.connections[0].endPoint==="PORT_B","Expected payload endPoint to use resolved port object names."),xe(s.connections[0].wireInfo?.diameter===1.25,"Expected payload diameter to match input.")}l(Cp,"test_wire_harness_connection_endpoint_resolution");function U(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(U,"assert$c");function on(e,t,n="termination",r=[0,0,0],a=[1,0,0]){return{name:e,userData:{isPortRoot:!0,portData:{objectName:e,name:t,kind:n,point:r.slice(),direction:a.slice(),extension:1,displayLength:1}}}}l(on,"createPort$1");function Jn(e,t,n,r,a){return{type:"SP",inputParams:{featureID:e,curveResolution:4,bendRadius:1},persistentData:{spline:{points:[{id:"p0",position:[0,0,0],attachment:{type:"port",portRef:t,side:n}},{id:"p1",position:[1,0,0],attachment:{type:"port",portRef:r,side:a}}]}}}}l(Jn,"createSplineFeature$1");function Np(){const e=on("START","Start","termination",[-6,0,0],[1,0,0]),t=on("SPLIT","Split","waypoint",[0,0,0],[1,0,0]),n=on("BRANCHA","Branch A","termination",[5,4,0],[1,0,0]),r=on("BRANCHB","Branch B","termination",[5,-4,0],[1,0,0]),a=new Map([[e.name,e],[t.name,t],[n.name,n],[r.name,r]]);return{scene:{traverse(o){o(e),o(t),o(n),o(r)},getObjectByName(o){return a.get(String(o))||null}},getObjectByName(o){return a.get(String(o))||null},features:[Jn("SP1","START","A","SPLIT","A"),Jn("SP2","SPLIT","B","BRANCHA","A"),Jn("SP3","SPLIT","A","BRANCHB","A")]}}l(Np,"createSimpleHarnessPartHistory");function Rp(){const e=new An(null),t=e.createSheet({name:"Large Formboard",sizeKey:"CUSTOM",orientation:"landscape",customWidthIn:72,customHeightIn:36,elements:[]});U(t.sizeKey==="CUSTOM","Expected custom sheet size key to persist."),U(t.widthIn===72,"Expected custom sheet width to persist."),U(t.heightIn===36,"Expected custom sheet height to persist.");const n=e.updateSheet(t.id,{sizeKey:"CUSTOM",orientation:"portrait",customWidthIn:36,customHeightIn:72});U(n.sizeKey==="CUSTOM","Expected custom size key to survive sheet updates."),U(n.widthIn===36,"Expected portrait custom sheet width to persist."),U(n.heightIn===72,"Expected portrait custom sheet height to persist.")}l(Rp,"test_sheet_custom_size_persists");function Ip(){const e=Date.now;let t=1e3;Date.now=()=>t;try{const n=new An(null),r=n.createSheet({name:"Timestamp Sheet",sizeKey:"A",orientation:"landscape",elements:[]}),a=r.metadata?.createdAt,o=r.metadata?.updatedAt;U(a===1e3,"Expected sheet createdAt to use creation time."),U(o===1e3,"Expected sheet updatedAt to use creation time."),t=2e3,n.getSheets(),n.toSerializable();const s=n.getSheetById(r.id);U(s.metadata?.updatedAt===o,"Expected reading sheets not to update metadata.updatedAt."),t=3e3,n.updateSheet(r.id,{name:"Timestamp Sheet Updated"});const i=n.getSheetById(r.id);U(i.metadata?.createdAt===a,"Expected sheet updates to preserve createdAt."),U(i.metadata?.updatedAt===3e3,"Expected sheet updates to advance updatedAt.")}finally{Date.now=e}}l(Ip,"test_sheet_metadata_updated_at_is_stable_on_read");function Op(){const e=Np(),t=rs(e,{includeTitle:!0});U(t.ok===!0,"Expected harness formboard definition to succeed.");const n=t.elements.filter(u=>u?.type==="line"),r=t.elements.filter(u=>u?.type==="text");U(n.length===3,"Expected three flattened line segments for the Y harness."),U(n.every(u=>u?.formboard?.exactGeometry===!0),"Expected generated line segments to be marked as exact formboard geometry."),U(n.every(u=>u?.formboard?.fromNodeId&&u?.formboard?.toNodeId),"Expected generated line segments to carry directed node metadata."),U(r.some(u=>String(u?.text||"")==="Start"),"Expected endpoint labels to be included."),U(r.some(u=>String(u?.text||"").includes("in")),"Expected segment length labels to be included.");const a=new An(null),o=a.createSheet({name:"Instruction Sheet",sizeKey:"A",orientation:"landscape",elements:[]}),s=as(a,o.id,e,{includeTitle:!0,resizeSheetToFit:!0});U(s.ok===!0,"Expected formboard insertion to succeed."),U(s.sheet?.sizeKey==="CUSTOM","Expected insertion to promote the target sheet to custom sizing."),U((s.insertedElements||[]).filter(u=>u?.type==="line").length===3,"Expected inserted formboard to contain three line elements."),U((s.sheet?.elements||[]).filter(u=>u?.type==="line").every(u=>u?.formboard?.exactGeometry===!0),"Expected exact formboard metadata to persist through sheet normalization."),U((s.sheet?.elements||[]).every(u=>String(u?.groupId||"").startsWith("wire-harness-formboard:")),"Expected inserted sheet elements to belong to the generated formboard group.");const i=os(s.sheet?.elements||[]),c=(s.sheet?.elements||[]).find(u=>u?.type==="line"&&String(u?.formboard?.fromNodeId||"")==="SPLIT"),d=ss(i,"SPLIT",c?.id);U(d.size===1,"Expected pivot branch resolution to isolate one downstream branch."),U(d.has(String(c?.formboard?.toNodeId||"")),"Expected branch resolution to include the segment endpoint opposite the pivot.")}l(Op,"test_wire_harness_formboard_insert");function Bt(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Bt,"assert$b");function Dp(){const e=new Za(null),t=e.addView({viewName:"Sheet View",camera:{},annotations:[],viewSettings:{pmiTextSizePt:"18.5"}});Bt(t?.viewSettings?.pmiTextSizePt===18.5,"Expected PMI text size to normalize to a finite number.");const n=e.updateView(0,r=>(r.viewSettings.pmiTextSizePt=-4,r));Bt(!Object.prototype.hasOwnProperty.call(n?.viewSettings||{},"pmiTextSizePt"),"Expected invalid PMI text size to be removed during normalization.")}l(Dp,"test_pmi_view_text_size_setting_normalizes");function Mp(){const n=new Za(null).addView({viewName:"Visibility View",camera:{},annotations:[],viewSettings:{visibilityState:{hidden:[{key:"solid-a",count:"2.8"},{key:"",count:10},{key:"face-b",count:0}]}}})?.viewSettings?.visibilityState?.hidden||[];Bt(n.length===2,"Expected PMI visibility state to discard invalid hidden entries."),Bt(n[0]?.key==="solid-a"&&n[0]?.count===3,"Expected PMI visibility counts to normalize to rounded positive integers."),Bt(n[1]?.key==="face-b"&&n[1]?.count===1,"Expected PMI visibility counts to clamp to at least 1.")}l(Mp,"test_pmi_view_visibility_state_normalizes");function se(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(se,"assert$a");function G(e,t,n,r){if(!Number.isFinite(e)||Math.abs(e-t)>n)throw new Error(`${r||"Expected approximate equality"}: expected ${t}, got ${e}.`)}l(G,"assertApprox$1");function mr(e,t=0,{x0:n=-1,x1:r=1,y0:a=-1,y1:o=1}={}){const s=new Tn;s.setAttribute("position",new Wt([n,a,t,r,a,t,r,o,t,n,a,t,r,o,t,n,o,t],3)),s.setAttribute("normal",new Wt([0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1],3));const i=new Fr(s,new Pr);return i.name=e,i.type="FACE",i}l(mr,"makePlanarFace");function Gt(e,t){const n=new Re;return n.name=e,n.type="VERTEX",n.position.copy(t),n}l(Gt,"makeVertex");function Sn(e,t,n){const r=new Tn;r.setAttribute("position",new Wt([t.x,t.y,t.z,n.x,n.y,n.z],3));const a=new zs(r,new Hs);return a.name=e,a.type="EDGE",a}l(Sn,"makeLinearEdge");function ot(e){return{viewer:{partHistory:{scene:e}}}}l(ot,"makePMIMode$1");async function kp(){const e=new we,t=mr("BASE_FACE",0),n=Gt("TARGET_VERTEX",new $(2,3,5));e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=pn.showContexButton([t,n]);se(Array.isArray(r?.params?.targets),"Expected linear PMI context action for face and vertex.");const a=at.computeDimPoints(ot(e),{targets:["BASE_FACE","TARGET_VERTEX"]});se(a?.measurementMode==="faceNormal","Expected face-normal linear dimension mode."),G(a.p0.x,2,1e-9,"Expected projected foot x."),G(a.p0.y,3,1e-9,"Expected projected foot y."),G(a.p0.z,0,1e-9,"Expected projected foot on base face."),G(a.p1.z,5,1e-9,"Expected target point to remain along face normal."),G(a.p0.distanceTo(a.p1),5,1e-9,"Expected perpendicular face distance.")}l(kp,"test_pmi_linear_dimension_face_target_measures_perpendicular_to_face");async function $p(){const e=new we,t=mr("BASE_FACE",0),n=mr("TARGET_FACE",4,{x0:1,x1:3,y0:2,y1:4});e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(e),{targets:["BASE_FACE","TARGET_FACE"]});se(r?.measurementMode==="faceNormal","Expected face-normal linear dimension mode for planar faces."),G(r.p0.z,0,1e-9,"Expected base measurement point on base face plane."),G(r.p1.z,4,1e-9,"Expected target measurement point on target face plane."),G(r.p0.distanceTo(r.p1),4,1e-9,"Expected parallel planar face spacing.")}l($p,"test_pmi_linear_dimension_parallel_faces_measure_plane_spacing");async function Lp(){const e=new $(2,3,0),t=new $(2,3,5),n=oi({pointA:e,pointB:t,extensionAnchorA:new $(0,0,0),extensionAnchorB:t,normal:new $(0,1,0),offset:1,showExtensions:!0,screenSizeWorld:l(a=>a*.01,"screenSizeWorld")});se(n?.segments?.length>=4,"Expected jogged extension plus dimension segments.");const r=n.segments[0];G(r[0].x,0,1e-9,"Expected first jog segment to begin at face anchor."),G(r[0].y,0,1e-9,"Expected first jog segment to begin at face anchor."),G(r[1].x,2,1e-9,"Expected first jog segment to end at measurement foot."),G(r[1].y,3,1e-9,"Expected first jog segment to end at measurement foot.")}l(Lp,"test_pmi_linear_dimension_face_extensions_can_jog_to_measurement_line");async function Bp(){const e=new we,t=Sn("BASE_EDGE",new $(0,0,0),new $(10,0,0)),n=Gt("TARGET_VERTEX",new $(4,3,5));e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(e),{targets:["BASE_EDGE","TARGET_VERTEX"]});se(r?.measurementMode==="edgeNormal","Expected edge-normal linear dimension mode."),G(r.p0.x,4,1e-9,"Expected projected foot on edge line x."),G(r.p0.y,0,1e-9,"Expected projected foot on edge line y."),G(r.p0.z,0,1e-9,"Expected projected foot on edge line z."),G(r.p1.x,4,1e-9,"Expected target point to stay on perpendicular line x."),G(r.p1.y,3,1e-9,"Expected target y."),G(r.p1.z,5,1e-9,"Expected target z."),G(r.p1.clone().sub(r.p0).dot(new $(1,0,0)),0,1e-9,"Expected measurement direction perpendicular to edge.");const a=at.computeDimPoints(ot(e),{targets:["TARGET_VERTEX","BASE_EDGE"]});se(a?.measurementMode==="edgeNormal","Expected edge-normal mode regardless of selection order."),G(a.p0.x,4,1e-9,"Expected reversed projected foot x."),G(a.p0.distanceTo(a.p1),Math.sqrt(34),1e-9,"Expected reversed perpendicular distance.")}l(Bp,"test_pmi_linear_dimension_edge_target_measures_perpendicular_to_edge");async function Gp(){const e=new we,t=Sn("BASE_EDGE",new $(0,0,0),new $(10,0,0)),n=Sn("TARGET_EDGE",new $(2,3,4),new $(8,3,4));e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(e),{targets:["BASE_EDGE","TARGET_EDGE"]});se(r?.measurementMode==="edgeNormal","Expected edge-normal linear dimension mode for parallel edges."),G(r.p0.y,0,1e-9,"Expected base point on base edge y."),G(r.p0.z,0,1e-9,"Expected base point on base edge z."),G(r.p1.y,3,1e-9,"Expected target point on target edge y."),G(r.p1.z,4,1e-9,"Expected target point on target edge z."),G(r.p0.distanceTo(r.p1),5,1e-9,"Expected parallel edge spacing.")}l(Gp,"test_pmi_linear_dimension_parallel_edges_measure_perpendicular_spacing");async function Wp(){const e=new we,t=Sn("BASE_EDGE",new $(0,0,0),new $(10,0,0));e.add(t),e.updateMatrixWorld(!0);const n=at.computeDimPoints(ot(e),{targets:["BASE_EDGE"]});se(n?.measurementMode!=="edgeNormal","Expected a single edge to keep length dimension behavior."),G(n.p0.distanceTo(n.p1),10,1e-9,"Expected single edge length.")}l(Wp,"test_pmi_linear_dimension_single_edge_still_measures_edge_length");async function jp(){const e=pn.inputParamsSchema?.targets||{};se(e.maxSelections===2,"Expected linear dimension target selector to cap selections at two.");const t={targets:["A","B","C"]};pn.applyParams(null,t,t),se(Array.isArray(t.targets),"Expected linear dimension targets to stay an array."),se(t.targets.length===2,"Expected linear dimension params to clamp targets to two."),se(t.targets[0]==="A"&&t.targets[1]==="B","Expected linear dimension to keep the first two targets.");const n=new we;n.add(Gt("A",new $(0,0,0))),n.add(Gt("B",new $(1,0,0))),n.add(Gt("C",new $(100,0,0))),n.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(n),{targets:["A","B","C"]});G(r.p0.distanceTo(r.p1),1,1e-9,"Expected runtime measurement to ignore targets after the first two.")}l(jp,"test_pmi_linear_dimension_limits_targets_to_two");async function Vp(){const n=is({type:"linear",inputParams:{id:"DIM1",type:"linear"},lastRun:{ok:!1,durationMs:4.2,errorMessage:"Linear dimension could not resolve two measurement points."}},{history:{registry:{resolve(r){return r==="linear"?pn:null}}}});se(n.hasError===!0,"Expected failed annotation to be marked as an error."),se(String(n.statusText||"").includes("Error"),"Expected failed annotation status text to show Error."),se(String(n.statusTitle||"").includes("could not resolve"),"Expected failed annotation status title to include the render error message.")}l(Vp,"test_pmi_annotation_failure_status_is_visible");function wn(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(wn,"assert$9");function Gr(e,t,n,r){if(!Number.isFinite(e)||Math.abs(e-t)>n)throw new Error(`${r||"Expected approximate equality"}: expected ${t}, got ${e}.`)}l(Gr,"assertApprox");function Up(e,t,n=24){const r=[];for(let o=0;o<n;o+=1){const s=o/n*Math.PI*2,i=(o+1)/n*Math.PI*2,c=[Math.cos(s)*e,0,Math.sin(s)*e],d=[Math.cos(s)*e,t,Math.sin(s)*e],u=[Math.cos(i)*e,0,Math.sin(i)*e],f=[Math.cos(i)*e,t,Math.sin(i)*e];r.push(...c,...d,...f,...c,...f,...u)}const a=new Tn;return a.setAttribute("position",new Wt(r,3)),a}l(Up,"makePipeFaceGeometry");function Wr({faceName:e,pathName:t,geometryRadius:n,metadata:r={},height:a=10}){const o=new we,s=new Fe;s.name=`${e}_OWNER`,s.type="SOLID",s._auxEdges=[{name:t,points:[[0,0,0],[0,a,0]],closedLoop:!1,polylineWorld:!0,centerline:!0}],s.getFaceMetadata=c=>c===e?r:{};const i=new Fr(Up(n,a),new Pr);return i.name=e,i.type="FACE",i.userData.faceName=e,s.add(i),o.add(s),o.updateMatrixWorld(!0),{scene:o,face:i}}l(Wr,"makePipeScene");function jr(e){return{viewer:{partHistory:{scene:e}}}}l(jr,"makePMIMode");async function zp(){const e="PMI_PIPE_Outer",{scene:t,face:n}=Wr({faceName:e,pathName:"PMI_PIPE_PATH",geometryRadius:2}),r=Ar.showContexButton([n]);wn(r?.params?.cylindricalFaceRef===e,"Expected radial PMI context action for pipe outer face.");const a=Tr.computeRadialPoints(jr(t),{cylindricalFaceRef:e});wn(a?.center&&a?.radiusPoint,"Expected radial PMI to resolve pipe geometry from the auxiliary path."),Gr(a.radius,2,1e-6,"Expected radial PMI to measure pipe radius from geometry.")}l(zp,"test_pmi_radial_dimension_accepts_pipe_aux_path_face");async function Hp(){const e="PMI_FILLET_E1_TUBE_Outer",{scene:t,face:n}=Wr({faceName:e,pathName:"PMI_FILLET_E1_TUBE_PATH",geometryRadius:2.4,metadata:{type:"pipe",source:"FilletFeature",pmiRadiusOverride:1.5,radiusOverride:1.5,inflatedRadius:2.4,filletSideWall:!0}}),r=Ar.showContexButton([n]);wn(r?.params?.cylindricalFaceRef===e,"Expected radial PMI context action for fillet pipe face.");const a=Tr.measureRadialValue(jr(t),{cylindricalFaceRef:e});Gr(a,1.5,1e-9,"Expected radial PMI to use fillet pmiRadiusOverride.")}l(Hp,"test_pmi_radial_dimension_uses_fillet_pipe_radius_override");async function Yp(){const e="O.S17_ROUND_PIPE_3_Outer",t="O.S17_ROUND_PIPE_3_PATH",{scene:n,face:r}=Wr({faceName:e,pathName:t,geometryRadius:.421,metadata:{type:"rounded_pipe",faceRole:"rounded_pipe",offsetShellFaceRole:"rounded_pipe",offsetShellRoundedPipe:!0,sourceFeatureId:"O.S17",pmiRadiusOverride:.5,radiusOverride:.5,offsetShellRadius:.5,pmiCenterlineAuxName:t}}),a=Ar.showContexButton([r]);wn(a?.params?.cylindricalFaceRef===e,"Expected radial PMI context action for offset-shell rounded pipe face.");const o=Tr.measureRadialValue(jr(n),{cylindricalFaceRef:e});Gr(o,.5,1e-9,"Expected radial PMI to use offset-shell rounded-pipe radius override.")}l(Yp,"test_pmi_radial_dimension_uses_offset_shell_pipe_radius_override");async function Xp(e){const t=await e.newFeature("P.CU");t.inputParams.sizeX=8,t.inputParams.sizeY=6,t.inputParams.sizeZ=4}l(Xp,"test_pmi_view_visibility_state_round_trip");async function Kp(e){const n=(Array.isArray(e?.features)?e.features[0]:null)?.inputParams?.featureID;if(!n)throw new Error("PMI visibility state test requires a first feature with featureID.");const r=e.scene?.getObjectByName?.(n);if(!r||r.type!=="SOLID")throw new Error("PMI visibility state test could not find the cube solid.");const a=(Array.isArray(r.children)?r.children:[]).find(c=>c?.type==="FACE")||null,o=(Array.isArray(r.children)?r.children:[]).find(c=>c?.type==="EDGE")||null;if(!a||!o)throw new Error("PMI visibility state test requires one face and one edge on the cube.");r.visible=!1,a.visible=!1,o.visible=!1;const s=new Re;s.type="COMPONENT",s.name="PMI_VIS_COMPONENT",s.visible=!1,e.scene.add(s);const i=e.captureVisibilityState();if(!Array.isArray(i)||i.length<4)throw new Error("Expected captureVisibilityState() to capture hidden scene objects beyond just faces and edges.");if(r.visible=!0,a.visible=!0,o.visible=!0,s.visible=!0,e.applyVisibilityState(i),r.visible!==!1||a.visible!==!1||o.visible!==!1||s.visible!==!1)throw new Error("applyVisibilityState() did not restore the captured hidden state.");if(e.applyVisibilityState([]),r.visible!==!0||a.visible!==!0||o.visible!==!0||s.visible!==!0)throw new Error("applyVisibilityState([]) did not clear the captured hidden state.")}l(Kp,"afterRun_pmi_view_visibility_state_round_trip");function ye(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(ye,"assert$8");function Jp(){const e=Object.create(Ut.prototype);e.viewer=null;const t=new co(-10,10,10,-10,.1,100);t.position.set(0,0,10),t.lookAt(0,0,0),t.updateProjectionMatrix(),t.updateMatrixWorld(!0);const n=e._composeLabelSVG("data:image/png;base64,",[{world:new $(0,0,0),text:"R1.500",anchor:"center middle"}],400,300,400,{viewer:{camera:t},renderMode:"monochrome",labelBackdropColor:"#ff0000"});ye(n.includes('fill="#ff0000"'),"Expected monochrome PMI label mask to use the view backdrop color."),ye(n.includes('stroke="none"'),"Expected monochrome PMI label mask to avoid drawing a border.")}l(Jp,"test_pmi_monochrome_label_svg_uses_backdrop_color");function Zp(){const e=Object.create(Ut.prototype);e.viewer=null;const t=e._getLabelLayoutMetrics(400,400,{renderMode:"monochrome"}),n=e._getLabelLayoutMetrics(400,400,{renderMode:"shaded"});ye(t.paddingX<n.paddingX,"Expected monochrome PMI label mask horizontal padding to be tighter than shaded export padding."),ye(t.paddingY<n.paddingY,"Expected monochrome PMI label mask vertical padding to be tighter than shaded export padding."),ye(t.lineHeight<n.lineHeight,"Expected monochrome PMI label mask line height to be tighter than shaded export line height."),ye(t.radius<n.radius,"Expected monochrome PMI label mask corner radius to be tighter than shaded export radius.")}l(Zp,"test_pmi_monochrome_label_layout_is_tighter_than_shaded");function qp(){const e=Object.create(Ut.prototype),t=[],n={viewName:"View 1"},r=globalThis.setTimeout;e._enterEditMode=(a,o)=>{t.push({view:a,index:o})};try{globalThis.setTimeout=(a,o)=>(a(),0),e.enterEditMode(n,3)}finally{globalThis.setTimeout=r}ye(t.length===2,"Expected shared PMI edit flow to invoke the edit handoff twice."),ye(t[0]?.view===n&&t[1]?.view===n,"Expected shared PMI edit flow to forward the same view."),ye(t[0]?.index===3&&t[1]?.index===3,"Expected shared PMI edit flow to forward the same view index.")}l(qp,"test_pmi_enter_edit_mode_reuses_shared_flow");function Qp(){const e=Object.create(Ut.prototype),t=[],n=new co(-10,10,10,-10,.1,100);n.position.set(0,0,10),n.lookAt(0,0,0),n.updateProjectionMatrix(),n.updateMatrixWorld(!0),e._getCaptureViewportMetrics=()=>({width:100,height:100}),e._updateExportCameraLightRig=()=>{},e._applyWireframe=()=>{};const r={camera:{position:{x:0,y:0,z:1},quaternion:{x:0,y:0,z:0,w:1},up:{x:0,y:1,z:0},zoom:1,projection:null},viewSettings:{visibilityState:{hidden:[{key:"solid-a",count:1}]}}},a={viewer:{camera:n,partHistory:{applyVisibilityState(o){t.push(o)}}},viewport:{width:100,height:100},scene:{}};e._applyViewToRenderContext(r,a,{index:0}),ye(t.length===1,"Expected PMI export render context to apply view visibility state."),ye(Array.isArray(t[0])&&t[0][0]?.key==="solid-a","Expected PMI export render context to forward hidden visibility entries.")}l(Qp,"test_pmi_export_render_context_applies_visibility_state");function e1(){const e=Object.create(Ut.prototype),t=new Re,n=new Re;t.visible=!1,n.visible=!0,t.add(n),ye(e._isObjectEffectivelyVisible(n)===!1,"Expected hidden ancestors to make PMI export objects effectively invisible.")}l(e1,"test_pmi_effective_visibility_respects_hidden_ancestor");function T(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(T,"assert$7");function Te(e,t,n=1e-9){return Math.abs(Number(e)-Number(t))<=n}l(Te,"approxEqual$1");function t1(){T(rr("PORT")===!0,"Expected feature dimension overlay to support port features.")}l(t1,"test_feature_dimension_overlay_supports_port");function n1(){const e=["P.CU","P.CY","P.CO","P.S","P.PY","P.T","E","R","PORT"];for(const t of e)T(rr(t)===!0,`Expected ${t} to be registered for feature dimensions.`),T(la(t)===!0,`Expected ${t} transform controls to expose dimension toggles.`);T(rr("UNKNOWN")===!1,"Expected unknown feature keys to be rejected by the feature dimension registry."),T(la("UNKNOWN")===!1,"Expected unknown feature keys to be rejected by the transform dimension toggle registry.")}l(n1,"test_feature_dimension_registry_support_and_transform_toggle_agree");function r1(){const e=[],n=new ls({active:{entryId:"P1",featureKey:"P.CU",entry:{inputParams:{sizeX:1,sizeY:2,sizeZ:3}}},createLinearAnnotation:l(r=>(e.push(r),{id:`${r.entryId}:${r.fieldKey}`,fieldKey:r.fieldKey}),"createLinearAnnotation"),createAngleAnnotation:l(()=>null,"createAngleAnnotation")}).build();T(n.length===3,"Expected cube feature to build three primitive dimensions."),T(e.map(r=>r.fieldKey).join(",")==="sizeX,sizeY,sizeZ","Expected registered cube descriptor to dispatch through the annotation builder.")}l(r1,"test_feature_dimension_annotation_builder_dispatches_registered_primitive");function a1(){const e={},n=Ys({stores:[e],schema:{edges:{type:"reference_selection"}},resolvedParams:{edges:[{name:"S1:G4",type:"EDGE",uuid:"edge-uuid",points:l(()=>[{x:0,y:0,z:0},{x:4,y:0,z:0}],"points")}]}});T(n===1,"Expected one reference snapshot write."),T(!e.__refPreviewSnapshots,"Expected legacy reference preview snapshots key not to be created."),T(Array.isArray(e.referenceSnapshots?.edges?.["S1:G4"]?.positions),"Expected edge snapshot to be stored under referenceSnapshots."),T(Xs(e,"edges",["S1:G4"],new Set(["EDGE"]))===e.referenceSnapshots.edges["S1:G4"],"Expected snapshots to resolve through the generic reference snapshot store.")}l(a1,"test_reference_snapshot_store_uses_generic_reference_snapshots_key");function o1(){const e=Qr({point:[1,2,3],direction:[0,0,10],extension:4},.5);T(e,"Expected positive port extension geometry to resolve."),T(Te(e.value,4),"Expected extension value to be preserved."),T(Te(e.dragPlaneValue,4),"Expected drag plane value to match positive extension."),T(Te(e.pointB.x,1)&&Te(e.pointB.y,2)&&Te(e.pointB.z,7),"Expected endpoint to follow normalized port direction.");const t=Qr({point:[0,0,0],direction:[5,0,0],extension:0},.75);T(t,"Expected zero-length port extension geometry to resolve."),T(Te(t.value,0),"Expected displayed extension value to remain zero."),T(Te(t.dragPlaneValue,.75),"Expected zero-length extension to keep a visible drag handle offset."),T(Te(t.pointB.x,.75)&&Te(t.pointB.y,0)&&Te(t.pointB.z,0),"Expected visible tip offset to follow the normalized direction.")}l(o1,"test_port_extension_annotation_geometry_preserves_extension_value");function s1(){const e={name:"S1:PROFILE",type:"FACE",children:[]},t={name:"S1:G4",type:"EDGE",children:[]},n={name:"S1",type:"SKETCH",children:[{name:"S1:P1",type:"VERTEX",children:[]},e,{name:"edges",type:"GROUP",children:[t]}]},r={effects:{removed:[n],added:[]}};T(Kt(r,"S1:PROFILE",new Set(["FACE"]))===e,"Expected consumed profile face to resolve from feature effects."),T(Kt(r,{edgeName:"S1:G4"},["EDGE"])===t,"Expected consumed revolve axis edge to resolve from feature effects."),T(Kt(r,{reference:"S1"},new Set(["SKETCH"]))===n,"Expected consumed sketch object to resolve from feature effects."),T(Kt(r,"S1:PROFILE",new Set(["EDGE"]))==null,"Expected type filtering to reject non-axis profile matches.");const a=cs({reference:["S1:PROFILE",{edgeName:"S1:G4"}]});T(a.includes("S1:PROFILE")&&a.includes("S1:G4"),"Expected nested reference names to be collected for generic overlay resolution.")}l(s1,"test_feature_dimension_effect_reference_resolves_consumed_profile_and_axis");async function i1(){const e=new Y,t=new Fe;t.name="protected-overlay-test",Ks(t,{preserve:!0,overlayType:"testOverlay"});const n=new Fe;n.name="regular-overlay-test",e.scene.add(n,t),await e.scene.clear(),T(t.parent===e.scene,"Expected preventRemove scene child to survive scene.clear()."),T(n.parent!==e.scene,"Expected unprotected scene child to be removed by scene.clear()."),Js(t,{deep:!0}),e.scene.remove(t),T(t.parent!==e.scene,"Expected unmarked overlay child to be removable.")}l(i1,"test_part_history_prevent_remove_survives_multi_child_scene_clear");async function l1(){const e=new Y;let t=0;const n={scene:e.scene,render:l(()=>{t++},"render")},r=new Re,a=new Fe,o={__helper:null,attached:null,mode:"translate",updated:!1,getHelper:l(()=>a,"getHelper"),attach(c){this.attached=c},getMode(){return this.mode},setMode(c){this.mode=c},update(){this.updated=!0}};Zs(r),e.scene.add(r);const s=qs(n,o);T(s.addedToScene===!0,"Expected transform helper to be added to the scene."),T(a.parent===e.scene,"Expected transform helper to have the scene as parent."),T(a.userData.preventRemove===!0,"Expected transform helper to be scene-removal protected."),T(r.userData.preventRemove===!0,"Expected transform target to be scene-removal protected."),await e.scene.clear(),T(a.parent===e.scene,"Expected transform helper to survive protected scene clear."),T(r.parent===e.scene,"Expected transform target to survive protected scene clear."),ca({viewer:n,controls:o,group:s.group,target:r}),T(a.parent!==e.scene,"Expected transform helper to be removable through transform teardown."),T(r.parent!==e.scene,"Expected transform target to be removable through transform teardown.");const i=Qs(n,o,r);T(i.addedToScene===!0,"Expected transform helper to be restored to the scene."),T(a.parent===e.scene,"Expected restored transform helper to have the scene as parent."),T(r.parent===e.scene,"Expected restored transform target to have the scene as parent."),T(o.attached===r,"Expected transform controls to reattach to the target."),T(o.updated===!0,"Expected transform controls to be updated after restore."),T(t>0,"Expected restore to request a viewer render."),ca({viewer:n,controls:o,group:i.group,target:r})}l(l1,"test_transform_control_scene_binding_readds_and_removes_overlay_roots");function Ce(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Ce,"assert$6");function un(e,t,n=1e-9){return Math.abs(Number(e)-Number(t))<=n}l(un,"approxEqual");function vn(e,t,n){const r=[e.x,e.y,e.z];for(let a=0;a<3;a+=1)if(!un(r[a],t[a]))throw new Error(n||`Expected vector ${t.join(", ")}, got ${r.join(", ")}.`)}l(vn,"assertVec3");function c1(){const e=ei({position:[1,2,3],rotationEuler:[4,5,6],scale:[1,1,1],reference:{name:"FACE_REF",type:"FACE",pickPoint:[7,8,9],faceIndex:3}});Ce(e.reference&&typeof e.reference=="object","Expected transform reference metadata to be preserved."),Ce(e.reference.name==="FACE_REF","Expected transform reference name to persist."),Ce(e.reference.type==="FACE","Expected transform reference type to persist."),Ce(Array.isArray(e.reference.pickPoint),"Expected pick point metadata to persist."),Ce(e.reference.faceIndex===3,"Expected face index metadata to persist.")}l(c1,"test_transform_reference_sanitize_preserves_metadata");function d1(){const e=new we,t=new Re;t.name="FACE_PICK",t.type="FACE",e.add(t);const n=ti({name:"FACE_PICK",type:"FACE",pickPoint:[3,4,5]},e,{},uo),r=new $(Number(n.position[0])||0,Number(n.position[1])||0,Number(n.position[2])||0);vn(r,[3,4,5],"Expected face reference base to use the stored pick point.")}l(d1,"test_transform_reference_base_uses_face_pick_point");function u1(){const e=new we,t=new Re;t.name="VERTEX_REF",t.type="VERTEX",t.position.set(10,20,30),e.add(t);const n=ni({position:[1,2,3],rotationEuler:[0,0,0],scale:[1,1,1],reference:{name:"VERTEX_REF",type:"VERTEX"}},e,{},uo),r=new $,a=new ri,o=new $;n.decompose(r,a,o),vn(r,[11,22,33],"Expected referenced transform to offset from the selected vertex.")}l(u1,"test_referenced_transform_matrix_uses_vertex_reference_origin");function f1(){const e=new we,t=new Re;t.name="PORT_VERTEX",t.type="VERTEX",t.position.set(5,0,0),e.add(t);const n=to({featureId:"PORT_REF_TEST",inputParams:{portName:"Port Ref Test",transform:{position:[2,0,0],rotationEuler:[0,0,0],scale:[1,1,1],reference:{name:"PORT_VERTEX",type:"VERTEX"}},extension:2,displayLength:4},referenceSource:e});Ce(Array.isArray(n.point),"Expected port definition point to resolve."),Ce(un(n.point[0],7),"Expected port point to be offset from the transform reference."),Ce(un(n.point[1],0)&&un(n.point[2],0),"Expected port point to remain aligned to the reference origin."),Ce(n.anchorName==="PORT_VERTEX","Expected anchorName compatibility field to reflect the transform reference."),Ce(n.transform?.reference,"Expected normalized port transform to retain its reference.")}l(f1,"test_port_definition_uses_transform_reference_without_anchor");function p1(){const e=new we,t=new Re;t.name="PORT_VERTEX_DIR",t.type="VERTEX",t.position.set(1,2,3),e.add(t);const n=new Re;n.name="PORT_DATUM_DIR",n.type="DATUM",n.quaternion.setFromAxisAngle(new $(0,0,1),Math.PI/2),e.add(n),e.updateMatrixWorld(!0);const r=to({featureId:"PORT_DIR_TEST",inputParams:{transform:{position:[2,0,0],rotationEuler:[0,0,0],scale:[1,1,1],reference:{name:"PORT_VERTEX_DIR",type:"VERTEX"}},directionRef:[{name:"PORT_DATUM_DIR",type:"DATUM"}]},referenceSource:e});vn(new $(...r.point),[1,4,3],"Expected point reference to inherit the direction reference basis."),vn(new $(...r.direction),[0,1,0],"Expected port direction to align with the direction reference.")}l(p1,"test_port_definition_uses_transform_reference_and_direction_reference");function Xe(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Xe,"assert$5");async function _1(){const e=new An(null),t=e.createSheet({name:"Harness Sheet",sizeKey:"A",orientation:"landscape",elements:[]}),n=[{id:"WIRE1",name:"Wire 1",from:"PORT_A",to:"PORT_B",diameter:1.25},{id:"WIRE2",name:"Wire 2",from:"PORT_C",to:"PORT_D",diameter:.8}],r=[{connectionId:"WIRE1",feasible:!0,distance:123.456},{connectionId:"WIRE2",feasible:!1,error:"No route found."}],a=ds(n,r);Xe(a.cells[0][0].text==="Wire","Expected first header cell to be Wire."),Xe(a.cells[1][1].text==="123.46","Expected routed length to be formatted into the sheet table."),Xe(a.cells[2][5].text==="Failed","Expected failed routes to use a compact sheet status label.");const o=us(e,t.id,n,r);Xe(!!o?.sheet,"Expected sheet insertion to return an updated sheet."),Xe(!!o?.element,"Expected sheet insertion to return the inserted element."),Xe(o.element.type==="table","Expected inserted element to be a table."),Xe(o.element.tableData?.cells?.[1]?.[0]?.text==="Wire 1","Expected first wire name to appear in the inserted table."),Xe(o.element.tableData?.cells?.[2]?.[5]?.text==="Failed","Expected compact status text to persist on the inserted table element.")}l(_1,"test_wire_harness_sheet_table_insert");function Zn(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Zn,"assert$4");function qn(e,t,n="termination",r=[0,0,0],a=[1,0,0]){return{name:e,userData:{isPortRoot:!0,portData:{objectName:e,name:t,kind:n,point:r.slice(),direction:a.slice(),extension:1,displayLength:1}}}}l(qn,"createPort");function Wa(e,t,n,r,a){return{type:"SP",inputParams:{featureID:e,curveResolution:4,bendRadius:1},persistentData:{spline:{points:[{id:"p0",position:[0,0,0],attachment:{type:"port",portRef:t,side:n}},{id:"p1",position:[1,0,0],attachment:{type:"port",portRef:r,side:a}}]}}}}l(Wa,"createSplineFeature");async function h1(){const e=qn("START","Start","termination",[-4,0,0],[1,0,0]),t=qn("END","End","termination",[4,0,0],[1,0,0]),n=qn("WAYPOINT","Waypoint","waypoint",[0,0,0],[1,0,0]),r=new Map([[e.name,e],[t.name,t],[n.name,n]]),a={scene:{traverse(c){c(e),c(t),c(n)},getObjectByName(c){return r.get(String(c))||null}},getObjectByName(c){return r.get(String(c))||null},features:[Wa("SP1","START","A","WAYPOINT","A"),Wa("SP2","WAYPOINT","B","END","A")]},{network:o,routes:s}=await fs(a,[{id:"WIRE3",name:"Wire 3",from:"Start",to:"End",diameter:1}]),i=(o?.splineSegments||[]).filter(c=>c.firstPoint==="WAYPOINT"||c.secondPoint==="WAYPOINT").map(c=>c.firstPoint==="WAYPOINT"?c.firstSide:c.secondSide);Zn(i.length===2,"Expected two waypoint segment attachments."),Zn(i.every(c=>c==="B"),"Expected both spline branches to occupy waypoint side B."),Zn(s[0].feasible===!1,"Expected route to fail when both branches use the same physical waypoint side.")}l(h1,"test_wire_harness_infers_endpoint_side_from_spline_direction");function et(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(et,"assert$3");function m1(){const e=new we;ps(e,[],[{segmentId:"SEG1",featureId:"SP1",polyline:[[0,0,0],[15,0,0],[15,10,0]],diameter:2.5,wireCount:3,wireDiameters:[1,1,1.5],connectionIds:["WIRE-1"],connectionNames:["Wire 1"]}]);const t=e.getObjectByName("__WireHarnessRoutes");et(t,"Expected the wire harness route group to be added to the scene.");const n=[];e.traverse(s=>{s?.type==="SOLID"&&s?.userData?.isWireHarnessRoute&&n.push(s)}),et(n.length===1,`Expected one routed harness solid, got ${n.length}.`),et(typeof n[0].toSTL=="function","Expected routed harness geometry to be a real BREP solid."),et(_s(e,"WIRE-1").length===1,"Expected connection hover lookup to resolve the routed harness solid.");const r=n[0].getMesh(),a=(r?.triVerts?.length||0)/3|0;try{r?.delete?.()}catch{}et(a>0,"Expected routed harness solid to contribute triangulated geometry for export."),hs(e),et(e.getObjectByName("__WireHarnessRoutes")==null,"Expected clear to remove the wire harness route group.");const o=[];e.traverse(s=>{s?.type==="SOLID"&&s?.userData?.isWireHarnessRoute&&o.push(s)}),et(o.length===0,"Expected clear to remove routed harness solids from the scene.")}l(m1,"test_wire_harness_routes_render_as_scene_solids");function Ke(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Ke,"assert$2");async function g1(){const e=new Y;e.wireHarnessManager.addConnection({id:"wire-1",name:"Wire 1",from:"PORT-A",to:"PORT-B",diameter:1.5}),e.wireHarnessManager.setRouteResults([{connectionId:"wire-1",connectionName:"Wire 1",feasible:!0,error:"",distance:42.5,polyline:[[0,0,0],[10,0,0],[10,5,0]],segmentIds:["SP1","SP2"],nodePath:["PORT-A:A","MID:A","PORT-B:A"],reusesHarnessPoint:!1,diameter:1.5,from:"PORT-A",to:"PORT-B"}]);const t=await e.toJSON(),n=new Y;await n.fromJSON(t);const r=n.wireHarnessManager.getConnections();Ke(r.length===1,`Expected one restored connection, got ${r.length}.`),Ke(r[0].id==="wire-1","Expected the connection ID to persist.");const a=n.wireHarnessManager.getRouteResults();Ke(a.length===1,`Expected one restored route result, got ${a.length}.`),Ke(a[0].feasible===!0,"Expected the restored route result to remain feasible."),Ke(a[0].distance===42.5,`Expected the restored route distance to persist, got ${a[0].distance}.`),Ke(a[0].segmentIds.join(",")==="SP1,SP2","Expected restored route segment IDs to persist.");const o=n.wireHarnessManager.consumePendingRestoredRouteResults();Ke(Array.isArray(o)&&o.length===1,"Expected the restored model to queue route geometry restoration."),Ke(n.wireHarnessManager.consumePendingRestoredRouteResults()==null,"Expected pending restored routes to be consumed only once.")}l(g1,"test_wire_harness_route_results_persist_in_model_json");async function x1(e){const t=await e.newFeature("P.CU");t.inputParams.sizeX=8,t.inputParams.sizeY=6,t.inputParams.sizeZ=4}l(x1,"test_visibility_hidden_state_persistence");async function E1(e){const n=(Array.isArray(e?.features)?e.features[0]:null)?.inputParams?.featureID;if(!n)throw new Error("Visibility persistence test requires a first feature with featureID.");const r=e.scene?.getObjectByName?.(n);if(!r||r.type!=="SOLID")throw new Error("Visibility persistence test could not find initial cube solid.");const a=(Array.isArray(r.children)?r.children:[]).find(p=>p?.type==="FACE")||null,o=(Array.isArray(r.children)?r.children:[]).find(p=>p?.type==="EDGE")||null;if(!a||!o)throw new Error("Visibility persistence test requires one face and one edge on the cube.");const s=String(a?.userData?.faceName||a?.name||""),i=String(o?.name||"");if(!s||!i)throw new Error("Visibility persistence test requires named face and edge.");r.visible=!1,a.visible=!1,o.visible=!1,await e.newFeature("P.CU"),await e.runHistory();const c=e.scene?.getObjectByName?.(n);if(!c)throw new Error("Visibility persistence test could not find rebuilt cube.");if(c.visible!==!1)throw new Error("Hidden solid visibility state was not preserved after history run.");const d=Array.isArray(c.children)?c.children:[],u=d.find(p=>p?.type!=="FACE"?!1:String(p?.userData?.faceName||p?.name||"")===s)||null,f=d.find(p=>p?.type==="EDGE"&&String(p?.name||"")===i)||null;if(!u)throw new Error("Hidden face could not be resolved after history run.");if(!f)throw new Error("Hidden edge could not be resolved after history run.");if(u.visible!==!1)throw new Error("Hidden face visibility state was not preserved after history run.");if(f.visible!==!1)throw new Error("Hidden edge visibility state was not preserved after history run.")}l(E1,"afterRun_visibility_hidden_state_persistence");function ja(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(ja,"assert$1");async function y1(){ja(da(sa,"MODELING")===!0,"Expected Thicken to be available in the Modeling workbench."),ja(da(sa,"SURFACING")===!0,"Expected Thicken to be available in the Surfacing workbench.")}l(y1,"test_thicken_feature_is_available_in_modeling_and_surfacing_workbenches");function Rt(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Rt,"assert");async function S1(){const e={type:"SKETCH",visible:!0},t={getObjectByName(n){return n==="SK_001"?e:null}};Rt(Vn(t,"SK_001",!1)===!0,"Expected sketch visibility helper to hide the requested sketch object."),Rt(e.visible===!1,"Expected sketch object to become hidden."),Rt(Vn(t,"SK_001",!0)===!0,"Expected sketch visibility helper to restore the requested sketch object."),Rt(e.visible===!0,"Expected sketch object visibility to be restored."),Rt(Vn(t,"MISSING",!0)===!1,"Expected helper to report when a sketch object cannot be found.")}l(S1,"test_sketch_feature_scene_visibility");function w1(e){const t=Array.isArray(e?._triVerts)?e._triVerts:[],n=t.length/3|0,r=new Map,a=l((i,c)=>i<c?`${i}|${c}`:`${c}|${i}`,"edgeKey");for(let i=0;i<n;i++){const c=t[i*3]>>>0,d=t[i*3+1]>>>0,u=t[i*3+2]>>>0;for(const[f,p]of[[c,d],[d,u],[u,c]]){const _=a(f,p);r.set(_,(r.get(_)||0)+1)}}let o=0,s=0;for(const i of r.values())i===1?o+=1:i!==2&&(s+=1);return{boundaryEdgeCount:o,nonManifoldEdgeCount:s,triangleCount:n}}l(w1,"analyzeMeshTopology");async function v1(){const e={scene:new M.THREE.Scene,getObjectByName(i){return this.scene.getObjectByName(i)}},t=new M.Cube({x:4,y:4,z:4,name:"REVOLVE_SRC"});t.visualize(),e.scene.add(t);const n=t.children.find(i=>i.type==="FACE"&&/_PZ$/.test(i.name)),r=n?.edges?.[0]||null;if(!n||!r)throw new Error("Failed to create source face/edge fixtures for revolve feature test.");const a=new Ts;a.inputParams={profile:n.name,axis:r.name,angle:34,resolution:64,featureID:"REVOLVE_FEATURE_TEST",boolean:{operation:"UNION",targets:[t]}};const o=await a.run(e);if(!(Array.isArray(o?.added)?o.added:[]).length)throw new Error("Expected revolve feature to resolve string face/edge references and produce a result.")}l(v1,"test_revolve_feature_resolves_face_and_edge_string_references");async function b1(){const e=new M.Cube({x:4,y:4,z:4,name:"REVOLVE_VIS_SRC"});e.visualize();const t=e.children.find(i=>i.type==="FACE"&&/_PZ$/.test(i.name)),n=t?.edges?.[0]||null;if(!t||!n)throw new Error("Failed to create source face/edge fixtures for revolve visualization test.");const r=new M.Revolve({face:t,axis:n,angle:360,resolution:8,name:"REVOLVE_VIS_TEST"});if(!Array.isArray(r._triIDs)||r._triIDs.length===0)throw new Error("Expected revolve to produce authored triangles.");const a=r.getFaces(!1);if(!Array.isArray(a)||a.length===0)throw new Error("Expected axis-edge revolve to produce native queryable faces.");for(const i of a)if(!Array.isArray(i.triangles)||i.triangles.length===0)throw new Error(`Native revolve face ${i.faceName||"UNKNOWN"} has no triangles.`);r.visualize();const o=r.children.filter(i=>i.type==="FACE");if(o.length!==a.length)throw new Error(`Expected rendered revolve face count to match native faces. Native=${a.length}, Rendered=${o.length}.`);const s=r.volume();if(!(s>0))throw new Error(`Expected axis-edge revolve to have positive manifold volume. Volume=${s}.`)}l(b1,"test_revolve_generates_manifold_native_faces_for_axis_edge_profile");async function F1(){const e=M.THREE,t=[[-2,-2,0],[2,-2,0],[2,2,0],[-2,2,0],[-1,-1,0],[1,-1,0],[1,1,0],[-1,1,0]],n=[[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],r=[];for(const d of n)for(const u of d)r.push(...t[u]);const a=new e.BufferGeometry;a.setAttribute("position",new e.Float32BufferAttribute(r,3)),a.computeVertexNormals();const o=new M.Face(a);o.updateMatrixWorld?.(!0);const s=As(o),i=s.filter(d=>!d.isHole).length,c=s.filter(d=>d.isHole).length;if(i!==1||c!==1)throw new Error(`Expected recovered annular profile to have one outer loop and one hole. Outer=${i}, Holes=${c}.`)}l(F1,"test_revolve_face_profile_boundary_recovery_marks_inner_loop_as_hole");async function P1(){const e=M.THREE,t=[[0,0,0],[8.905728,14.930946,0],[-10.96543,26.783322,0],[-19.87116,11.852382,0]],n=[...t[0],...t[1],...t[2],...t[0],...t[2],...t[3]],r=new e.BufferGeometry;r.setAttribute("position",new e.Float32BufferAttribute(n,3)),r.computeVertexNormals();const a=new M.Face(r);a.name="REVOLVE_AXIS_EDGE_PROFILE",a.userData.boundaryLoopsWorld=[{pts:t,isHole:!1}],a.updateMatrixWorld?.(!0);const o=new e.BufferGeometry;o.setAttribute("position",new e.Float32BufferAttribute([...t[0],...t[3]],3));const s=new e.Line(o);s.name="REVOLVE_AXIS_EDGE",s.type="EDGE",s.updateMatrixWorld?.(!0);const i=new M.Revolve({face:a,axis:s,angle:144,resolution:64,name:"REVOLVE_AXIS_EDGE_PARTIAL_TEST"}),c=w1(i);if(c.boundaryEdgeCount||c.nonManifoldEdgeCount)throw new Error(`Expected partial revolve around a profile edge to be closed and manifold. Boundaries=${c.boundaryEdgeCount}, nonManifold=${c.nonManifoldEdgeCount}, triangles=${c.triangleCount}.`);if(typeof i._isCoherentlyOrientedManifold=="function"&&i._isCoherentlyOrientedManifold()!==!0)throw new Error("Expected partial revolve around a profile edge to be coherently oriented.")}l(P1,"test_revolve_axis_edge_profile_reuses_axis_vertices_for_partial_sweep");async function A1(e=new Y){e.expressions="resolution = 32;";const t=await e.newFeature("S");Object.assign(t.inputParams,{id:"S1",sketchPlane:null,curveResolution:"resolution"}),t.persistentData={sketch:{points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:0,y:0,fixed:!1,construction:!1,externalReference:!1},{id:2,x:3,y:0,fixed:!1,construction:!1,externalReference:!1},{id:3,x:3,y:0,fixed:!1,construction:!1,externalReference:!1},{id:4,x:3,y:4,fixed:!1,construction:!1,externalReference:!1},{id:5,x:3,y:4,fixed:!1,construction:!1,externalReference:!1},{id:6,x:0,y:4,fixed:!1,construction:!1,externalReference:!1},{id:7,x:0,y:4,fixed:!1,construction:!1,externalReference:!1},{id:8,x:0,y:0,fixed:!1,construction:!1,externalReference:!1}],geometries:[{id:1,type:"line",points:[1,2],construction:!1},{id:2,type:"line",points:[3,4],construction:!1},{id:3,type:"line",points:[5,6],construction:!1},{id:4,type:"line",points:[7,8],construction:!1}],constraints:[{id:1,type:"≡",points:[2,3]},{id:2,type:"≡",points:[4,5]},{id:3,type:"≡",points:[6,7]},{id:4,type:"≡",points:[8,1]}]}};const n=await e.newFeature("R");Object.assign(n.inputParams,{id:"R2",profile:"S1",consumeProfileSketch:!0,axis:"S1:G4",angle:120,resolution:"resolution",boolean:{targets:[],operation:"NONE",overlapConditioningEnabled:!0}});const r=l(a=>{const o=e.getObjectByName("R2");if(!o)throw new Error(`${a} Expected revolve output R2.`);const s=typeof o.getFaceNames=="function"?o.getFaceNames():[];for(const i of["S1:G1_RV","S1:G2_RV","S1:G3_RV"])if(!s.includes(i))throw new Error(`${a} Missing revolve sidewall ${i}. Faces: ${s.join(", ")}`);if(s.some(i=>i==="S1:PROFILE_RV"||i==="R2:S1:PROFILE_RV"))throw new Error(`${a} Revolve sidewalls collapsed to profile-level face. Faces: ${s.join(", ")}`)},"assertEdgeSidewalls");return await e.runHistory({throwOnFeatureError:!0}),r("[revolve restored sketch initial]"),n.inputParams.angle=180,await e.runHistory({throwOnFeatureError:!0}),r("[revolve restored sketch angle edit]"),console.log("✓ Revolve keeps edge side wall faces after editing a consumed sketch profile"),e}l(A1,"test_revolve_restored_consumed_sketch_keeps_edge_sidewalls_after_angle_edit");const T1="src/tests/importTestingData/import_test.stl";function C1(e){const t=Array.isArray(e?._triVerts)?e._triVerts:[],n=t.length/3|0,r=new Map,a=l((i,c)=>i<c?`${i}|${c}`:`${c}|${i}`,"edgeKey");for(let i=0;i<n;i+=1){const c=t[i*3+0]>>>0,d=t[i*3+1]>>>0,u=t[i*3+2]>>>0;for(const[f,p]of[[c,d],[d,u],[u,c]]){const _=a(f,p);r.set(_,(r.get(_)||0)+1)}}let o=0,s=0;for(const i of r.values())i===1?o+=1:i!==2&&(s+=1);return{boundaryEdgeCount:o,nonManifoldEdgeCount:s}}l(C1,"analyzeSolidTopology");function N1(e,t){const n=C1(e);if(n.boundaryEdgeCount||n.nonManifoldEdgeCount)throw new Error(`[${t}] Expected closed manifold result. Boundary edges=${n.boundaryEdgeCount}, non-manifold edges=${n.nonManifoldEdgeCount}.`);if(typeof e?._isCoherentlyOrientedManifold=="function"&&e._isCoherentlyOrientedManifold()!==!0)throw new Error(`[${t}] Expected coherently oriented manifold result.`)}l(N1,"assertClosedManifold");async function R1(){const e=[],t={type:"SOLID",simplify(c){return e.push(["simplify",c]),this},_weldVerticesByEpsilon(c,d){return e.push(["weld",c,d?.rebuildManifold]),this},fixTriangleWindingsByAdjacency(){return e.push(["fixWindings"]),this},visualize(){e.push(["visualize"])}},n={type:"SOLID",name:"REMESH_SRC",clone(){return e.push(["clone"]),t}},r={scene:{async getObjectByName(c){return c==="REMESH_SRC"?n:null}}},a=new Cs;a.inputParams={targetSolid:"REMESH_SRC",mode:"Simplify",tolerance:.05};const o=await a.run(r);if(!Array.isArray(o?.added)||o.added[0]!==t)throw new Error("Expected remesh simplify feature to return the cloned output solid.");if(!Array.isArray(o?.removed)||o.removed[0]!==n)throw new Error("Expected remesh simplify feature to mark the source solid for removal.");const s=e.map(c=>{const[d,u,f]=c;return d==="weld"?`${d}:${u}:${String(f)}`:u===void 0?d:`${d}:${u}`}),i=["clone","fixWindings","simplify:0.05","visualize"];if(s.join("|")!==i.join("|"))throw new Error(`Expected remesh simplify to use kernel simplify without full-tolerance weld; received ${s.join("|")}.`)}l(R1,"test_remesh_simplify_uses_kernel_simplify_without_full_tolerance_weld");async function I1(e){const t=await j.promises.readFile(T1,"utf8"),n=await e.newFeature("IMPORT3D");Object.assign(n.inputParams,{id:"REMESH_IMPORT_FIXTURE_SOURCE",featureID:"REMESH_IMPORT_FIXTURE_SOURCE",fileToImport:t,centerMesh:!0,deflectionAngle:8,decimationLevel:100,meshRepairLevel:"NONE",extractMultipleSolids:!1,extractPlanarFaces:!0,planarFaceMinAreaPercent:1,segmentAnalyticPrimitives:!1});const r=await e.newFeature("RM");return r.inputParams.targetSolid="REMESH_IMPORT_FIXTURE_SOURCE",r.inputParams.mode="Simplify",r.inputParams.tolerance=.02,e}l(I1,"test_remesh_simplify_imported_fixture_stl");async function O1(e){const n=(e.scene?.children||[]).filter(a=>a?.type==="SOLID").find(a=>String(a?.name||"")==="(REMESH_IMPORT_FIXTURE_SOURCE)");if(!n)throw new Error("[remesh imported fixture] Expected remeshed imported solid.");const r=Math.floor((Array.isArray(n._triVerts)?n._triVerts.length:0)/3);if(!(r>0&&r<17228))throw new Error(`[remesh imported fixture] Expected simplified triangle count below 17228, got ${r}.`);N1(n,"remesh imported fixture")}l(O1,"afterRun_remesh_simplify_imported_fixture_stl");async function D1(){if(!Qa())return;const e=new Sr({radius:1,height:2,resolution:64,name:"SIMPLIFY_CYL"}),t=e.getTriangleCount(),n=e.simplify(.1),r=n.getTriangleCount();if(!(r>0&&r<t))throw new Error(`Expected simplify to reduce triangle count from ${t}; got ${r}.`);const a=new Set(n.getFaceNames());for(const s of["SIMPLIFY_CYL_B","SIMPLIFY_CYL_T","SIMPLIFY_CYL_S"])if(!a.has(s))throw new Error(`Expected simplified cylinder to preserve face tag "${s}".`);const o=n.getFaceMetadata("SIMPLIFY_CYL_S");if(o?.type!=="cylindrical"||Math.abs((o?.radius||0)-1)>1e-9)throw new Error("Expected simplified cylinder to preserve side-face metadata.")}l(D1,"test_solid_simplify_preserves_face_tags_and_metadata");function M1(e,t,n,r,a=100){return{points:[{id:0,x:e,y:t,fixed:!0},{id:1,x:n,y:t,fixed:!1},{id:2,x:n,y:r,fixed:!1},{id:3,x:e,y:r,fixed:!1}],geometries:[{id:a+0,type:"line",points:[0,1],construction:!1},{id:a+1,type:"line",points:[1,2],construction:!1},{id:a+2,type:"line",points:[2,3],construction:!1},{id:a+3,type:"line",points:[3,0],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]}}l(M1,"makeRectSketch");async function k1(e){const t=await e.newFeature("P.CY");Object.assign(t.inputParams,{id:"P.CY1",radius:"4",height:10,resolution:64,transform:{position:[0,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},boolean:{targets:[],operation:"NONE"}});const n=await e.newFeature("S");Object.assign(n.inputParams,{id:"S5",sketchPlane:"P.CY1_T",curveResolution:32}),n.persistentData={sketch:M1(4,-2,7,2,200)};const r=await e.newFeature("E");Object.assign(r.inputParams,{id:"E6",profile:"S5:PROFILE",distance:"5",distanceBack:"4",boolean:{targets:["P.CY1"],operation:"UNION",overlapConditioningEnabled:!0},consumeProfileSketch:!0}),await e.runHistory();const a=e.getObjectByName("P.CY1");if(!a)throw new Error("Expected extrude boolean target solid to exist.");a.visualize();const o=e.getObjectByName("E6:S5:PROFILE_END");if(!o)throw new Error("Expected post-union face reference E6:S5:PROFILE_END to resolve before revolve.");const s=Array.isArray(o.edges)?o.edges[0]:null;if(!s?.name)throw new Error("Expected a boundary edge on the resolved extrude end face.");const i=a.volume(),c=await e.newFeature("R");Object.assign(c.inputParams,{id:"R9",profile:"E6:S5:PROFILE_END",axis:s.name,angle:34,resolution:"128",boolean:{targets:["P.CY1"],operation:"UNION",overlapConditioningEnabled:!1}}),await e.runHistory();const d=e.getObjectByName("P.CY1");if(!d)throw new Error("Expected final boolean target solid to exist after revolve.");const u=d.volume();if(!(u>i+1e-6))throw new Error(`Expected revolve union to add volume. Before=${i}, After=${u}.`);if(!d.getFaceNames().some(p=>String(p||"").includes("_RV")))throw new Error("Expected final solid to retain revolve side-wall face names.")}l(k1,"test_revolve_after_union_preserves_face_reference_resolution");function $1(e,t){return(e?.scene?.children||[]).filter(r=>r?.type==="SOLID").find(r=>String(r?.name||"")===String(t))||null}l($1,"getSolidByName");function L1(e){return/^FACE(?:_\d+)?$/.test(String(e||""))||/_REPAIR_\d+$/.test(String(e||""))}l(L1,"isSyntheticFaceName");async function B1(e){const t=await e.newFeature("P.CU");Object.assign(t.inputParams,{id:"P.CU1",sizeX:14,sizeY:10,sizeZ:8,transform:{position:[0,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},boolean:{targets:[],operation:"NONE"}});const n=await e.newFeature("P.CY");Object.assign(n.inputParams,{id:"P.CY2",radius:3,height:12,resolution:64,transform:{position:[0,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},boolean:{targets:["P.CU1"],operation:"UNION",overlapConditioningEnabled:!0}})}l(B1,"test_primitive_boolean_union_preserves_face_grouping");async function G1(e){const t=$1(e,"P.CU1");if(!t)throw new Error("[primitive_boolean_union_preserves_face_grouping] Expected final solid P.CU1 to exist.");const n=(t.getFaceNames?.()||[]).map(o=>String(o||"")),r=n.filter(L1);if(r.length>0)throw new Error(`[primitive_boolean_union_preserves_face_grouping] Expected native primitive union to avoid fallback face labels, found ${r.join(", ")}.`);const a=["P.CU1_NX","P.CU1_NY","P.CU1_NZ","P.CU1_PX","P.CU1_PY","P.CU1_PZ","P.CY2_B","P.CY2_T","P.CY2_S"];for(const o of a)if(!n.includes(o))throw new Error(`[primitive_boolean_union_preserves_face_grouping] Missing expected face ${o}. Faces: ${n.join(", ")}`)}l(G1,"afterRun_primitive_boolean_union_preserves_face_grouping");const Uo=typeof process<"u"&&process.versions&&process.versions.node&&typeof window>"u",W1=Ie.join("tests","test-run.log.md"),j1=1;function bn(e){return e?.test?.name&&String(e.test.name)||"unnamed_test"}l(bn,"getTestName");function V1(e=[]){const t=e.slice(2);for(let n=0;n<t.length;n+=1){const r=t[n];if(r==="--test"||r==="-t")return t[n+1]?String(t[n+1]):"";if(r.startsWith("--test="))return r.slice(7);if(!r.startsWith("-"))return r}return null}l(V1,"getCliRequestedTestName");function U1(e,t){if(t==null)return e;if(!t)throw new Error("Missing test name. Use `pnpm test -- <test_name>` or `pnpm test -- --test <test_name>`.");const n=e.filter(s=>bn(s)===t);if(n.length>0)return n;const a=e.map(bn).sort().filter(s=>s.includes(t)).slice(0,10),o=a.length?`
1940
+ `;function P(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(P,"assert$g");async function np(){const e={type:"SOLID",owningFeatureID:"BODY_OWNER",getFaceMetadata(u){return u==="FACE_FROM_META"?{sourceFeatureId:"FACE_OWNER"}:null},getEdgeMetadata(u){return u==="EDGE_FROM_META"?{sourceFeatureId:"EDGE_OWNER"}:null}},t={type:"FACE",name:"FACE_FROM_META",parentSolid:e,parent:e},n={type:"EDGE",name:"EDGE_FROM_META",parentSolid:e,parent:e},r={type:"FACE",name:"FACE_FALLBACK",parentSolid:e,parent:e},a={type:"EDGE",userData:{splineFeatureId:"SP_001"}},o={type:"LINE2",userData:{},parent:a},i={type:"EDGE",name:"SK_001:G5",userData:{},parent:{type:"SKETCH",name:"SK_001",userData:{sketchFeatureId:"SK_001"}}},d={type:"FACE",name:"OF_001:FACE_A:PROFILE",userData:{},parent:{type:"SKETCH",name:"OF_001:FACE_A",userData:{sketchFeatureId:"OF_001"}}};P(Wn(t)==="FACE_OWNER","Face metadata owner should win."),P(Wn(n)==="EDGE_OWNER","Edge metadata owner should use precise edge metadata."),P(Wn(r)==null,"Faces without precise provenance should not fall back to solid owner."),P(Kr(a)==="SP_001","Spline owner should resolve from spline metadata."),P(Kr(o)==="SP_001","Spline owner should resolve through parent geometry."),P(Jr(i)==="SK_001","Sketch owner should resolve through sketch group metadata."),P(Jr(d)==="OF_001","Sketch-like owner should resolve from group metadata."),P(qo([{object:t}])==="FACE_OWNER","Single-selection resolution should unwrap selection objects."),P(Qo([{object:o}])==="SP_001","Spline selection resolution should unwrap selection objects."),P(es([{object:i}])==="SK_001","Sketch-like selection resolution should unwrap selection objects."),P(jn([{object:t}],["FACE"])===!0,"Single face selection should match FACE."),P(Zr([{object:a}])===!0,"Single spline selection should match spline helper."),P(ts([{object:d}])===!0,"Single sketch-like selection should match sketch-like helper."),P(jn([{object:n}],["FACE","PLANE"])===!1,"Edge selection should not match the face-only toolbar filter."),P(Zr([{object:a},{object:n}])===!1,"Multiple selections should not match spline helper."),P(jn([{object:t},{object:n}],["FACE","EDGE"])===!1,"Multiple selections should not match.")}l(np,"test_selection_owning_feature_resolution");async function rp(){const e=typeof globalThis.window<"u",t=globalThis.window;e||(globalThis.window={DEBUG_MODE:!1});let n;try{({selectionMethods:n}=await ai(()=>import("./main-cad-BckkeW6Q.js").then(i=>i.M),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12])))}finally{if(e)globalThis.window=t;else try{delete globalThis.window}catch{globalThis.window=void 0}}const r={linewidth:3},a={isLine2:!0,material:r},o={renderer:{domElement:{clientWidth:640,clientHeight:480,getBoundingClientRect:l(()=>({width:640,height:480}),"getBoundingClientRect")}},scene:{traverse(i){i(a)}}};o._syncLineMaterialResolutionForPicking=n._syncLineMaterialResolutionForPicking,n._syncLineMaterialResolutionForPicking.call(o),P(r.resolution,"Expected Line2 material to receive a resolution before raycasting."),P(r.resolution.width===640,`Expected repaired width 640, got ${r.resolution.width}`),P(r.resolution.height===480,`Expected repaired height 480, got ${r.resolution.height}`),delete r.resolution;let s=!1;n._withDoubleSidedPicking.call(o,()=>(s=!!r.resolution,[])),P(s,"Expected picking wrapper to repair Line2 material resolution before raycasting.")}l(rp,"test_selection_line2_resolution_repair");async function ap(){let e=null;const t={type:"FakeMaterial",color:{set(){}},clone(){return e={type:"FakeHoverMaterial",color:{set(){}},disposed:!1,dispose(){this.disposed=!0}},e}},n={type:"EDGE",name:"hover-restore-edge",material:t,userData:{}};ne.attach(n),n.hovered=!0,P(e,"Expected hover to create a temporary material."),P(n.material===e,"Expected hover material to be assigned while hovered."),ne._clearHover(n),P(n.material===t,"Expected base material to be restored before hover material disposal."),P(e.disposed===!0,"Expected temporary hover material to be disposed after restore.")}l(ap,"test_selection_hover_material_restores_before_dispose");async function op(){let e="#00009e",t=null;const n={type:"SharedFaceMaterial",isMaterial:!0,color:{set(o){e=o},getHex(){return e}},clone(){let o=e;return t={type:"HoverFaceMaterial",isMaterial:!0,color:{set(s){o=s},getHex(){return o}},disposed:!1,dispose(){this.disposed=!0},get currentColor(){return o}},t},get currentColor(){return e}},r={type:"FACE",name:"E2:S1:PROFILE_END_START",material:n,userData:{}},a={type:"FACE",name:"E2:S1:G2_SW_END",material:n,userData:{}};ne.attach(r),ne.attach(a),r.hovered=!0,P(t,"Expected solid face hover to create a temporary material."),P(r.material===t,"Expected profile-named solid face hover to assign only the temporary material."),P(a.material===n,"Expected sibling face to keep the shared base material."),P(n.currentColor==="#00009e",`Expected shared face material color to remain unchanged, got ${n.currentColor}.`),P(t.currentColor===ne.hoverColor,`Expected hover material color ${ne.hoverColor}, got ${t.currentColor}.`),r.hovered=!1,P(r.material===n,"Expected profile-named solid face hover clear to restore the base material."),P(t.disposed===!0,"Expected profile-named solid face hover material to be disposed.")}l(op,"test_selection_profile_named_solid_face_hover_does_not_tint_shared_face_material");async function sp(){const e=l((s,i)=>{let c=s;return{type:i,needsUpdate:!1,color:{set(u){c=u},getHex(){return c}},clone(){throw new Error("Sketch hover should not clone/replace materials.")},get currentColor(){return c}}},"makeSketchMaterial"),t=e("#009dff","FakeSketchLineMaterial"),n=e("#00009e","FakeSketchFaceMaterial"),a={type:"FACE",name:"S1:PROFILE",material:n,userData:{__baseMaterial:{type:"MeshStandardMaterial",color:158},__defaultMaterial:{type:"MeshStandardMaterial",color:158}},parent:{type:"SKETCH",userData:{sketchFeatureId:"S1"}}},o={type:"EDGE",name:"S1:G100",material:t,userData:{sketchFeatureId:"S1",sketchGeometryId:100,__baseMaterial:{type:"LineMaterial",color:40447},__defaultMaterial:{type:"LineMaterial",color:40447}}};ne.attach(o),P(o.userData.__baseMaterial===t,"Expected cloned plain edge base material to be replaced with the live material."),o.hovered=!0,P(o.material===t,"Expected sketch edge hover to keep the same material object."),P(t.currentColor===ne.hoverColor,`Expected edge hover color ${ne.hoverColor}, got ${t.currentColor}`),P(t.needsUpdate===!0,"Expected edge hover tint to mark material for update."),o.hovered=!1,P(o.material===t,"Expected sketch edge hover clear to keep the same material object."),P(t.currentColor==="#009dff",`Expected sketch edge hover clear to restore original color, got ${t.currentColor}`),ne.attach(a),P(a.userData.__baseMaterial===n,"Expected cloned plain face base material to be replaced with the live material."),a.hovered=!0,P(a.material===n,"Expected sketch face hover to keep the same material object."),P(n.currentColor===ne.hoverColor,`Expected face hover color ${ne.hoverColor}, got ${n.currentColor}`),a.hovered=!1,P(a.material===n,"Expected sketch face hover clear to keep the same material object."),P(n.currentColor==="#00009e",`Expected sketch face hover clear to restore original color, got ${n.currentColor}`)}l(sp,"test_selection_sketch_hover_tints_material_in_place");async function ip(){let e="#009dff";const t={needsUpdate:!1,color:{set(r){e=r},getHex(){return e}},clone(){throw new Error("SelectionFilter hover should tint sketch materials in place.")},get currentColor(){return e}},n={type:"EDGE",name:"S1:G101",uuid:"selection-filter-empty-hover-edge",material:t,userData:{sketchFeatureId:"S1",sketchGeometryId:101}};Zt.clearHover(),Zt.setHoverObjects([n],{ignoreFilter:!0}),P(n.hovered===!0,"Expected SelectionFilter to mark the sketch edge hovered."),P(t.currentColor===ne.hoverColor,`Expected sketch edge hover color ${ne.hoverColor}, got ${t.currentColor}`),Zt.setHoverObjects([],{ignoreFilter:!0}),P(n.hovered===!1,"Expected an empty hover update to clear the hovered flag."),P(t.currentColor==="#009dff",`Expected empty hover update to restore sketch material color, got ${t.currentColor}`),P(Zt._hovered.size===0,"Expected SelectionFilter hovered target set to be empty after clear.")}l(ip,"test_selection_filter_empty_hover_clears_in_place_sketch_hover");function Z(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Z,"assert$f");function lp(e,t){const n=[];for(const[o,s,i]of t)n.push(...o,...s,...i);const r=new Tn;r.setAttribute("position",new Wt(n,3)),r.computeBoundingBox(),r.computeBoundingSphere();const a=new Fr(r,new Pr);return a.type="FACE",a.name=e,a.userData={faceName:e},a}l(lp,"makeFaceMesh");function yn(e){const t=new Fe;t.type="SOLID",t.name="TEST_SOLID";for(const[n,r]of e)t.add(lp(n,r));return t.updateMatrixWorld(!0),t}l(yn,"buildSolidWithFaces");function Le(e,t,n,r,a=0){return[[[e,t,a],[n,t,a],[n,r,a]],[[e,t,a],[n,r,a],[e,r,a]]]}l(Le,"makeQuad");async function cp(){const e=yn([["FACE_A",Le(0,0,1,1,0)],["FACE_B",Le(.5,0,1.5,1,0)],["FACE_OFF_PLANE",Le(0,0,1,1,.01)]]),t=wr(e,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(t.faceCount===3,`Expected 3 planar faces, got ${t.faceCount}`),Z(t.overlaps.length===1,`Expected exactly one overlap pair, got ${t.overlaps.length}`),Z(t.overlaps[0].faceA==="FACE_A",`Expected FACE_A first, got ${t.overlaps[0].faceA}`),Z(t.overlaps[0].faceB==="FACE_B",`Expected FACE_B second, got ${t.overlaps[0].faceB}`),Z(Math.abs(t.overlaps[0].overlapArea-.5)<1e-6,`Expected overlap area close to 0.5, got ${t.overlaps[0].overlapArea}`),Z(t.highlightedFaceNames.includes("FACE_A")&&t.highlightedFaceNames.includes("FACE_B"),"Expected both overlapping faces to be highlighted."),Z(!t.highlightedFaceNames.includes("FACE_OFF_PLANE"),"Expected off-plane face to be ignored.")}l(cp,"test_solid_overlap_diagnostics_detects_coplanar_overlap");async function dp(){const e=yn([["FACE_A",Le(0,0,1,1,0)],["FACE_TOUCH_ONLY",Le(1,0,2,1,0)]]),t=wr(e,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(t.overlaps.length===0,`Expected no overlap pairs, got ${t.overlaps.length}`),Z(t.highlightedFaceNames.length===0,"Expected no highlighted faces for boundary-only contact.")}l(dp,"test_solid_overlap_diagnostics_ignores_boundary_touching_faces");async function up(){const e=yn([["A_FACE_1",Le(0,0,1,1,0)],["A_FACE_2",Le(2,0,3,1,0)]]);e.name="SOLID_A";const t=yn([["B_FACE_1",Le(.5,0,1.5,1,0)],["B_FACE_2",Le(5,0,6,1,0)]]);t.name="SOLID_B";const n=wr(e,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(n.overlaps.length===0,"Single-solid analysis should not report cross-solid pairs.");const r=Ps(e,t,{normalToleranceDeg:.5,planeDistanceTolerance:1e-5,overlapAreaTolerance:1e-6});Z(r.overlaps.length===1,`Expected one cross-solid overlap pair, got ${r.overlaps.length}`),Z(r.overlaps[0].solidA==="SOLID_A",`Expected solidA label SOLID_A, got ${r.overlaps[0].solidA}`),Z(r.overlaps[0].solidB==="SOLID_B",`Expected solidB label SOLID_B, got ${r.overlaps[0].solidB}`),Z(r.overlaps[0].faceA==="A_FACE_1",`Expected A_FACE_1, got ${r.overlaps[0].faceA}`),Z(r.overlaps[0].faceB==="B_FACE_1",`Expected B_FACE_1, got ${r.overlaps[0].faceB}`),Z(Math.abs(r.overlaps[0].overlapArea-.5)<1e-6,`Expected cross-solid overlap area close to 0.5, got ${r.overlaps[0].overlapArea}`),Z(Array.isArray(r.highlightedBySolid[r.solidAKey]?.faceNames)&&r.highlightedBySolid[r.solidAKey].faceNames.includes("A_FACE_1"),"Expected SOLID_A highlight set to include A_FACE_1."),Z(Array.isArray(r.highlightedBySolid[r.solidBKey]?.faceNames)&&r.highlightedBySolid[r.solidBKey].faceNames.includes("B_FACE_1"),"Expected SOLID_B highlight set to include B_FACE_1.")}l(up,"test_solid_overlap_diagnostics_detects_cross_solid_overlap");function Vo(){return{points:[{id:10,x:-5,y:-5,fixed:!1},{id:11,x:5,y:-5,fixed:!1},{id:12,x:5,y:5,fixed:!1},{id:13,x:-5,y:5,fixed:!1},{id:20,x:-3,y:-3,fixed:!1},{id:21,x:3,y:-3,fixed:!1},{id:22,x:3,y:3,fixed:!1},{id:23,x:-3,y:3,fixed:!1}],geometries:[{id:200,type:"line",points:[10,11],construction:!1},{id:201,type:"line",points:[11,12],construction:!1},{id:202,type:"line",points:[12,13],construction:!1},{id:203,type:"line",points:[13,10],construction:!1},{id:210,type:"line",points:[20,21],construction:!1},{id:211,type:"line",points:[21,22],construction:!1},{id:212,type:"line",points:[22,23],construction:!1},{id:213,type:"line",points:[23,20],construction:!1}],constraints:[]}}l(Vo,"makeCenteredRingSketch");function hr(e,t){let n=0,r=0;const a=Array.isArray(e)?e:[];for(const o of a){const s=t==="x"?[-o[0],o[1],o[2]]:[o[0],-o[1],o[2]];let i=1/0;for(const c of a){const d=Math.hypot(c[0]-s[0],c[1]-s[1],c[2]-s[2]);d<i&&(i=d)}i>n&&(n=i),r+=i}return{max:n,mean:a.length?r/a.length:0}}l(hr,"nearestMirrorError");async function fp(e){const t=await e.newFeature("P.CY");t.inputParams.id="SMOOTH_SRC",t.inputParams.radius=5,t.inputParams.height=12,t.inputParams.resolution=16;const n=await e.newFeature("SWS");return n.inputParams.targetSolid=t.inputParams.featureID,n.inputParams.subdivisionLoops=1,e}l(fp,"test_smooth_with_subdivision_replaces_source_solid");async function pp(e){const t=(e.features||[]).find(d=>String(d?.type||"").toUpperCase()==="SWS");if(!t)throw new Error("[smooth with subdivision] Feature entry was not created.");const n=t.persistentData||{};if(!(Number(n.sourceTriangleCount)>0))throw new Error("[smooth with subdivision] Source triangle count was not captured.");if(!(Number(n.outputTriangleCount)>Number(n.sourceTriangleCount)))throw new Error("[smooth with subdivision] Expected subdivision to increase triangle count.");const r=(e.scene?.children||[]).filter(d=>d?.type==="SOLID");if(r.length!==1)throw new Error(`[smooth with subdivision] Expected one replacement solid, found ${r.length}.`);const a=r[0],o=a?.userData?.smoothWithSubdivision||null;if(!o)throw new Error("[smooth with subdivision] Output solid is missing feature metadata.");if(Number(o.subdivisionLoops)!==1)throw new Error("[smooth with subdivision] Output solid metadata has the wrong subdivision loop count.");if(!(Number(o.outputTriangleCount)>Number(o.sourceTriangleCount)))throw new Error("[smooth with subdivision] Output solid metadata did not record increased triangle count.");const s=new Set(["SMOOTH_SRC_B","SMOOTH_SRC_T","SMOOTH_SRC_S"]),i=new Set((typeof a.getFaceNames=="function"?a.getFaceNames():[]).map(d=>String(d||"").trim()).filter(d=>d.length>0));if(i.size!==s.size)throw new Error(`[smooth with subdivision] Expected ${s.size} retained face names, found ${i.size}.`);for(const d of s)if(!i.has(d))throw new Error(`[smooth with subdivision] Missing retained face name "${d}".`);const c=typeof a.getFaceMetadata=="function"?a.getFaceMetadata("SMOOTH_SRC_S"):null;if(!c||c.type!=="cylindrical")throw new Error("[smooth with subdivision] Cylindrical side face metadata was not preserved.");if(Number(c.radius)!==5||Number(c.height)!==12)throw new Error("[smooth with subdivision] Cylindrical side face metadata has the wrong dimensions.")}l(pp,"afterRun_smooth_with_subdivision_replaces_source_solid");async function _p(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch=Vo();const r=await e.newFeature("E");r.inputParams.profile=n.inputParams.featureID,r.inputParams.consumeProfileSketch=!1,r.inputParams.distance=6;const a=await e.newFeature("SWS");return a.inputParams.targetSolid=r.inputParams.featureID,a.inputParams.subdivisionLoops=1,e}l(_p,"test_smooth_with_subdivision_preserves_centered_ring_symmetry");async function hp(e){const t=(e.features||[]).find(c=>c?.type==="E");if(!t?.inputParams?.featureID)throw new Error("[smooth with subdivision symmetry] Missing extrude feature.");const n=e.scene.getObjectByName(t.inputParams.featureID);if(!n||typeof n.getMesh!="function")throw new Error("[smooth with subdivision symmetry] Smoothed solid missing from scene.");const r=n.getMesh(),a=[];try{for(let c=0;c<r.vertProperties.length;c+=3)a.push([r.vertProperties[c+0],r.vertProperties[c+1],r.vertProperties[c+2]])}finally{try{r?.delete?.()}catch{}}const o=hr(a,"x"),s=hr(a,"y"),i=1e-5;if(o.max>i||s.max>i)throw new Error(`[smooth with subdivision symmetry] Expected centered ring symmetry. mirrorX.max=${o.max}, mirrorY.max=${s.max}`)}l(hp,"afterRun_smooth_with_subdivision_preserves_centered_ring_symmetry");async function mp(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch=Vo();const r=await e.newFeature("E");r.inputParams.profile=n.inputParams.featureID,r.inputParams.consumeProfileSketch=!1,r.inputParams.distance=6;const a=await e.newFeature("P.CU");a.inputParams.sizeX=20,a.inputParams.sizeY=20,a.inputParams.sizeZ=20,a.inputParams.transform={position:[-20,-10,-10],rotationEuler:[0,0,0],scale:[1,1,1]};const o=await e.newFeature("B");o.inputParams.targetSolid=r.inputParams.featureID,o.inputParams.boolean={operation:"SUBTRACT",targets:[a.inputParams.featureID]};const s=await e.newFeature("P");s.inputParams.orientation="YZ";const i=await e.newFeature("M");i.inputParams.solids=[r.inputParams.featureID],i.inputParams.mirrorPlane=s.inputParams.featureID;const c=await e.newFeature("B");c.inputParams.targetSolid=r.inputParams.featureID,c.inputParams.boolean={operation:"UNION",targets:[`${i.inputParams.featureID}:${r.inputParams.featureID}:M`]};const d=await e.newFeature("SWS");return d.inputParams.targetSolid=r.inputParams.featureID,d.inputParams.subdivisionLoops=1,e}l(mp,"test_smooth_with_subdivision_preserves_mirrored_union_symmetry");async function gp(e){const t=(e.features||[]).find(i=>i?.type==="E");if(!t?.inputParams?.featureID)throw new Error("[smooth with subdivision mirrored symmetry] Missing extrude feature.");const n=e.scene.getObjectByName(t.inputParams.featureID);if(!n||typeof n.getMesh!="function")throw new Error("[smooth with subdivision mirrored symmetry] Smoothed mirrored-union solid missing.");const r=n.getMesh(),a=[];try{for(let i=0;i<r.vertProperties.length;i+=3)a.push([r.vertProperties[i+0],r.vertProperties[i+1],r.vertProperties[i+2]])}finally{try{r?.delete?.()}catch{}}const o=hr(a,"x");if(o.max>1e-5)throw new Error(`[smooth with subdivision mirrored symmetry] Expected mirrored-union symmetry. mirrorX.max=${o.max}`)}l(gp,"afterRun_smooth_with_subdivision_preserves_mirrored_union_symmetry");async function xp(e){const t=await e.newFeature("P.CO");t.inputParams.radiusTop=3,t.inputParams.radiusBottom=.5,t.inputParams.height=5.2,t.inputParams.resolution=20;const n=await e.newFeature("P");n.inputParams.orientation="YZ";const r=await e.newFeature("S");r.inputParams.sketchPlane=n.inputParams.featureID,r.persistentData.sketch={points:[{id:0,x:0,y:0,fixed:!0},{id:1,x:8,y:20,fixed:!1},{id:10,x:-.5,y:-.5,fixed:!1},{id:11,x:.5,y:-.5,fixed:!1},{id:12,x:.5,y:.5,fixed:!1},{id:13,x:-.5,y:.5,fixed:!1}],geometries:[{id:100,type:"line",points:[0,1],construction:!1},{id:200,type:"line",points:[10,11],construction:!1},{id:201,type:"line",points:[11,12],construction:!1},{id:202,type:"line",points:[12,13],construction:!1},{id:203,type:"line",points:[13,10],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]};const a=await e.newFeature("SW");a.inputParams.profile=`${t.inputParams.featureID}_T`,a.inputParams.path=[`${r.inputParams.featureID}:G100`],a.inputParams.orientationMode="translate";const o=await e.newFeature("B");return o.inputParams.targetSolid=t.inputParams.featureID,o.inputParams.boolean={targets:[a.inputParams.featureID],operation:"UNION"},e}l(xp,"test_SweepFace");async function Ep(e){const t=await e.newFeature("P");t.inputParams.orientation="YZ";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch={points:[{id:10,x:-5,y:-5,fixed:!1},{id:11,x:5,y:-5,fixed:!1},{id:12,x:5,y:5,fixed:!1},{id:13,x:-5,y:5,fixed:!1},{id:20,x:-3,y:-3,fixed:!1},{id:21,x:3,y:-3,fixed:!1},{id:22,x:3,y:3,fixed:!1},{id:23,x:-3,y:3,fixed:!1},{id:30,x:-1,y:-1,fixed:!1},{id:31,x:1,y:-1,fixed:!1},{id:32,x:1,y:1,fixed:!1},{id:33,x:-1,y:1,fixed:!1}],geometries:[{id:200,type:"line",points:[10,11],construction:!1},{id:201,type:"line",points:[11,12],construction:!1},{id:202,type:"line",points:[12,13],construction:!1},{id:203,type:"line",points:[13,10],construction:!1},{id:210,type:"line",points:[20,21],construction:!1},{id:211,type:"line",points:[21,22],construction:!1},{id:212,type:"line",points:[22,23],construction:!1},{id:213,type:"line",points:[23,20],construction:!1},{id:220,type:"line",points:[30,31],construction:!1},{id:221,type:"line",points:[31,32],construction:!1},{id:222,type:"line",points:[32,33],construction:!1},{id:223,type:"line",points:[33,30],construction:!1}],constraints:[]};const r=await e.newFeature("P");r.inputParams.orientation="XY";const a=await e.newFeature("S");a.inputParams.sketchPlane=r.inputParams.featureID,a.persistentData.sketch={points:[{id:0,x:0,y:0,fixed:!0},{id:1,x:12,y:0,fixed:!1}],geometries:[{id:100,type:"line",points:[0,1],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]};const o=await e.newFeature("SW");return o.inputParams.profile=n.inputParams.featureID,o.inputParams.path=[`${a.inputParams.featureID}:G100`],o.inputParams.orientationMode="pathAlign",o.inputParams.consumeProfileSketch=!1,e}l(Ep,"test_SweepFace_pathAlign_multi_loop_islands");async function yp(e){const t=(e?.features||[]).find(c=>String(c?.type||"").toUpperCase()==="SW"),n=Number(t?.persistentData?.profileIslandCount)||0,r=Array.isArray(t?.persistentData?.profileIslandEdgeCounts)?t.persistentData.profileIslandEdgeCounts:[];if(n>1){if(r.length!==n)throw new Error("[sweep_path_align_multi_loop_islands] Missing per-island edge counts.");if(r.some(c=>!(Number(c)>0)))throw new Error("[sweep_path_align_multi_loop_islands] One or more profile islands lost edge data.")}const a=(e?.scene?.children||[]).filter(c=>String(c?.type||"").toUpperCase()==="SOLID");if(!a.length)throw new Error("[sweep_path_align_multi_loop_islands] Expected sweep to produce a solid.");const o=a.find(c=>String(c?.name||"").startsWith("SW"))||a[0];let s=null;try{s=o.getMesh()}catch(c){throw new Error(`[sweep_path_align_multi_loop_islands] Sweep solid is not manifold: ${c?.message||c}`)}let i=0;try{i=typeof s?.numTri=="function"?Number(s.numTri())||0:(s?.triVerts?.length||0)/3}finally{try{s&&typeof s.delete=="function"&&s.delete()}catch{}}if(!(i>0))throw new Error("[sweep_path_align_multi_loop_islands] Sweep solid has no triangles.")}l(yp,"afterRun_sweepFace_pathAlign_multi_loop_islands");const Sp=1e-6;function La(e){return(Array.isArray(e?.children)?e.children:[]).find(n=>n&&n.type==="SKETCH")||null}l(La,"findSketchGroup");function Ba(e){return e&&(Array.isArray(e.children)?e.children:[]).find(n=>n&&n.type==="FACE")||null}l(Ba,"findSketchFace");function wp(e){return e?(Array.isArray(e.children)?e.children:[]).filter(n=>n&&n.type==="EDGE"):[]}l(wp,"findSketchEdges");function ut(e,t){if(!e)throw new Error(t)}l(ut,"expectTruthy");function vp(e,t,n){if(!Number.isFinite(e)||Math.abs(e-t)>Sp)throw new Error(`${n} expected ${t}, got ${e}`)}l(vp,"expectApprox");async function bp(e){e.expressions='textLabel = "BREP";';const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("TEXT");return n.inputParams.text="textLabel",n.inputParams.textHeight=10,n.inputParams.curveResolution=12,n.inputParams.placementPlane=t.inputParams.featureID,e}l(bp,"test_textToFace");async function Fp(e){const t=Array.isArray(e.features)?e.features.find(x=>x&&x.type==="TEXT"):null;if(ut(t,"[text_to_face] No TEXT feature found"),String(t?.previouseExpressions?.text??"")!=="BREP")throw new Error("[text_to_face] Text expression did not resolve to BREP");const n=t?.persistentData?.fontFile;if(typeof n!="string"||!n.startsWith("data:"))throw new Error("[text_to_face] Missing persistentData.fontFile data URL");const r=t?.persistentData?.fontFileKey;if(typeof r!="string"||!r.startsWith("font:"))throw new Error("[text_to_face] Missing or invalid persistentData.fontFileKey");const a=La(e.scene);ut(a,"[text_to_face] No SKETCH group found");const o=Ba(a);ut(o,"[text_to_face] No FACE found on SKETCH group");const s=wp(a);if(!s.length)throw new Error("[text_to_face] No sketch edges found");const i=o?.userData?.boundaryLoopsWorld;if(!Array.isArray(i)||!i.length)throw new Error("[text_to_face] Missing boundaryLoopsWorld on face");const c=o?.userData?.profileGroups;if(!Array.isArray(c)||!c.length)throw new Error("[text_to_face] Missing profileGroups on face");const d=ne.getBaseMaterial(o)||o.material;if(!d)throw new Error("[text_to_face] Face has no material");if(d.side!==M.THREE.DoubleSide)throw new Error("[text_to_face] Face material is not DoubleSide");if(!d.polygonOffset)throw new Error("[text_to_face] Face material polygonOffset not enabled");const u=ne.getBaseMaterial(s[0])||s[0].material;if(!u)throw new Error("[text_to_face] Edge has no material");if(u.depthTest!==!1)throw new Error("[text_to_face] Edge material depthTest should be false");if(s[0].renderOrder<2)throw new Error("[text_to_face] Edge renderOrder should be elevated");try{if(typeof o.getAverageNormal=="function"){const x=o.getAverageNormal();vp(Number(x.length()),1,"[text_to_face] Face normal not normalized")}}catch{}const f="__text_to_face_removed_font_test__";t.inputParams.font=f,t.inputParams.fontFile="",t.persistentData=t.persistentData||{},t.persistentData.fontFile=n,t.persistentData.fontFileKey=`font:${f}`,await e.runHistory();const p=Array.isArray(e.features)?e.features.find(x=>x&&x.type==="TEXT"):null;if(ut(p,"[text_to_face] No TEXT feature found after persisted-font fallback run"),p?.persistentData?.fontFileKey!==`font:${f}`)throw new Error("[text_to_face] Persisted font fallback did not preserve missing font id key");if(typeof p?.persistentData?.fontFile!="string"||!p.persistentData.fontFile.startsWith("data:"))throw new Error("[text_to_face] Persisted font fallback lost font data URL");const _=La(e.scene);ut(_,"[text_to_face] No SKETCH group found after persisted-font fallback run");const h=Ba(_);ut(h,"[text_to_face] No FACE found after persisted-font fallback run")}l(Fp,"afterRun_textToFace");async function Pp(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID,n.persistentData.sketch={points:[{id:0,x:0,y:0,fixed:!0},{id:1,x:0,y:40,fixed:!1},{id:2,x:25,y:40,fixed:!1},{id:10,x:-2,y:-2,fixed:!1},{id:11,x:2,y:-2,fixed:!1},{id:12,x:2,y:2,fixed:!1},{id:13,x:-2,y:2,fixed:!1}],geometries:[{id:200,type:"line",points:[0,1],construction:!1},{id:201,type:"line",points:[1,2],construction:!1},{id:300,type:"line",points:[10,11],construction:!1},{id:301,type:"line",points:[11,12],construction:!1},{id:302,type:"line",points:[12,13],construction:!1},{id:303,type:"line",points:[13,10],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]};const r=`${n.inputParams.featureID}:`,a=await e.newFeature("TU");a.inputParams.path=[`${r}G200`,`${r}G201`],a.inputParams.radius=4,a.inputParams.innerRadius=0,a.inputParams.resolution=32;const o=await e.newFeature("TU");return o.inputParams.path=[`${r}G200`,`${r}G201`],o.inputParams.radius=5,o.inputParams.innerRadius=2,o.inputParams.resolution=48,e}l(Pp,"test_tube");async function Ap(e){const t=await e.newFeature("P");t.inputParams.orientation="XY";const n=await e.newFeature("S");n.inputParams.sketchPlane=t.inputParams.featureID;const r=6,a=20,o=[],s=[];for(let u=0;u<r;u++){const f=u/r*2*Math.PI;o.push({id:u,x:Math.cos(f)*a,y:Math.sin(f)*a,fixed:!1})}for(let u=0;u<r;u++){const f=(u+1)%r;s.push({id:200+u,type:"line",points:[u,f],construction:!1})}n.persistentData.sketch={points:o,geometries:s,constraints:[{id:0,type:"⏚",points:[0]}]};const i=`${n.inputParams.featureID}:`,c=await e.newFeature("TU");c.inputParams.path=s.map(u=>`${i}G${u.id}`),c.inputParams.radius=3,c.inputParams.innerRadius=0,c.inputParams.resolution=24;const d=await e.newFeature("TU");return d.inputParams.path=s.map(u=>`${i}G${u.id}`),d.inputParams.radius=4,d.inputParams.innerRadius=1,d.inputParams.resolution=24,d.inputParams.transform={position:[0,0,10],rotation:[0,0,0],scale:[1,1,1]},e}l(Ap,"test_tube_closedLoop");function an(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(an,"assert$e");function Tp(){const e={id:"sheet-1",name:"Instruction Sheet",elements:[{id:"table-1",type:"table"}]},t={id:"sheet-2",name:"Formboard Sheet",elements:[{id:"line-1",type:"line",groupId:"wire-harness-formboard:abc"}]};an(Xt([e],"")===null,"Expected unrelated sheets to be ignored when reusing a formboard target."),an(Xt([e,t],"")?.id==="sheet-2","Expected an existing formboard sheet to be reused."),an(Xt([e,t],"sheet-1")?.id==="sheet-2","Expected preferred non-formboard sheets to be ignored in favor of the actual formboard sheet."),an(Xt([e,t],"sheet-2")?.id==="sheet-2","Expected the preferred sheet to be reused when it already contains a formboard.")}l(Tp,"test_wire_harness_formboard_reuses_only_formboard_sheet");function xe(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(xe,"assert$d");function Ga(e,t){return{name:e,userData:{isPortRoot:!0,portData:{objectName:e,name:t,kind:"termination",point:[0,0,0],direction:[1,0,0]}}}}l(Ga,"createFakePort");async function Cp(){const e=Ga("PORT_A","Port A"),t=Ga("PORT_B","Port B"),n=new Map([[e.name,e],[t.name,t]]),r={scene:{traverse(i){i(e),i(t)},getObjectByName(i){return n.get(String(i))||null}},getObjectByName(i){return n.get(String(i))||null}},a=qr(r,{from:"Port A",to:"Port B"});xe(a.ok===!0,"Expected endpoint labels to resolve."),xe(a.fromRef==="PORT_A","Expected from endpoint to resolve to PORT_A."),xe(a.toRef==="PORT_B","Expected to endpoint to resolve to PORT_B."),xe(Array.isArray(a.portRefs)&&a.portRefs.length===2,"Expected both endpoint refs to be returned.");const o=qr(r,{from:"Port A",to:"Missing"});xe(o.ok===!1,"Expected unresolved endpoint lookup to fail."),xe(o.portRefs.length===1&&o.portRefs[0]==="PORT_A","Expected partial resolution to preserve the valid endpoint.");const s=ns(r,[{id:"WIRE1",from:"Port A",to:"Port B",diameter:1.25}]);xe(Array.isArray(s.segments)&&s.segments.length===0,"Expected payload to expose a segments array."),xe(Array.isArray(s.connections)&&s.connections.length===1,"Expected payload to expose one valid connection."),xe(s.connections[0].id==="WIRE1","Expected payload connection id to match."),xe(s.connections[0].startPoint==="PORT_A","Expected payload startPoint to use resolved port object names."),xe(s.connections[0].endPoint==="PORT_B","Expected payload endPoint to use resolved port object names."),xe(s.connections[0].wireInfo?.diameter===1.25,"Expected payload diameter to match input.")}l(Cp,"test_wire_harness_connection_endpoint_resolution");function U(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(U,"assert$c");function on(e,t,n="termination",r=[0,0,0],a=[1,0,0]){return{name:e,userData:{isPortRoot:!0,portData:{objectName:e,name:t,kind:n,point:r.slice(),direction:a.slice(),extension:1,displayLength:1}}}}l(on,"createPort$1");function Jn(e,t,n,r,a){return{type:"SP",inputParams:{featureID:e,curveResolution:4,bendRadius:1},persistentData:{spline:{points:[{id:"p0",position:[0,0,0],attachment:{type:"port",portRef:t,side:n}},{id:"p1",position:[1,0,0],attachment:{type:"port",portRef:r,side:a}}]}}}}l(Jn,"createSplineFeature$1");function Np(){const e=on("START","Start","termination",[-6,0,0],[1,0,0]),t=on("SPLIT","Split","waypoint",[0,0,0],[1,0,0]),n=on("BRANCHA","Branch A","termination",[5,4,0],[1,0,0]),r=on("BRANCHB","Branch B","termination",[5,-4,0],[1,0,0]),a=new Map([[e.name,e],[t.name,t],[n.name,n],[r.name,r]]);return{scene:{traverse(o){o(e),o(t),o(n),o(r)},getObjectByName(o){return a.get(String(o))||null}},getObjectByName(o){return a.get(String(o))||null},features:[Jn("SP1","START","A","SPLIT","A"),Jn("SP2","SPLIT","B","BRANCHA","A"),Jn("SP3","SPLIT","A","BRANCHB","A")]}}l(Np,"createSimpleHarnessPartHistory");function Rp(){const e=new An(null),t=e.createSheet({name:"Large Formboard",sizeKey:"CUSTOM",orientation:"landscape",customWidthIn:72,customHeightIn:36,elements:[]});U(t.sizeKey==="CUSTOM","Expected custom sheet size key to persist."),U(t.widthIn===72,"Expected custom sheet width to persist."),U(t.heightIn===36,"Expected custom sheet height to persist.");const n=e.updateSheet(t.id,{sizeKey:"CUSTOM",orientation:"portrait",customWidthIn:36,customHeightIn:72});U(n.sizeKey==="CUSTOM","Expected custom size key to survive sheet updates."),U(n.widthIn===36,"Expected portrait custom sheet width to persist."),U(n.heightIn===72,"Expected portrait custom sheet height to persist.")}l(Rp,"test_sheet_custom_size_persists");function Ip(){const e=Date.now;let t=1e3;Date.now=()=>t;try{const n=new An(null),r=n.createSheet({name:"Timestamp Sheet",sizeKey:"A",orientation:"landscape",elements:[]}),a=r.metadata?.createdAt,o=r.metadata?.updatedAt;U(a===1e3,"Expected sheet createdAt to use creation time."),U(o===1e3,"Expected sheet updatedAt to use creation time."),t=2e3,n.getSheets(),n.toSerializable();const s=n.getSheetById(r.id);U(s.metadata?.updatedAt===o,"Expected reading sheets not to update metadata.updatedAt."),t=3e3,n.updateSheet(r.id,{name:"Timestamp Sheet Updated"});const i=n.getSheetById(r.id);U(i.metadata?.createdAt===a,"Expected sheet updates to preserve createdAt."),U(i.metadata?.updatedAt===3e3,"Expected sheet updates to advance updatedAt.")}finally{Date.now=e}}l(Ip,"test_sheet_metadata_updated_at_is_stable_on_read");function Op(){const e=Np(),t=rs(e,{includeTitle:!0});U(t.ok===!0,"Expected harness formboard definition to succeed.");const n=t.elements.filter(u=>u?.type==="line"),r=t.elements.filter(u=>u?.type==="text");U(n.length===3,"Expected three flattened line segments for the Y harness."),U(n.every(u=>u?.formboard?.exactGeometry===!0),"Expected generated line segments to be marked as exact formboard geometry."),U(n.every(u=>u?.formboard?.fromNodeId&&u?.formboard?.toNodeId),"Expected generated line segments to carry directed node metadata."),U(r.some(u=>String(u?.text||"")==="Start"),"Expected endpoint labels to be included."),U(r.some(u=>String(u?.text||"").includes("in")),"Expected segment length labels to be included.");const a=new An(null),o=a.createSheet({name:"Instruction Sheet",sizeKey:"A",orientation:"landscape",elements:[]}),s=as(a,o.id,e,{includeTitle:!0,resizeSheetToFit:!0});U(s.ok===!0,"Expected formboard insertion to succeed."),U(s.sheet?.sizeKey==="CUSTOM","Expected insertion to promote the target sheet to custom sizing."),U((s.insertedElements||[]).filter(u=>u?.type==="line").length===3,"Expected inserted formboard to contain three line elements."),U((s.sheet?.elements||[]).filter(u=>u?.type==="line").every(u=>u?.formboard?.exactGeometry===!0),"Expected exact formboard metadata to persist through sheet normalization."),U((s.sheet?.elements||[]).every(u=>String(u?.groupId||"").startsWith("wire-harness-formboard:")),"Expected inserted sheet elements to belong to the generated formboard group.");const i=os(s.sheet?.elements||[]),c=(s.sheet?.elements||[]).find(u=>u?.type==="line"&&String(u?.formboard?.fromNodeId||"")==="SPLIT"),d=ss(i,"SPLIT",c?.id);U(d.size===1,"Expected pivot branch resolution to isolate one downstream branch."),U(d.has(String(c?.formboard?.toNodeId||"")),"Expected branch resolution to include the segment endpoint opposite the pivot.")}l(Op,"test_wire_harness_formboard_insert");function Bt(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Bt,"assert$b");function Dp(){const e=new Za(null),t=e.addView({viewName:"Sheet View",camera:{},annotations:[],viewSettings:{pmiTextSizePt:"18.5"}});Bt(t?.viewSettings?.pmiTextSizePt===18.5,"Expected PMI text size to normalize to a finite number.");const n=e.updateView(0,r=>(r.viewSettings.pmiTextSizePt=-4,r));Bt(!Object.prototype.hasOwnProperty.call(n?.viewSettings||{},"pmiTextSizePt"),"Expected invalid PMI text size to be removed during normalization.")}l(Dp,"test_pmi_view_text_size_setting_normalizes");function Mp(){const n=new Za(null).addView({viewName:"Visibility View",camera:{},annotations:[],viewSettings:{visibilityState:{hidden:[{key:"solid-a",count:"2.8"},{key:"",count:10},{key:"face-b",count:0}]}}})?.viewSettings?.visibilityState?.hidden||[];Bt(n.length===2,"Expected PMI visibility state to discard invalid hidden entries."),Bt(n[0]?.key==="solid-a"&&n[0]?.count===3,"Expected PMI visibility counts to normalize to rounded positive integers."),Bt(n[1]?.key==="face-b"&&n[1]?.count===1,"Expected PMI visibility counts to clamp to at least 1.")}l(Mp,"test_pmi_view_visibility_state_normalizes");function se(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(se,"assert$a");function G(e,t,n,r){if(!Number.isFinite(e)||Math.abs(e-t)>n)throw new Error(`${r||"Expected approximate equality"}: expected ${t}, got ${e}.`)}l(G,"assertApprox$1");function mr(e,t=0,{x0:n=-1,x1:r=1,y0:a=-1,y1:o=1}={}){const s=new Tn;s.setAttribute("position",new Wt([n,a,t,r,a,t,r,o,t,n,a,t,r,o,t,n,o,t],3)),s.setAttribute("normal",new Wt([0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1],3));const i=new Fr(s,new Pr);return i.name=e,i.type="FACE",i}l(mr,"makePlanarFace");function Gt(e,t){const n=new Re;return n.name=e,n.type="VERTEX",n.position.copy(t),n}l(Gt,"makeVertex");function Sn(e,t,n){const r=new Tn;r.setAttribute("position",new Wt([t.x,t.y,t.z,n.x,n.y,n.z],3));const a=new zs(r,new Hs);return a.name=e,a.type="EDGE",a}l(Sn,"makeLinearEdge");function ot(e){return{viewer:{partHistory:{scene:e}}}}l(ot,"makePMIMode$1");async function kp(){const e=new we,t=mr("BASE_FACE",0),n=Gt("TARGET_VERTEX",new $(2,3,5));e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=pn.showContexButton([t,n]);se(Array.isArray(r?.params?.targets),"Expected linear PMI context action for face and vertex.");const a=at.computeDimPoints(ot(e),{targets:["BASE_FACE","TARGET_VERTEX"]});se(a?.measurementMode==="faceNormal","Expected face-normal linear dimension mode."),G(a.p0.x,2,1e-9,"Expected projected foot x."),G(a.p0.y,3,1e-9,"Expected projected foot y."),G(a.p0.z,0,1e-9,"Expected projected foot on base face."),G(a.p1.z,5,1e-9,"Expected target point to remain along face normal."),G(a.p0.distanceTo(a.p1),5,1e-9,"Expected perpendicular face distance.")}l(kp,"test_pmi_linear_dimension_face_target_measures_perpendicular_to_face");async function $p(){const e=new we,t=mr("BASE_FACE",0),n=mr("TARGET_FACE",4,{x0:1,x1:3,y0:2,y1:4});e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(e),{targets:["BASE_FACE","TARGET_FACE"]});se(r?.measurementMode==="faceNormal","Expected face-normal linear dimension mode for planar faces."),G(r.p0.z,0,1e-9,"Expected base measurement point on base face plane."),G(r.p1.z,4,1e-9,"Expected target measurement point on target face plane."),G(r.p0.distanceTo(r.p1),4,1e-9,"Expected parallel planar face spacing.")}l($p,"test_pmi_linear_dimension_parallel_faces_measure_plane_spacing");async function Lp(){const e=new $(2,3,0),t=new $(2,3,5),n=oi({pointA:e,pointB:t,extensionAnchorA:new $(0,0,0),extensionAnchorB:t,normal:new $(0,1,0),offset:1,showExtensions:!0,screenSizeWorld:l(a=>a*.01,"screenSizeWorld")});se(n?.segments?.length>=4,"Expected jogged extension plus dimension segments.");const r=n.segments[0];G(r[0].x,0,1e-9,"Expected first jog segment to begin at face anchor."),G(r[0].y,0,1e-9,"Expected first jog segment to begin at face anchor."),G(r[1].x,2,1e-9,"Expected first jog segment to end at measurement foot."),G(r[1].y,3,1e-9,"Expected first jog segment to end at measurement foot.")}l(Lp,"test_pmi_linear_dimension_face_extensions_can_jog_to_measurement_line");async function Bp(){const e=new we,t=Sn("BASE_EDGE",new $(0,0,0),new $(10,0,0)),n=Gt("TARGET_VERTEX",new $(4,3,5));e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(e),{targets:["BASE_EDGE","TARGET_VERTEX"]});se(r?.measurementMode==="edgeNormal","Expected edge-normal linear dimension mode."),G(r.p0.x,4,1e-9,"Expected projected foot on edge line x."),G(r.p0.y,0,1e-9,"Expected projected foot on edge line y."),G(r.p0.z,0,1e-9,"Expected projected foot on edge line z."),G(r.p1.x,4,1e-9,"Expected target point to stay on perpendicular line x."),G(r.p1.y,3,1e-9,"Expected target y."),G(r.p1.z,5,1e-9,"Expected target z."),G(r.p1.clone().sub(r.p0).dot(new $(1,0,0)),0,1e-9,"Expected measurement direction perpendicular to edge.");const a=at.computeDimPoints(ot(e),{targets:["TARGET_VERTEX","BASE_EDGE"]});se(a?.measurementMode==="edgeNormal","Expected edge-normal mode regardless of selection order."),G(a.p0.x,4,1e-9,"Expected reversed projected foot x."),G(a.p0.distanceTo(a.p1),Math.sqrt(34),1e-9,"Expected reversed perpendicular distance.")}l(Bp,"test_pmi_linear_dimension_edge_target_measures_perpendicular_to_edge");async function Gp(){const e=new we,t=Sn("BASE_EDGE",new $(0,0,0),new $(10,0,0)),n=Sn("TARGET_EDGE",new $(2,3,4),new $(8,3,4));e.add(t),e.add(n),e.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(e),{targets:["BASE_EDGE","TARGET_EDGE"]});se(r?.measurementMode==="edgeNormal","Expected edge-normal linear dimension mode for parallel edges."),G(r.p0.y,0,1e-9,"Expected base point on base edge y."),G(r.p0.z,0,1e-9,"Expected base point on base edge z."),G(r.p1.y,3,1e-9,"Expected target point on target edge y."),G(r.p1.z,4,1e-9,"Expected target point on target edge z."),G(r.p0.distanceTo(r.p1),5,1e-9,"Expected parallel edge spacing.")}l(Gp,"test_pmi_linear_dimension_parallel_edges_measure_perpendicular_spacing");async function Wp(){const e=new we,t=Sn("BASE_EDGE",new $(0,0,0),new $(10,0,0));e.add(t),e.updateMatrixWorld(!0);const n=at.computeDimPoints(ot(e),{targets:["BASE_EDGE"]});se(n?.measurementMode!=="edgeNormal","Expected a single edge to keep length dimension behavior."),G(n.p0.distanceTo(n.p1),10,1e-9,"Expected single edge length.")}l(Wp,"test_pmi_linear_dimension_single_edge_still_measures_edge_length");async function jp(){const e=pn.inputParamsSchema?.targets||{};se(e.maxSelections===2,"Expected linear dimension target selector to cap selections at two.");const t={targets:["A","B","C"]};pn.applyParams(null,t,t),se(Array.isArray(t.targets),"Expected linear dimension targets to stay an array."),se(t.targets.length===2,"Expected linear dimension params to clamp targets to two."),se(t.targets[0]==="A"&&t.targets[1]==="B","Expected linear dimension to keep the first two targets.");const n=new we;n.add(Gt("A",new $(0,0,0))),n.add(Gt("B",new $(1,0,0))),n.add(Gt("C",new $(100,0,0))),n.updateMatrixWorld(!0);const r=at.computeDimPoints(ot(n),{targets:["A","B","C"]});G(r.p0.distanceTo(r.p1),1,1e-9,"Expected runtime measurement to ignore targets after the first two.")}l(jp,"test_pmi_linear_dimension_limits_targets_to_two");async function Vp(){const n=is({type:"linear",inputParams:{id:"DIM1",type:"linear"},lastRun:{ok:!1,durationMs:4.2,errorMessage:"Linear dimension could not resolve two measurement points."}},{history:{registry:{resolve(r){return r==="linear"?pn:null}}}});se(n.hasError===!0,"Expected failed annotation to be marked as an error."),se(String(n.statusText||"").includes("Error"),"Expected failed annotation status text to show Error."),se(String(n.statusTitle||"").includes("could not resolve"),"Expected failed annotation status title to include the render error message.")}l(Vp,"test_pmi_annotation_failure_status_is_visible");function wn(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(wn,"assert$9");function Gr(e,t,n,r){if(!Number.isFinite(e)||Math.abs(e-t)>n)throw new Error(`${r||"Expected approximate equality"}: expected ${t}, got ${e}.`)}l(Gr,"assertApprox");function Up(e,t,n=24){const r=[];for(let o=0;o<n;o+=1){const s=o/n*Math.PI*2,i=(o+1)/n*Math.PI*2,c=[Math.cos(s)*e,0,Math.sin(s)*e],d=[Math.cos(s)*e,t,Math.sin(s)*e],u=[Math.cos(i)*e,0,Math.sin(i)*e],f=[Math.cos(i)*e,t,Math.sin(i)*e];r.push(...c,...d,...f,...c,...f,...u)}const a=new Tn;return a.setAttribute("position",new Wt(r,3)),a}l(Up,"makePipeFaceGeometry");function Wr({faceName:e,pathName:t,geometryRadius:n,metadata:r={},height:a=10}){const o=new we,s=new Fe;s.name=`${e}_OWNER`,s.type="SOLID",s._auxEdges=[{name:t,points:[[0,0,0],[0,a,0]],closedLoop:!1,polylineWorld:!0,centerline:!0}],s.getFaceMetadata=c=>c===e?r:{};const i=new Fr(Up(n,a),new Pr);return i.name=e,i.type="FACE",i.userData.faceName=e,s.add(i),o.add(s),o.updateMatrixWorld(!0),{scene:o,face:i}}l(Wr,"makePipeScene");function jr(e){return{viewer:{partHistory:{scene:e}}}}l(jr,"makePMIMode");async function zp(){const e="PMI_PIPE_Outer",{scene:t,face:n}=Wr({faceName:e,pathName:"PMI_PIPE_PATH",geometryRadius:2}),r=Ar.showContexButton([n]);wn(r?.params?.cylindricalFaceRef===e,"Expected radial PMI context action for pipe outer face.");const a=Tr.computeRadialPoints(jr(t),{cylindricalFaceRef:e});wn(a?.center&&a?.radiusPoint,"Expected radial PMI to resolve pipe geometry from the auxiliary path."),Gr(a.radius,2,1e-6,"Expected radial PMI to measure pipe radius from geometry.")}l(zp,"test_pmi_radial_dimension_accepts_pipe_aux_path_face");async function Hp(){const e="PMI_FILLET_E1_TUBE_Outer",{scene:t,face:n}=Wr({faceName:e,pathName:"PMI_FILLET_E1_TUBE_PATH",geometryRadius:2.4,metadata:{type:"pipe",source:"FilletFeature",pmiRadiusOverride:1.5,radiusOverride:1.5,inflatedRadius:2.4,filletSideWall:!0}}),r=Ar.showContexButton([n]);wn(r?.params?.cylindricalFaceRef===e,"Expected radial PMI context action for fillet pipe face.");const a=Tr.measureRadialValue(jr(t),{cylindricalFaceRef:e});Gr(a,1.5,1e-9,"Expected radial PMI to use fillet pmiRadiusOverride.")}l(Hp,"test_pmi_radial_dimension_uses_fillet_pipe_radius_override");async function Yp(){const e="O.S17_ROUND_PIPE_3_Outer",t="O.S17_ROUND_PIPE_3_PATH",{scene:n,face:r}=Wr({faceName:e,pathName:t,geometryRadius:.421,metadata:{type:"rounded_pipe",faceRole:"rounded_pipe",offsetShellFaceRole:"rounded_pipe",offsetShellRoundedPipe:!0,sourceFeatureId:"O.S17",pmiRadiusOverride:.5,radiusOverride:.5,offsetShellRadius:.5,pmiCenterlineAuxName:t}}),a=Ar.showContexButton([r]);wn(a?.params?.cylindricalFaceRef===e,"Expected radial PMI context action for offset-shell rounded pipe face.");const o=Tr.measureRadialValue(jr(n),{cylindricalFaceRef:e});Gr(o,.5,1e-9,"Expected radial PMI to use offset-shell rounded-pipe radius override.")}l(Yp,"test_pmi_radial_dimension_uses_offset_shell_pipe_radius_override");async function Xp(e){const t=await e.newFeature("P.CU");t.inputParams.sizeX=8,t.inputParams.sizeY=6,t.inputParams.sizeZ=4}l(Xp,"test_pmi_view_visibility_state_round_trip");async function Kp(e){const n=(Array.isArray(e?.features)?e.features[0]:null)?.inputParams?.featureID;if(!n)throw new Error("PMI visibility state test requires a first feature with featureID.");const r=e.scene?.getObjectByName?.(n);if(!r||r.type!=="SOLID")throw new Error("PMI visibility state test could not find the cube solid.");const a=(Array.isArray(r.children)?r.children:[]).find(c=>c?.type==="FACE")||null,o=(Array.isArray(r.children)?r.children:[]).find(c=>c?.type==="EDGE")||null;if(!a||!o)throw new Error("PMI visibility state test requires one face and one edge on the cube.");r.visible=!1,a.visible=!1,o.visible=!1;const s=new Re;s.type="COMPONENT",s.name="PMI_VIS_COMPONENT",s.visible=!1,e.scene.add(s);const i=e.captureVisibilityState();if(!Array.isArray(i)||i.length<4)throw new Error("Expected captureVisibilityState() to capture hidden scene objects beyond just faces and edges.");if(r.visible=!0,a.visible=!0,o.visible=!0,s.visible=!0,e.applyVisibilityState(i),r.visible!==!1||a.visible!==!1||o.visible!==!1||s.visible!==!1)throw new Error("applyVisibilityState() did not restore the captured hidden state.");if(e.applyVisibilityState([]),r.visible!==!0||a.visible!==!0||o.visible!==!0||s.visible!==!0)throw new Error("applyVisibilityState([]) did not clear the captured hidden state.")}l(Kp,"afterRun_pmi_view_visibility_state_round_trip");function ye(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(ye,"assert$8");function Jp(){const e=Object.create(Ut.prototype);e.viewer=null;const t=new co(-10,10,10,-10,.1,100);t.position.set(0,0,10),t.lookAt(0,0,0),t.updateProjectionMatrix(),t.updateMatrixWorld(!0);const n=e._composeLabelSVG("data:image/png;base64,",[{world:new $(0,0,0),text:"R1.500",anchor:"center middle"}],400,300,400,{viewer:{camera:t},renderMode:"monochrome",labelBackdropColor:"#ff0000"});ye(n.includes('fill="#ff0000"'),"Expected monochrome PMI label mask to use the view backdrop color."),ye(n.includes('stroke="none"'),"Expected monochrome PMI label mask to avoid drawing a border.")}l(Jp,"test_pmi_monochrome_label_svg_uses_backdrop_color");function Zp(){const e=Object.create(Ut.prototype);e.viewer=null;const t=e._getLabelLayoutMetrics(400,400,{renderMode:"monochrome"}),n=e._getLabelLayoutMetrics(400,400,{renderMode:"shaded"});ye(t.paddingX<n.paddingX,"Expected monochrome PMI label mask horizontal padding to be tighter than shaded export padding."),ye(t.paddingY<n.paddingY,"Expected monochrome PMI label mask vertical padding to be tighter than shaded export padding."),ye(t.lineHeight<n.lineHeight,"Expected monochrome PMI label mask line height to be tighter than shaded export line height."),ye(t.radius<n.radius,"Expected monochrome PMI label mask corner radius to be tighter than shaded export radius.")}l(Zp,"test_pmi_monochrome_label_layout_is_tighter_than_shaded");function qp(){const e=Object.create(Ut.prototype),t=[],n={viewName:"View 1"},r=globalThis.setTimeout;e._enterEditMode=(a,o)=>{t.push({view:a,index:o})};try{globalThis.setTimeout=(a,o)=>(a(),0),e.enterEditMode(n,3)}finally{globalThis.setTimeout=r}ye(t.length===2,"Expected shared PMI edit flow to invoke the edit handoff twice."),ye(t[0]?.view===n&&t[1]?.view===n,"Expected shared PMI edit flow to forward the same view."),ye(t[0]?.index===3&&t[1]?.index===3,"Expected shared PMI edit flow to forward the same view index.")}l(qp,"test_pmi_enter_edit_mode_reuses_shared_flow");function Qp(){const e=Object.create(Ut.prototype),t=[],n=new co(-10,10,10,-10,.1,100);n.position.set(0,0,10),n.lookAt(0,0,0),n.updateProjectionMatrix(),n.updateMatrixWorld(!0),e._getCaptureViewportMetrics=()=>({width:100,height:100}),e._updateExportCameraLightRig=()=>{},e._applyWireframe=()=>{};const r={camera:{position:{x:0,y:0,z:1},quaternion:{x:0,y:0,z:0,w:1},up:{x:0,y:1,z:0},zoom:1,projection:null},viewSettings:{visibilityState:{hidden:[{key:"solid-a",count:1}]}}},a={viewer:{camera:n,partHistory:{applyVisibilityState(o){t.push(o)}}},viewport:{width:100,height:100},scene:{}};e._applyViewToRenderContext(r,a,{index:0}),ye(t.length===1,"Expected PMI export render context to apply view visibility state."),ye(Array.isArray(t[0])&&t[0][0]?.key==="solid-a","Expected PMI export render context to forward hidden visibility entries.")}l(Qp,"test_pmi_export_render_context_applies_visibility_state");function e1(){const e=Object.create(Ut.prototype),t=new Re,n=new Re;t.visible=!1,n.visible=!0,t.add(n),ye(e._isObjectEffectivelyVisible(n)===!1,"Expected hidden ancestors to make PMI export objects effectively invisible.")}l(e1,"test_pmi_effective_visibility_respects_hidden_ancestor");function T(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(T,"assert$7");function Te(e,t,n=1e-9){return Math.abs(Number(e)-Number(t))<=n}l(Te,"approxEqual$1");function t1(){T(rr("PORT")===!0,"Expected feature dimension overlay to support port features.")}l(t1,"test_feature_dimension_overlay_supports_port");function n1(){const e=["P.CU","P.CY","P.CO","P.S","P.PY","P.T","E","R","PORT"];for(const t of e)T(rr(t)===!0,`Expected ${t} to be registered for feature dimensions.`),T(la(t)===!0,`Expected ${t} transform controls to expose dimension toggles.`);T(rr("UNKNOWN")===!1,"Expected unknown feature keys to be rejected by the feature dimension registry."),T(la("UNKNOWN")===!1,"Expected unknown feature keys to be rejected by the transform dimension toggle registry.")}l(n1,"test_feature_dimension_registry_support_and_transform_toggle_agree");function r1(){const e=[],n=new ls({active:{entryId:"P1",featureKey:"P.CU",entry:{inputParams:{sizeX:1,sizeY:2,sizeZ:3}}},createLinearAnnotation:l(r=>(e.push(r),{id:`${r.entryId}:${r.fieldKey}`,fieldKey:r.fieldKey}),"createLinearAnnotation"),createAngleAnnotation:l(()=>null,"createAngleAnnotation")}).build();T(n.length===3,"Expected cube feature to build three primitive dimensions."),T(e.map(r=>r.fieldKey).join(",")==="sizeX,sizeY,sizeZ","Expected registered cube descriptor to dispatch through the annotation builder.")}l(r1,"test_feature_dimension_annotation_builder_dispatches_registered_primitive");function a1(){const e={},n=Ys({stores:[e],schema:{edges:{type:"reference_selection"}},resolvedParams:{edges:[{name:"S1:G4",type:"EDGE",uuid:"edge-uuid",points:l(()=>[{x:0,y:0,z:0},{x:4,y:0,z:0}],"points")}]}});T(n===1,"Expected one reference snapshot write."),T(!e.__refPreviewSnapshots,"Expected legacy reference preview snapshots key not to be created."),T(Array.isArray(e.referenceSnapshots?.edges?.["S1:G4"]?.positions),"Expected edge snapshot to be stored under referenceSnapshots."),T(Xs(e,"edges",["S1:G4"],new Set(["EDGE"]))===e.referenceSnapshots.edges["S1:G4"],"Expected snapshots to resolve through the generic reference snapshot store.")}l(a1,"test_reference_snapshot_store_uses_generic_reference_snapshots_key");function o1(){const e=Qr({point:[1,2,3],direction:[0,0,10],extension:4},.5);T(e,"Expected positive port extension geometry to resolve."),T(Te(e.value,4),"Expected extension value to be preserved."),T(Te(e.dragPlaneValue,4),"Expected drag plane value to match positive extension."),T(Te(e.pointB.x,1)&&Te(e.pointB.y,2)&&Te(e.pointB.z,7),"Expected endpoint to follow normalized port direction.");const t=Qr({point:[0,0,0],direction:[5,0,0],extension:0},.75);T(t,"Expected zero-length port extension geometry to resolve."),T(Te(t.value,0),"Expected displayed extension value to remain zero."),T(Te(t.dragPlaneValue,.75),"Expected zero-length extension to keep a visible drag handle offset."),T(Te(t.pointB.x,.75)&&Te(t.pointB.y,0)&&Te(t.pointB.z,0),"Expected visible tip offset to follow the normalized direction.")}l(o1,"test_port_extension_annotation_geometry_preserves_extension_value");function s1(){const e={name:"S1:PROFILE",type:"FACE",children:[]},t={name:"S1:G4",type:"EDGE",children:[]},n={name:"S1",type:"SKETCH",children:[{name:"S1:P1",type:"VERTEX",children:[]},e,{name:"edges",type:"GROUP",children:[t]}]},r={effects:{removed:[n],added:[]}};T(Kt(r,"S1:PROFILE",new Set(["FACE"]))===e,"Expected consumed profile face to resolve from feature effects."),T(Kt(r,{edgeName:"S1:G4"},["EDGE"])===t,"Expected consumed revolve axis edge to resolve from feature effects."),T(Kt(r,{reference:"S1"},new Set(["SKETCH"]))===n,"Expected consumed sketch object to resolve from feature effects."),T(Kt(r,"S1:PROFILE",new Set(["EDGE"]))==null,"Expected type filtering to reject non-axis profile matches.");const a=cs({reference:["S1:PROFILE",{edgeName:"S1:G4"}]});T(a.includes("S1:PROFILE")&&a.includes("S1:G4"),"Expected nested reference names to be collected for generic overlay resolution.")}l(s1,"test_feature_dimension_effect_reference_resolves_consumed_profile_and_axis");async function i1(){const e=new Y,t=new Fe;t.name="protected-overlay-test",Ks(t,{preserve:!0,overlayType:"testOverlay"});const n=new Fe;n.name="regular-overlay-test",e.scene.add(n,t),await e.scene.clear(),T(t.parent===e.scene,"Expected preventRemove scene child to survive scene.clear()."),T(n.parent!==e.scene,"Expected unprotected scene child to be removed by scene.clear()."),Js(t,{deep:!0}),e.scene.remove(t),T(t.parent!==e.scene,"Expected unmarked overlay child to be removable.")}l(i1,"test_part_history_prevent_remove_survives_multi_child_scene_clear");async function l1(){const e=new Y;let t=0;const n={scene:e.scene,render:l(()=>{t++},"render")},r=new Re,a=new Fe,o={__helper:null,attached:null,mode:"translate",updated:!1,getHelper:l(()=>a,"getHelper"),attach(c){this.attached=c},getMode(){return this.mode},setMode(c){this.mode=c},update(){this.updated=!0}};Zs(r),e.scene.add(r);const s=qs(n,o);T(s.addedToScene===!0,"Expected transform helper to be added to the scene."),T(a.parent===e.scene,"Expected transform helper to have the scene as parent."),T(a.userData.preventRemove===!0,"Expected transform helper to be scene-removal protected."),T(r.userData.preventRemove===!0,"Expected transform target to be scene-removal protected."),await e.scene.clear(),T(a.parent===e.scene,"Expected transform helper to survive protected scene clear."),T(r.parent===e.scene,"Expected transform target to survive protected scene clear."),ca({viewer:n,controls:o,group:s.group,target:r}),T(a.parent!==e.scene,"Expected transform helper to be removable through transform teardown."),T(r.parent!==e.scene,"Expected transform target to be removable through transform teardown.");const i=Qs(n,o,r);T(i.addedToScene===!0,"Expected transform helper to be restored to the scene."),T(a.parent===e.scene,"Expected restored transform helper to have the scene as parent."),T(r.parent===e.scene,"Expected restored transform target to have the scene as parent."),T(o.attached===r,"Expected transform controls to reattach to the target."),T(o.updated===!0,"Expected transform controls to be updated after restore."),T(t>0,"Expected restore to request a viewer render."),ca({viewer:n,controls:o,group:i.group,target:r})}l(l1,"test_transform_control_scene_binding_readds_and_removes_overlay_roots");function Ce(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Ce,"assert$6");function un(e,t,n=1e-9){return Math.abs(Number(e)-Number(t))<=n}l(un,"approxEqual");function vn(e,t,n){const r=[e.x,e.y,e.z];for(let a=0;a<3;a+=1)if(!un(r[a],t[a]))throw new Error(n||`Expected vector ${t.join(", ")}, got ${r.join(", ")}.`)}l(vn,"assertVec3");function c1(){const e=ei({position:[1,2,3],rotationEuler:[4,5,6],scale:[1,1,1],reference:{name:"FACE_REF",type:"FACE",pickPoint:[7,8,9],faceIndex:3}});Ce(e.reference&&typeof e.reference=="object","Expected transform reference metadata to be preserved."),Ce(e.reference.name==="FACE_REF","Expected transform reference name to persist."),Ce(e.reference.type==="FACE","Expected transform reference type to persist."),Ce(Array.isArray(e.reference.pickPoint),"Expected pick point metadata to persist."),Ce(e.reference.faceIndex===3,"Expected face index metadata to persist.")}l(c1,"test_transform_reference_sanitize_preserves_metadata");function d1(){const e=new we,t=new Re;t.name="FACE_PICK",t.type="FACE",e.add(t);const n=ti({name:"FACE_PICK",type:"FACE",pickPoint:[3,4,5]},e,{},uo),r=new $(Number(n.position[0])||0,Number(n.position[1])||0,Number(n.position[2])||0);vn(r,[3,4,5],"Expected face reference base to use the stored pick point.")}l(d1,"test_transform_reference_base_uses_face_pick_point");function u1(){const e=new we,t=new Re;t.name="VERTEX_REF",t.type="VERTEX",t.position.set(10,20,30),e.add(t);const n=ni({position:[1,2,3],rotationEuler:[0,0,0],scale:[1,1,1],reference:{name:"VERTEX_REF",type:"VERTEX"}},e,{},uo),r=new $,a=new ri,o=new $;n.decompose(r,a,o),vn(r,[11,22,33],"Expected referenced transform to offset from the selected vertex.")}l(u1,"test_referenced_transform_matrix_uses_vertex_reference_origin");function f1(){const e=new we,t=new Re;t.name="PORT_VERTEX",t.type="VERTEX",t.position.set(5,0,0),e.add(t);const n=to({featureId:"PORT_REF_TEST",inputParams:{portName:"Port Ref Test",transform:{position:[2,0,0],rotationEuler:[0,0,0],scale:[1,1,1],reference:{name:"PORT_VERTEX",type:"VERTEX"}},extension:2,displayLength:4},referenceSource:e});Ce(Array.isArray(n.point),"Expected port definition point to resolve."),Ce(un(n.point[0],7),"Expected port point to be offset from the transform reference."),Ce(un(n.point[1],0)&&un(n.point[2],0),"Expected port point to remain aligned to the reference origin."),Ce(n.anchorName==="PORT_VERTEX","Expected anchorName compatibility field to reflect the transform reference."),Ce(n.transform?.reference,"Expected normalized port transform to retain its reference.")}l(f1,"test_port_definition_uses_transform_reference_without_anchor");function p1(){const e=new we,t=new Re;t.name="PORT_VERTEX_DIR",t.type="VERTEX",t.position.set(1,2,3),e.add(t);const n=new Re;n.name="PORT_DATUM_DIR",n.type="DATUM",n.quaternion.setFromAxisAngle(new $(0,0,1),Math.PI/2),e.add(n),e.updateMatrixWorld(!0);const r=to({featureId:"PORT_DIR_TEST",inputParams:{transform:{position:[2,0,0],rotationEuler:[0,0,0],scale:[1,1,1],reference:{name:"PORT_VERTEX_DIR",type:"VERTEX"}},directionRef:[{name:"PORT_DATUM_DIR",type:"DATUM"}]},referenceSource:e});vn(new $(...r.point),[1,4,3],"Expected point reference to inherit the direction reference basis."),vn(new $(...r.direction),[0,1,0],"Expected port direction to align with the direction reference.")}l(p1,"test_port_definition_uses_transform_reference_and_direction_reference");function Xe(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Xe,"assert$5");async function _1(){const e=new An(null),t=e.createSheet({name:"Harness Sheet",sizeKey:"A",orientation:"landscape",elements:[]}),n=[{id:"WIRE1",name:"Wire 1",from:"PORT_A",to:"PORT_B",diameter:1.25},{id:"WIRE2",name:"Wire 2",from:"PORT_C",to:"PORT_D",diameter:.8}],r=[{connectionId:"WIRE1",feasible:!0,distance:123.456},{connectionId:"WIRE2",feasible:!1,error:"No route found."}],a=ds(n,r);Xe(a.cells[0][0].text==="Wire","Expected first header cell to be Wire."),Xe(a.cells[1][1].text==="123.46","Expected routed length to be formatted into the sheet table."),Xe(a.cells[2][5].text==="Failed","Expected failed routes to use a compact sheet status label.");const o=us(e,t.id,n,r);Xe(!!o?.sheet,"Expected sheet insertion to return an updated sheet."),Xe(!!o?.element,"Expected sheet insertion to return the inserted element."),Xe(o.element.type==="table","Expected inserted element to be a table."),Xe(o.element.tableData?.cells?.[1]?.[0]?.text==="Wire 1","Expected first wire name to appear in the inserted table."),Xe(o.element.tableData?.cells?.[2]?.[5]?.text==="Failed","Expected compact status text to persist on the inserted table element.")}l(_1,"test_wire_harness_sheet_table_insert");function Zn(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Zn,"assert$4");function qn(e,t,n="termination",r=[0,0,0],a=[1,0,0]){return{name:e,userData:{isPortRoot:!0,portData:{objectName:e,name:t,kind:n,point:r.slice(),direction:a.slice(),extension:1,displayLength:1}}}}l(qn,"createPort");function Wa(e,t,n,r,a){return{type:"SP",inputParams:{featureID:e,curveResolution:4,bendRadius:1},persistentData:{spline:{points:[{id:"p0",position:[0,0,0],attachment:{type:"port",portRef:t,side:n}},{id:"p1",position:[1,0,0],attachment:{type:"port",portRef:r,side:a}}]}}}}l(Wa,"createSplineFeature");async function h1(){const e=qn("START","Start","termination",[-4,0,0],[1,0,0]),t=qn("END","End","termination",[4,0,0],[1,0,0]),n=qn("WAYPOINT","Waypoint","waypoint",[0,0,0],[1,0,0]),r=new Map([[e.name,e],[t.name,t],[n.name,n]]),a={scene:{traverse(c){c(e),c(t),c(n)},getObjectByName(c){return r.get(String(c))||null}},getObjectByName(c){return r.get(String(c))||null},features:[Wa("SP1","START","A","WAYPOINT","A"),Wa("SP2","WAYPOINT","B","END","A")]},{network:o,routes:s}=await fs(a,[{id:"WIRE3",name:"Wire 3",from:"Start",to:"End",diameter:1}]),i=(o?.splineSegments||[]).filter(c=>c.firstPoint==="WAYPOINT"||c.secondPoint==="WAYPOINT").map(c=>c.firstPoint==="WAYPOINT"?c.firstSide:c.secondSide);Zn(i.length===2,"Expected two waypoint segment attachments."),Zn(i.every(c=>c==="B"),"Expected both spline branches to occupy waypoint side B."),Zn(s[0].feasible===!1,"Expected route to fail when both branches use the same physical waypoint side.")}l(h1,"test_wire_harness_infers_endpoint_side_from_spline_direction");function et(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(et,"assert$3");function m1(){const e=new we;ps(e,[],[{segmentId:"SEG1",featureId:"SP1",polyline:[[0,0,0],[15,0,0],[15,10,0]],diameter:2.5,wireCount:3,wireDiameters:[1,1,1.5],connectionIds:["WIRE-1"],connectionNames:["Wire 1"]}]);const t=e.getObjectByName("__WireHarnessRoutes");et(t,"Expected the wire harness route group to be added to the scene.");const n=[];e.traverse(s=>{s?.type==="SOLID"&&s?.userData?.isWireHarnessRoute&&n.push(s)}),et(n.length===1,`Expected one routed harness solid, got ${n.length}.`),et(typeof n[0].toSTL=="function","Expected routed harness geometry to be a real BREP solid."),et(_s(e,"WIRE-1").length===1,"Expected connection hover lookup to resolve the routed harness solid.");const r=n[0].getMesh(),a=(r?.triVerts?.length||0)/3|0;try{r?.delete?.()}catch{}et(a>0,"Expected routed harness solid to contribute triangulated geometry for export."),hs(e),et(e.getObjectByName("__WireHarnessRoutes")==null,"Expected clear to remove the wire harness route group.");const o=[];e.traverse(s=>{s?.type==="SOLID"&&s?.userData?.isWireHarnessRoute&&o.push(s)}),et(o.length===0,"Expected clear to remove routed harness solids from the scene.")}l(m1,"test_wire_harness_routes_render_as_scene_solids");function Ke(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Ke,"assert$2");async function g1(){const e=new Y;e.wireHarnessManager.addConnection({id:"wire-1",name:"Wire 1",from:"PORT-A",to:"PORT-B",diameter:1.5}),e.wireHarnessManager.setRouteResults([{connectionId:"wire-1",connectionName:"Wire 1",feasible:!0,error:"",distance:42.5,polyline:[[0,0,0],[10,0,0],[10,5,0]],segmentIds:["SP1","SP2"],nodePath:["PORT-A:A","MID:A","PORT-B:A"],reusesHarnessPoint:!1,diameter:1.5,from:"PORT-A",to:"PORT-B"}]);const t=await e.toJSON(),n=new Y;await n.fromJSON(t);const r=n.wireHarnessManager.getConnections();Ke(r.length===1,`Expected one restored connection, got ${r.length}.`),Ke(r[0].id==="wire-1","Expected the connection ID to persist.");const a=n.wireHarnessManager.getRouteResults();Ke(a.length===1,`Expected one restored route result, got ${a.length}.`),Ke(a[0].feasible===!0,"Expected the restored route result to remain feasible."),Ke(a[0].distance===42.5,`Expected the restored route distance to persist, got ${a[0].distance}.`),Ke(a[0].segmentIds.join(",")==="SP1,SP2","Expected restored route segment IDs to persist.");const o=n.wireHarnessManager.consumePendingRestoredRouteResults();Ke(Array.isArray(o)&&o.length===1,"Expected the restored model to queue route geometry restoration."),Ke(n.wireHarnessManager.consumePendingRestoredRouteResults()==null,"Expected pending restored routes to be consumed only once.")}l(g1,"test_wire_harness_route_results_persist_in_model_json");async function x1(e){const t=await e.newFeature("P.CU");t.inputParams.sizeX=8,t.inputParams.sizeY=6,t.inputParams.sizeZ=4}l(x1,"test_visibility_hidden_state_persistence");async function E1(e){const n=(Array.isArray(e?.features)?e.features[0]:null)?.inputParams?.featureID;if(!n)throw new Error("Visibility persistence test requires a first feature with featureID.");const r=e.scene?.getObjectByName?.(n);if(!r||r.type!=="SOLID")throw new Error("Visibility persistence test could not find initial cube solid.");const a=(Array.isArray(r.children)?r.children:[]).find(p=>p?.type==="FACE")||null,o=(Array.isArray(r.children)?r.children:[]).find(p=>p?.type==="EDGE")||null;if(!a||!o)throw new Error("Visibility persistence test requires one face and one edge on the cube.");const s=String(a?.userData?.faceName||a?.name||""),i=String(o?.name||"");if(!s||!i)throw new Error("Visibility persistence test requires named face and edge.");r.visible=!1,a.visible=!1,o.visible=!1,await e.newFeature("P.CU"),await e.runHistory();const c=e.scene?.getObjectByName?.(n);if(!c)throw new Error("Visibility persistence test could not find rebuilt cube.");if(c.visible!==!1)throw new Error("Hidden solid visibility state was not preserved after history run.");const d=Array.isArray(c.children)?c.children:[],u=d.find(p=>p?.type!=="FACE"?!1:String(p?.userData?.faceName||p?.name||"")===s)||null,f=d.find(p=>p?.type==="EDGE"&&String(p?.name||"")===i)||null;if(!u)throw new Error("Hidden face could not be resolved after history run.");if(!f)throw new Error("Hidden edge could not be resolved after history run.");if(u.visible!==!1)throw new Error("Hidden face visibility state was not preserved after history run.");if(f.visible!==!1)throw new Error("Hidden edge visibility state was not preserved after history run.")}l(E1,"afterRun_visibility_hidden_state_persistence");function ja(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(ja,"assert$1");async function y1(){ja(da(sa,"MODELING")===!0,"Expected Thicken to be available in the Modeling workbench."),ja(da(sa,"SURFACING")===!0,"Expected Thicken to be available in the Surfacing workbench.")}l(y1,"test_thicken_feature_is_available_in_modeling_and_surfacing_workbenches");function Rt(e,t){if(!e)throw new Error(t||"Assertion failed.")}l(Rt,"assert");async function S1(){const e={type:"SKETCH",visible:!0},t={getObjectByName(n){return n==="SK_001"?e:null}};Rt(Vn(t,"SK_001",!1)===!0,"Expected sketch visibility helper to hide the requested sketch object."),Rt(e.visible===!1,"Expected sketch object to become hidden."),Rt(Vn(t,"SK_001",!0)===!0,"Expected sketch visibility helper to restore the requested sketch object."),Rt(e.visible===!0,"Expected sketch object visibility to be restored."),Rt(Vn(t,"MISSING",!0)===!1,"Expected helper to report when a sketch object cannot be found.")}l(S1,"test_sketch_feature_scene_visibility");function w1(e){const t=Array.isArray(e?._triVerts)?e._triVerts:[],n=t.length/3|0,r=new Map,a=l((i,c)=>i<c?`${i}|${c}`:`${c}|${i}`,"edgeKey");for(let i=0;i<n;i++){const c=t[i*3]>>>0,d=t[i*3+1]>>>0,u=t[i*3+2]>>>0;for(const[f,p]of[[c,d],[d,u],[u,c]]){const _=a(f,p);r.set(_,(r.get(_)||0)+1)}}let o=0,s=0;for(const i of r.values())i===1?o+=1:i!==2&&(s+=1);return{boundaryEdgeCount:o,nonManifoldEdgeCount:s,triangleCount:n}}l(w1,"analyzeMeshTopology");async function v1(){const e={scene:new M.THREE.Scene,getObjectByName(i){return this.scene.getObjectByName(i)}},t=new M.Cube({x:4,y:4,z:4,name:"REVOLVE_SRC"});t.visualize(),e.scene.add(t);const n=t.children.find(i=>i.type==="FACE"&&/_PZ$/.test(i.name)),r=n?.edges?.[0]||null;if(!n||!r)throw new Error("Failed to create source face/edge fixtures for revolve feature test.");const a=new Ts;a.inputParams={profile:n.name,axis:r.name,angle:34,resolution:64,featureID:"REVOLVE_FEATURE_TEST",boolean:{operation:"UNION",targets:[t]}};const o=await a.run(e);if(!(Array.isArray(o?.added)?o.added:[]).length)throw new Error("Expected revolve feature to resolve string face/edge references and produce a result.")}l(v1,"test_revolve_feature_resolves_face_and_edge_string_references");async function b1(){const e=new M.Cube({x:4,y:4,z:4,name:"REVOLVE_VIS_SRC"});e.visualize();const t=e.children.find(i=>i.type==="FACE"&&/_PZ$/.test(i.name)),n=t?.edges?.[0]||null;if(!t||!n)throw new Error("Failed to create source face/edge fixtures for revolve visualization test.");const r=new M.Revolve({face:t,axis:n,angle:360,resolution:8,name:"REVOLVE_VIS_TEST"});if(!Array.isArray(r._triIDs)||r._triIDs.length===0)throw new Error("Expected revolve to produce authored triangles.");const a=r.getFaces(!1);if(!Array.isArray(a)||a.length===0)throw new Error("Expected axis-edge revolve to produce native queryable faces.");for(const i of a)if(!Array.isArray(i.triangles)||i.triangles.length===0)throw new Error(`Native revolve face ${i.faceName||"UNKNOWN"} has no triangles.`);r.visualize();const o=r.children.filter(i=>i.type==="FACE");if(o.length!==a.length)throw new Error(`Expected rendered revolve face count to match native faces. Native=${a.length}, Rendered=${o.length}.`);const s=r.volume();if(!(s>0))throw new Error(`Expected axis-edge revolve to have positive manifold volume. Volume=${s}.`)}l(b1,"test_revolve_generates_manifold_native_faces_for_axis_edge_profile");async function F1(){const e=M.THREE,t=[[-2,-2,0],[2,-2,0],[2,2,0],[-2,2,0],[-1,-1,0],[1,-1,0],[1,1,0],[-1,1,0]],n=[[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],r=[];for(const d of n)for(const u of d)r.push(...t[u]);const a=new e.BufferGeometry;a.setAttribute("position",new e.Float32BufferAttribute(r,3)),a.computeVertexNormals();const o=new M.Face(a);o.updateMatrixWorld?.(!0);const s=As(o),i=s.filter(d=>!d.isHole).length,c=s.filter(d=>d.isHole).length;if(i!==1||c!==1)throw new Error(`Expected recovered annular profile to have one outer loop and one hole. Outer=${i}, Holes=${c}.`)}l(F1,"test_revolve_face_profile_boundary_recovery_marks_inner_loop_as_hole");async function P1(){const e=M.THREE,t=[[0,0,0],[8.905728,14.930946,0],[-10.96543,26.783322,0],[-19.87116,11.852382,0]],n=[...t[0],...t[1],...t[2],...t[0],...t[2],...t[3]],r=new e.BufferGeometry;r.setAttribute("position",new e.Float32BufferAttribute(n,3)),r.computeVertexNormals();const a=new M.Face(r);a.name="REVOLVE_AXIS_EDGE_PROFILE",a.userData.boundaryLoopsWorld=[{pts:t,isHole:!1}],a.updateMatrixWorld?.(!0);const o=new e.BufferGeometry;o.setAttribute("position",new e.Float32BufferAttribute([...t[0],...t[3]],3));const s=new e.Line(o);s.name="REVOLVE_AXIS_EDGE",s.type="EDGE",s.updateMatrixWorld?.(!0);const i=new M.Revolve({face:a,axis:s,angle:144,resolution:64,name:"REVOLVE_AXIS_EDGE_PARTIAL_TEST"}),c=w1(i);if(c.boundaryEdgeCount||c.nonManifoldEdgeCount)throw new Error(`Expected partial revolve around a profile edge to be closed and manifold. Boundaries=${c.boundaryEdgeCount}, nonManifold=${c.nonManifoldEdgeCount}, triangles=${c.triangleCount}.`);if(typeof i._isCoherentlyOrientedManifold=="function"&&i._isCoherentlyOrientedManifold()!==!0)throw new Error("Expected partial revolve around a profile edge to be coherently oriented.")}l(P1,"test_revolve_axis_edge_profile_reuses_axis_vertices_for_partial_sweep");async function A1(e=new Y){e.expressions="resolution = 32;";const t=await e.newFeature("S");Object.assign(t.inputParams,{id:"S1",sketchPlane:null,curveResolution:"resolution"}),t.persistentData={sketch:{points:[{id:0,x:0,y:0,fixed:!0,construction:!0,externalReference:!1},{id:1,x:0,y:0,fixed:!1,construction:!1,externalReference:!1},{id:2,x:3,y:0,fixed:!1,construction:!1,externalReference:!1},{id:3,x:3,y:0,fixed:!1,construction:!1,externalReference:!1},{id:4,x:3,y:4,fixed:!1,construction:!1,externalReference:!1},{id:5,x:3,y:4,fixed:!1,construction:!1,externalReference:!1},{id:6,x:0,y:4,fixed:!1,construction:!1,externalReference:!1},{id:7,x:0,y:4,fixed:!1,construction:!1,externalReference:!1},{id:8,x:0,y:0,fixed:!1,construction:!1,externalReference:!1}],geometries:[{id:1,type:"line",points:[1,2],construction:!1},{id:2,type:"line",points:[3,4],construction:!1},{id:3,type:"line",points:[5,6],construction:!1},{id:4,type:"line",points:[7,8],construction:!1}],constraints:[{id:1,type:"≡",points:[2,3]},{id:2,type:"≡",points:[4,5]},{id:3,type:"≡",points:[6,7]},{id:4,type:"≡",points:[8,1]}]}};const n=await e.newFeature("R");Object.assign(n.inputParams,{id:"R2",profile:"S1",consumeProfileSketch:!0,axis:"S1:G4",angle:120,resolution:"resolution",boolean:{targets:[],operation:"NONE",overlapConditioningEnabled:!0}});const r=l(a=>{const o=e.getObjectByName("R2");if(!o)throw new Error(`${a} Expected revolve output R2.`);const s=typeof o.getFaceNames=="function"?o.getFaceNames():[];for(const i of["S1:G1_RV","S1:G2_RV","S1:G3_RV"])if(!s.includes(i))throw new Error(`${a} Missing revolve sidewall ${i}. Faces: ${s.join(", ")}`);if(s.some(i=>i==="S1:PROFILE_RV"||i==="R2:S1:PROFILE_RV"))throw new Error(`${a} Revolve sidewalls collapsed to profile-level face. Faces: ${s.join(", ")}`)},"assertEdgeSidewalls");return await e.runHistory({throwOnFeatureError:!0}),r("[revolve restored sketch initial]"),n.inputParams.angle=180,await e.runHistory({throwOnFeatureError:!0}),r("[revolve restored sketch angle edit]"),console.log("✓ Revolve keeps edge side wall faces after editing a consumed sketch profile"),e}l(A1,"test_revolve_restored_consumed_sketch_keeps_edge_sidewalls_after_angle_edit");const T1="src/tests/importTestingData/import_test.stl";function C1(e){const t=Array.isArray(e?._triVerts)?e._triVerts:[],n=t.length/3|0,r=new Map,a=l((i,c)=>i<c?`${i}|${c}`:`${c}|${i}`,"edgeKey");for(let i=0;i<n;i+=1){const c=t[i*3+0]>>>0,d=t[i*3+1]>>>0,u=t[i*3+2]>>>0;for(const[f,p]of[[c,d],[d,u],[u,c]]){const _=a(f,p);r.set(_,(r.get(_)||0)+1)}}let o=0,s=0;for(const i of r.values())i===1?o+=1:i!==2&&(s+=1);return{boundaryEdgeCount:o,nonManifoldEdgeCount:s}}l(C1,"analyzeSolidTopology");function N1(e,t){const n=C1(e);if(n.boundaryEdgeCount||n.nonManifoldEdgeCount)throw new Error(`[${t}] Expected closed manifold result. Boundary edges=${n.boundaryEdgeCount}, non-manifold edges=${n.nonManifoldEdgeCount}.`);if(typeof e?._isCoherentlyOrientedManifold=="function"&&e._isCoherentlyOrientedManifold()!==!0)throw new Error(`[${t}] Expected coherently oriented manifold result.`)}l(N1,"assertClosedManifold");async function R1(){const e=[],t={type:"SOLID",simplify(c){return e.push(["simplify",c]),this},_weldVerticesByEpsilon(c,d){return e.push(["weld",c,d?.rebuildManifold]),this},fixTriangleWindingsByAdjacency(){return e.push(["fixWindings"]),this},visualize(){e.push(["visualize"])}},n={type:"SOLID",name:"REMESH_SRC",clone(){return e.push(["clone"]),t}},r={scene:{async getObjectByName(c){return c==="REMESH_SRC"?n:null}}},a=new Cs;a.inputParams={targetSolid:"REMESH_SRC",mode:"Simplify",tolerance:.05};const o=await a.run(r);if(!Array.isArray(o?.added)||o.added[0]!==t)throw new Error("Expected remesh simplify feature to return the cloned output solid.");if(!Array.isArray(o?.removed)||o.removed[0]!==n)throw new Error("Expected remesh simplify feature to mark the source solid for removal.");const s=e.map(c=>{const[d,u,f]=c;return d==="weld"?`${d}:${u}:${String(f)}`:u===void 0?d:`${d}:${u}`}),i=["clone","fixWindings","simplify:0.05","visualize"];if(s.join("|")!==i.join("|"))throw new Error(`Expected remesh simplify to use kernel simplify without full-tolerance weld; received ${s.join("|")}.`)}l(R1,"test_remesh_simplify_uses_kernel_simplify_without_full_tolerance_weld");async function I1(e){const t=await j.promises.readFile(T1,"utf8"),n=await e.newFeature("IMPORT3D");Object.assign(n.inputParams,{id:"REMESH_IMPORT_FIXTURE_SOURCE",featureID:"REMESH_IMPORT_FIXTURE_SOURCE",fileToImport:t,centerMesh:!0,deflectionAngle:8,decimationLevel:100,meshRepairLevel:"NONE",extractMultipleSolids:!1,extractPlanarFaces:!0,planarFaceMinAreaPercent:1,segmentAnalyticPrimitives:!1});const r=await e.newFeature("RM");return r.inputParams.targetSolid="REMESH_IMPORT_FIXTURE_SOURCE",r.inputParams.mode="Simplify",r.inputParams.tolerance=.02,e}l(I1,"test_remesh_simplify_imported_fixture_stl");async function O1(e){const n=(e.scene?.children||[]).filter(a=>a?.type==="SOLID").find(a=>String(a?.name||"")==="(REMESH_IMPORT_FIXTURE_SOURCE)");if(!n)throw new Error("[remesh imported fixture] Expected remeshed imported solid.");const r=Math.floor((Array.isArray(n._triVerts)?n._triVerts.length:0)/3);if(!(r>0&&r<17228))throw new Error(`[remesh imported fixture] Expected simplified triangle count below 17228, got ${r}.`);N1(n,"remesh imported fixture")}l(O1,"afterRun_remesh_simplify_imported_fixture_stl");async function D1(){if(!Qa())return;const e=new Sr({radius:1,height:2,resolution:64,name:"SIMPLIFY_CYL"}),t=e.getTriangleCount(),n=e.simplify(.1),r=n.getTriangleCount();if(!(r>0&&r<t))throw new Error(`Expected simplify to reduce triangle count from ${t}; got ${r}.`);const a=new Set(n.getFaceNames());for(const s of["SIMPLIFY_CYL_B","SIMPLIFY_CYL_T","SIMPLIFY_CYL_S"])if(!a.has(s))throw new Error(`Expected simplified cylinder to preserve face tag "${s}".`);const o=n.getFaceMetadata("SIMPLIFY_CYL_S");if(o?.type!=="cylindrical"||Math.abs((o?.radius||0)-1)>1e-9)throw new Error("Expected simplified cylinder to preserve side-face metadata.")}l(D1,"test_solid_simplify_preserves_face_tags_and_metadata");function M1(e,t,n,r,a=100){return{points:[{id:0,x:e,y:t,fixed:!0},{id:1,x:n,y:t,fixed:!1},{id:2,x:n,y:r,fixed:!1},{id:3,x:e,y:r,fixed:!1}],geometries:[{id:a+0,type:"line",points:[0,1],construction:!1},{id:a+1,type:"line",points:[1,2],construction:!1},{id:a+2,type:"line",points:[2,3],construction:!1},{id:a+3,type:"line",points:[3,0],construction:!1}],constraints:[{id:0,type:"⏚",points:[0]}]}}l(M1,"makeRectSketch");async function k1(e){const t=await e.newFeature("P.CY");Object.assign(t.inputParams,{id:"P.CY1",radius:"4",height:10,resolution:64,transform:{position:[0,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},boolean:{targets:[],operation:"NONE"}});const n=await e.newFeature("S");Object.assign(n.inputParams,{id:"S5",sketchPlane:"P.CY1_T",curveResolution:32}),n.persistentData={sketch:M1(4,-2,7,2,200)};const r=await e.newFeature("E");Object.assign(r.inputParams,{id:"E6",profile:"S5:PROFILE",distance:"5",distanceBack:"4",boolean:{targets:["P.CY1"],operation:"UNION",overlapConditioningEnabled:!0},consumeProfileSketch:!0}),await e.runHistory();const a=e.getObjectByName("P.CY1");if(!a)throw new Error("Expected extrude boolean target solid to exist.");a.visualize();const o=e.getObjectByName("E6:S5:PROFILE_END");if(!o)throw new Error("Expected post-union face reference E6:S5:PROFILE_END to resolve before revolve.");const s=Array.isArray(o.edges)?o.edges[0]:null;if(!s?.name)throw new Error("Expected a boundary edge on the resolved extrude end face.");const i=a.volume(),c=await e.newFeature("R");Object.assign(c.inputParams,{id:"R9",profile:"E6:S5:PROFILE_END",axis:s.name,angle:34,resolution:"128",boolean:{targets:["P.CY1"],operation:"UNION",overlapConditioningEnabled:!1}}),await e.runHistory();const d=e.getObjectByName("P.CY1");if(!d)throw new Error("Expected final boolean target solid to exist after revolve.");const u=d.volume();if(!(u>i+1e-6))throw new Error(`Expected revolve union to add volume. Before=${i}, After=${u}.`);if(!d.getFaceNames().some(p=>String(p||"").includes("_RV")))throw new Error("Expected final solid to retain revolve side-wall face names.")}l(k1,"test_revolve_after_union_preserves_face_reference_resolution");function $1(e,t){return(e?.scene?.children||[]).filter(r=>r?.type==="SOLID").find(r=>String(r?.name||"")===String(t))||null}l($1,"getSolidByName");function L1(e){return/^FACE(?:_\d+)?$/.test(String(e||""))||/_REPAIR_\d+$/.test(String(e||""))}l(L1,"isSyntheticFaceName");async function B1(e){const t=await e.newFeature("P.CU");Object.assign(t.inputParams,{id:"P.CU1",sizeX:14,sizeY:10,sizeZ:8,transform:{position:[0,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},boolean:{targets:[],operation:"NONE"}});const n=await e.newFeature("P.CY");Object.assign(n.inputParams,{id:"P.CY2",radius:3,height:12,resolution:64,transform:{position:[0,0,0],rotationEuler:[0,0,0],scale:[1,1,1]},boolean:{targets:["P.CU1"],operation:"UNION",overlapConditioningEnabled:!0}})}l(B1,"test_primitive_boolean_union_preserves_face_grouping");async function G1(e){const t=$1(e,"P.CU1");if(!t)throw new Error("[primitive_boolean_union_preserves_face_grouping] Expected final solid P.CU1 to exist.");const n=(t.getFaceNames?.()||[]).map(o=>String(o||"")),r=n.filter(L1);if(r.length>0)throw new Error(`[primitive_boolean_union_preserves_face_grouping] Expected native primitive union to avoid fallback face labels, found ${r.join(", ")}.`);const a=["P.CU1_NX","P.CU1_NY","P.CU1_NZ","P.CU1_PX","P.CU1_PY","P.CU1_PZ","P.CY2_B","P.CY2_T","P.CY2_S"];for(const o of a)if(!n.includes(o))throw new Error(`[primitive_boolean_union_preserves_face_grouping] Missing expected face ${o}. Faces: ${n.join(", ")}`)}l(G1,"afterRun_primitive_boolean_union_preserves_face_grouping");const Uo=typeof process<"u"&&process.versions&&process.versions.node&&typeof window>"u",W1=Ie.join("tests","test-run.log.md"),j1=1;function bn(e){return e?.test?.name&&String(e.test.name)||"unnamed_test"}l(bn,"getTestName");function V1(e=[]){const t=e.slice(2);for(let n=0;n<t.length;n+=1){const r=t[n];if(r==="--test"||r==="-t")return t[n+1]?String(t[n+1]):"";if(r.startsWith("--test="))return r.slice(7);if(!r.startsWith("-"))return r}return null}l(V1,"getCliRequestedTestName");function U1(e,t){if(t==null)return e;if(!t)throw new Error("Missing test name. Use `pnpm test -- <test_name>` or `pnpm test -- --test <test_name>`.");const n=e.filter(s=>bn(s)===t);if(n.length>0)return n;const a=e.map(bn).sort().filter(s=>s.includes(t)).slice(0,10),o=a.length?`
1941
1941
  Matching test names:
1942
1942
  ${a.map(s=>` - ${s}`).join(`
1943
1943
  `)}`:`