@layoutit/polycss-morph 0.2.10 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/prepare.js CHANGED
@@ -1 +1 @@
1
- var X="polycss-morph.model@1",ee="polycss-morph.catalog@1",ne="polycss-morph.package@1";var Ke=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,Cn=/^[a-z0-9][a-z0-9._-]*$/,Ye=/^\d+\.\d+\.\d+$/,jn=/^[a-f0-9]{64}$/,Tn=new Set(["joint-skin","morph-regions","prepared-playback","static-prepared"]),Ln=new Set(["animation","joint-skinning","morph-targets","prepared-playback","retained-render","semantic-controls","sparse-updates","springs"]),En=new Set(["atlas-slice","direct-image","solid-quad","solid-triangle"]),Nn=new Set(["control-value","joint-rotation","joint-scale","joint-translation","morph-weight","shape-matrix"]),he=class extends TypeError{constructor(e,r,o){super(`${r}: ${o}`),this.name="PolyMorphContractError",this.code=e,this.path=r}};function u(n,e,r){throw new he(n,e,r)}function I(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&u("invalid-type",e,"expected an object");let o=Object.keys(n).sort(),a=[...r].sort();return(o.length!==a.length||o.some((t,i)=>t!==a[i]))&&u("invalid-keys",e,`expected exactly ${a.join(", ")}`),n}function A(n,e){return Array.isArray(n)||u("invalid-type",e,"expected an array"),n}function F(n,e){return(typeof n!="string"||n.length===0)&&u("invalid-string",e,"expected a non-empty string"),n}function N(n,e){return(typeof n!="number"||!Number.isFinite(n))&&u("invalid-number",e,"expected a finite number"),n}function U(n,e,r=0){let o=N(n,e);return(!Number.isSafeInteger(o)||o<r)&&u("invalid-integer",e,`expected an integer >= ${r}`),o}function ke(n,e){return typeof n!="boolean"&&u("invalid-boolean",e,"expected a boolean"),n}function L(n,e){let r=F(n,e);return Ke.test(r)||u("invalid-id",e,"expected a normalized kebab-case id"),r}function V(n,e){let r=new Set;for(let o of n)r.has(o)&&u("duplicate-id",e,`duplicate id ${o}`),r.add(o)}function te(n,e){let r=A(n,e);return r.length!==3&&u("invalid-vector",e,"expected three components"),r.map((o,a)=>N(o,`${e}[${a}]`))}function Y(n,e){let r=A(n,e);return r.length!==16&&u("invalid-matrix",e,"expected sixteen components"),r.map((o,a)=>N(o,`${e}[${a}]`))}function Ze(n,e){let r=F(n,e);return r.split("/").some(o=>!Cn.test(o))&&u("invalid-path",e,"expected lowercase URL-safe package path segments"),r}function ge(n,e,r){let o=U(n,e);return o>=r&&u("out-of-range",e,`expected an index below ${r}`),o}function Vn(n,e){let r=I(n,e,["normals","polygons","vertices"]),o=A(r.vertices,`${e}.vertices`).map((i,c)=>te(i,`${e}.vertices[${c}]`)),a=A(r.normals,`${e}.normals`).map((i,c)=>te(i,`${e}.normals[${c}]`));o.length===0&&u("missing-topology",`${e}.vertices`,"expected at least one vertex"),a.length===0&&u("missing-topology",`${e}.normals`,"expected at least one normal");let t=A(r.polygons,`${e}.polygons`).map((i,c)=>{let s=`${e}.polygons[${c}]`,l=I(i,s,["id","normalIndices","vertexIndices"]),d=A(l.vertexIndices,`${s}.vertexIndices`).map((m,M)=>ge(m,`${s}.vertexIndices[${M}]`,o.length)),p=A(l.normalIndices,`${s}.normalIndices`).map((m,M)=>ge(m,`${s}.normalIndices[${M}]`,a.length));return d.length<3&&u("invalid-polygon",s,"expected at least three vertices"),p.length!==d.length&&u("invalid-polygon",s,"normal and vertex index counts must match"),new Set(d).size!==d.length&&u("invalid-polygon",s,"vertex indices must be unique"),{id:L(l.id,`${s}.id`),vertexIndices:d,normalIndices:p}});return t.length===0&&u("missing-topology",`${e}.polygons`,"expected at least one polygon"),V(t.map(i=>i.id),`${e}.polygons`),{vertices:o,normals:a,polygons:t}}function Bn(n,e,r){let o=I(n,e,["atlas","fallback","height","id","materialId","matrix","polygonId","shapeId","strategy","width"]),a=F(o.strategy,`${e}.strategy`);En.has(a)||u("invalid-strategy",`${e}.strategy`,"unknown render strategy");let t=L(o.polygonId,`${e}.polygonId`),i=L(o.shapeId,`${e}.shapeId`),c=L(o.materialId,`${e}.materialId`);r.polygonIds.has(t)||u("unknown-reference",`${e}.polygonId`,t),r.shapeIds.has(i)||u("unknown-reference",`${e}.shapeId`,i),r.materialIds.has(c)||u("unknown-reference",`${e}.materialId`,c);let s=N(o.width,`${e}.width`),l=N(o.height,`${e}.height`);(s<=0||l<=0)&&u("invalid-size",e,"leaf dimensions must be positive");let d=a==="atlas-slice"||a==="direct-image",p=o.atlas===null?null:Qe(o.atlas,`${e}.atlas`);d!==(p!==null)&&u("invalid-strategy",`${e}.atlas`,d?"image strategies require an atlas/source slice":"solid strategies cannot declare an atlas/source slice");let m=o.fallback===null?null:_n(o.fallback,`${e}.fallback`);return m!==null&&a!=="solid-triangle"&&u("invalid-strategy",`${e}.fallback`,"only solid-triangle leaves may declare a prepared fallback"),{id:L(o.id,`${e}.id`),polygonId:t,shapeId:i,materialId:c,strategy:a,width:s,height:l,matrix:Y(o.matrix,`${e}.matrix`),atlas:p,fallback:m}}function _n(n,e){let r=I(n,e,["atlas","height","matrixFromLeaf","width"]),o=U(r.width,`${e}.width`,1),a=U(r.height,`${e}.height`,1),t=Qe(r.atlas,`${e}.atlas`);return(t.width!==o||t.height!==a)&&u("invalid-size",e,"fallback dimensions must match its per-polygon atlas slice"),{width:o,height:a,matrixFromLeaf:Y(r.matrixFromLeaf,`${e}.matrixFromLeaf`),atlas:t}}function Qe(n,e){let r=I(n,e,["height","pageHeight","pageWidth","resourcePath","width","x","y"]),o={resourcePath:Ze(r.resourcePath,`${e}.resourcePath`),x:U(r.x,`${e}.x`),y:U(r.y,`${e}.y`),width:U(r.width,`${e}.width`,1),height:U(r.height,`${e}.height`,1),pageWidth:U(r.pageWidth,`${e}.pageWidth`,1),pageHeight:U(r.pageHeight,`${e}.pageHeight`,1)};return(o.x+o.width>o.pageWidth||o.y+o.height>o.pageHeight)&&u("out-of-range",e,"slice must fit inside its page"),o}function Jn(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&u("invalid-type",e,"expected a deformation object");let o=F(n.kind,`${e}.kind`);if(o==="none")return I(n,e,["kind"]),{kind:o};if(o==="morph-regions"){let a=I(n,e,["kind","targets"]),t=A(a.targets,`${e}.targets`).map((i,c)=>{let s=`${e}.targets[${c}]`,l=I(i,s,["deltas","id"]),d=A(l.deltas,`${s}.deltas`).map((m,M)=>{let P=`${s}.deltas[${M}]`,x=I(m,P,["normal","position","vertexIndex"]),f=x.position===null?null:te(x.position,`${P}.position`),$=x.normal===null?null:te(x.normal,`${P}.normal`);return f===null&&$===null&&u("empty-delta",P,"expected a position or normal delta"),{vertexIndex:ge(x.vertexIndex,`${P}.vertexIndex`,r.vertices.length),position:f,normal:$}});d.length===0&&u("missing-deltas",`${s}.deltas`,"expected at least one delta");let p=d.map(m=>String(m.vertexIndex));return V(p,`${s}.deltas`),{id:L(l.id,`${s}.id`),deltas:d}});return t.length===0&&u("missing-targets",`${e}.targets`,"expected at least one target"),V(t.map(i=>i.id),`${e}.targets`),{kind:o,targets:t}}if(o==="joint-skin"){let a=I(n,e,["joints","kind","vertices"]),t=A(a.joints,`${e}.joints`).map((l,d)=>{let p=`${e}.joints[${d}]`,m=I(l,p,["id","inverseBindMatrix","parentId","restMatrix"]);return{id:L(m.id,`${p}.id`),parentId:m.parentId===null?null:L(m.parentId,`${p}.parentId`),restMatrix:Y(m.restMatrix,`${p}.restMatrix`),inverseBindMatrix:Y(m.inverseBindMatrix,`${p}.inverseBindMatrix`)}});t.length===0&&u("missing-joints",`${e}.joints`,"expected at least one joint"),V(t.map(l=>l.id),`${e}.joints`),Un(t,`${e}.joints`);let i=new Set(t.map(l=>l.id)),c=A(a.vertices,`${e}.vertices`).map((l,d)=>{let p=`${e}.vertices[${d}]`,m=I(l,p,["influences","vertexIndex"]),M=ge(m.vertexIndex,`${p}.vertexIndex`,r.vertices.length),P=A(m.influences,`${p}.influences`).map((f,$)=>{let v=`${p}.influences[${$}]`,O=I(f,v,["jointId","weight"]),C=L(O.jointId,`${v}.jointId`);i.has(C)||u("unknown-reference",`${v}.jointId`,C);let z=N(O.weight,`${v}.weight`);return(z<=0||z>1)&&u("invalid-weight",`${v}.weight`,"expected 0 < weight <= 1"),{jointId:C,weight:z}});P.length===0&&u("missing-influences",`${p}.influences`,"expected at least one influence"),V(P.map(f=>f.jointId),`${p}.influences`);let x=P.reduce((f,$)=>f+$.weight,0);return Math.abs(x-1)>1e-6&&u("invalid-weight",`${p}.influences`,"weights must sum to 1"),{vertexIndex:M,influences:P}});c.length!==r.vertices.length&&u("missing-skin-vertex",`${e}.vertices`,"every topology vertex must have one skin record");let s=c.map(l=>String(l.vertexIndex));return V(s,`${e}.vertices`),{kind:o,joints:t,vertices:c}}u("invalid-deformation",`${e}.kind`,`unknown deformation kind ${o}`)}function Un(n,e){let r=new Map(n.map(a=>[a.id,a]));n.filter(a=>a.parentId===null).length!==1&&u("invalid-hierarchy",e,"expected exactly one root joint");for(let a of n){a.parentId!==null&&!r.has(a.parentId)&&u("unknown-reference",e,`joint ${a.id} references ${a.parentId}`);let t=new Set,i=a;for(;i;)t.has(i.id)&&u("invalid-hierarchy",e,`cycle at joint ${i.id}`),t.add(i.id),i=i.parentId===null?void 0:r.get(i.parentId)}}function Dn(n){return n==="control-value"||n==="morph-weight"?1:n==="joint-rotation"?4:n==="shape-matrix"?16:3}function Fn(n,e,r,o){let a=I(n,e,["interpolation","target","targetId","timesMs","values"]),t=F(a.target,`${e}.target`);Nn.has(t)||u("invalid-animation-target",`${e}.target`,t);let i=L(a.targetId,`${e}.targetId`);(t==="control-value"?r.controlIds:t==="morph-weight"?r.targetIds:t==="shape-matrix"?r.shapeIds:r.jointIds).has(i)||u("unknown-reference",`${e}.targetId`,i);let s=F(a.interpolation,`${e}.interpolation`);s!=="linear"&&s!=="step"&&u("invalid-interpolation",`${e}.interpolation`,s),t==="shape-matrix"&&s!=="step"&&u("invalid-interpolation",`${e}.interpolation`,"shape matrices require step interpolation");let l=A(a.timesMs,`${e}.timesMs`).map((p,m)=>N(p,`${e}.timesMs[${m}]`)),d=A(a.values,`${e}.values`).map((p,m)=>{let M=A(p,`${e}.values[${m}]`),P=Dn(t);M.length!==P&&u("invalid-animation-value",`${e}.values[${m}]`,`expected ${P} components`);let x=M.map((f,$)=>N(f,`${e}.values[${m}][${$}]`));return t==="joint-rotation"&&Math.hypot(...x)<=1e-12&&u("invalid-animation-value",`${e}.values[${m}]`,"quaternion must be non-zero"),x});return(l.length===0||l.length!==d.length)&&u("invalid-animation-samples",e,"times and values must have the same non-zero length"),(l[0]!==0||l.some((p,m)=>p<0||p>o||m>0&&p<=l[m-1]))&&u("invalid-animation-time",`${e}.timesMs`,"times must start at zero and increase within the clip"),{target:t,targetId:i,interpolation:s,timesMs:l,values:d}}function Hn(n,e,r,o){let a=I(n,e,["durationMs","frames","loop"]),t=N(a.durationMs,`${e}.durationMs`);t<=0&&u("invalid-duration",`${e}.durationMs`,"expected a positive duration");let i=A(a.frames,`${e}.frames`).map((c,s)=>{let l=`${e}.frames[${s}]`,d=I(c,l,["leaves","modelMatrix","shapes","timeMs"]),p=N(d.timeMs,`${l}.timeMs`),m=A(d.shapes,`${l}.shapes`).map((P,x)=>{let f=`${l}.shapes[${x}]`,$=I(P,f,["matrix","shapeId"]),v=L($.shapeId,`${f}.shapeId`);return o.has(v)||u("unknown-reference",`${f}.shapeId`,v),{shapeId:v,matrix:Y($.matrix,`${f}.matrix`)}});V(m.map(P=>P.shapeId),`${l}.shapes`);let M=A(d.leaves,`${l}.leaves`).map((P,x)=>{let f=`${l}.leaves[${x}]`,$=I(P,f,["atlasRow","leafId","matrix","opacity","visible"]),v=L($.leafId,`${f}.leafId`);r.has(v)||u("unknown-reference",`${f}.leafId`,v);let O=$.opacity===null?null:N($.opacity,`${f}.opacity`);return O!==null&&(O<0||O>1)&&u("out-of-range",`${f}.opacity`,"expected 0 <= opacity <= 1"),{leafId:v,matrix:$.matrix===null?null:Y($.matrix,`${f}.matrix`),visible:$.visible===null?null:ke($.visible,`${f}.visible`),opacity:O,atlasRow:$.atlasRow===null?null:U($.atlasRow,`${f}.atlasRow`)}});return V(M.map(P=>P.leafId),`${l}.leaves`),{timeMs:p,modelMatrix:d.modelMatrix===null?null:Y(d.modelMatrix,`${l}.modelMatrix`),shapes:m,leaves:M}});return i.length===0&&u("missing-frames",`${e}.frames`,"expected at least one frame"),(i[0].timeMs!==0||i.some((c,s)=>c.timeMs<0||c.timeMs>t||s>0&&c.timeMs<=i[s-1].timeMs))&&u("invalid-frame-time",`${e}.frames`,"frames must start at zero and increase within the timeline"),{durationMs:t,loop:ke(a.loop,`${e}.loop`),frames:i}}function zn(n,e){let r=["retained-render"];return n==="morph-regions"&&r.push("morph-targets","sparse-updates"),n==="joint-skin"&&r.push("joint-skinning","sparse-updates"),n==="prepared-playback"&&r.push("prepared-playback","sparse-updates"),e.controls.length>0&&r.push("semantic-controls"),e.springs.length>0&&r.push("springs"),e.animations.length>0&&r.push("animation"),r}function ce(n){let r=I(n,"$",["animations","budgets","capabilities","controls","deformation","identity","materials","playback","profile","provenance","render","schema","springs","topology"]);r.schema!==X&&u("invalid-schema","$.schema",`expected ${X}`);let o=I(r.identity,"$.identity",["id","name","revision"]),a={id:L(o.id,"$.identity.id"),name:F(o.name,"$.identity.name"),revision:F(o.revision,"$.identity.revision")};Ye.test(a.revision)||u("invalid-revision","$.identity.revision","expected x.y.z");let t=F(r.profile,"$.profile");Tn.has(t)||u("invalid-profile","$.profile",t);let i=A(r.capabilities,"$.capabilities").map((b,R)=>{let h=F(b,`$.capabilities[${R}]`);return Ln.has(h)||u("invalid-capability",`$.capabilities[${R}]`,h),h});V(i,"$.capabilities"),i.some((b,R)=>R>0&&b<=i[R-1])&&u("non-canonical-order","$.capabilities","capabilities must be sorted");let c=I(r.budgets,"$.budgets",["maxBytes","maxFrames","maxJoints","maxLeaves","maxPolygons","maxResources","maxVertices"]),s={maxVertices:U(c.maxVertices,"$.budgets.maxVertices"),maxPolygons:U(c.maxPolygons,"$.budgets.maxPolygons"),maxLeaves:U(c.maxLeaves,"$.budgets.maxLeaves"),maxFrames:U(c.maxFrames,"$.budgets.maxFrames"),maxJoints:U(c.maxJoints,"$.budgets.maxJoints"),maxResources:U(c.maxResources,"$.budgets.maxResources"),maxBytes:U(c.maxBytes,"$.budgets.maxBytes")},l=Vn(r.topology,"$.topology"),d=A(r.materials,"$.materials").map((b,R)=>{let h=`$.materials[${R}]`,w=I(b,h,["color","id"]),T=A(w.color,`${h}.color`);T.length!==4&&u("invalid-color",`${h}.color`,"expected four components");let J=T.map((G,W)=>{let Q=N(G,`${h}.color[${W}]`);return(Q<0||Q>1)&&u("out-of-range",`${h}.color[${W}]`,"expected 0 <= component <= 1"),Q});return{id:L(w.id,`${h}.id`),color:J}});d.length===0&&u("missing-materials","$.materials","expected at least one material"),V(d.map(b=>b.id),"$.materials");let p=I(r.render,"$.render",["leaves","modelMatrix","shapes"]),m=A(p.shapes,"$.render.shapes").map((b,R)=>{let h=`$.render.shapes[${R}]`,w=I(b,h,["id","matrix"]);return{id:L(w.id,`${h}.id`),matrix:Y(w.matrix,`${h}.matrix`)}});m.length===0&&u("missing-shapes","$.render.shapes","expected at least one shape"),V(m.map(b=>b.id),"$.render.shapes");let M=A(p.leaves,"$.render.leaves").map((b,R)=>Bn(b,`$.render.leaves[${R}]`,{polygonIds:new Set(l.polygons.map(h=>h.id)),shapeIds:new Set(m.map(h=>h.id)),materialIds:new Set(d.map(h=>h.id))}));V(M.map(b=>b.id),"$.render.leaves"),V(M.map(b=>b.polygonId),"$.render.leaves[*].polygonId"),M.length!==l.polygons.length&&u("unstable-topology","$.render.leaves","every polygon must bind exactly one retained leaf");let P={modelMatrix:Y(p.modelMatrix,"$.render.modelMatrix"),shapes:m,leaves:M},x=Jn(r.deformation,"$.deformation",l);(t==="static-prepared"||t==="prepared-playback"?x.kind!=="none":x.kind!==t)&&u("profile-mismatch","$.deformation.kind",`does not match profile ${t}`);let f=new Set(x.kind==="morph-regions"?x.targets.map(b=>b.id):[]),$=new Set(x.kind==="joint-skin"?x.joints.map(b=>b.id):[]),v=A(r.controls,"$.controls").map((b,R)=>{let h=`$.controls[${R}]`,w=I(b,h,["anchor","axis","id","initial","maximum","minimum","radius","targets"]),T=N(w.minimum,`${h}.minimum`),J=N(w.maximum,`${h}.maximum`),G=N(w.initial,`${h}.initial`);(T>J||G<T||G>J)&&u("invalid-control-bounds",h,"expected minimum <= initial <= maximum");let W=te(w.anchor,`${h}.anchor`),Q=te(w.axis,`${h}.axis`);Math.hypot(...Q)<1e-9&&u("invalid-control-axis",`${h}.axis`,"axis must be non-zero");let Ge=N(w.radius,`${h}.radius`);Ge<=0&&u("invalid-control-radius",`${h}.radius`,"radius must be positive");let qe=A(w.targets,`${h}.targets`).map(($e,On)=>{let fe=`${h}.targets[${On}]`,We=I($e,fe,["scale","targetId"]),ve=L(We.targetId,`${fe}.targetId`);return f.has(ve)||u("unknown-reference",`${fe}.targetId`,ve),{targetId:ve,scale:N(We.scale,`${fe}.scale`)}});return V(qe.map($e=>$e.targetId),`${h}.targets`),{id:L(w.id,`${h}.id`),anchor:W,axis:Q,radius:Ge,minimum:T,maximum:J,initial:G,targets:qe}});V(v.map(b=>b.id),"$.controls");let O=new Set(v.map(b=>b.id)),C=A(r.springs,"$.springs").map((b,R)=>{let h=`$.springs[${R}]`,w=I(b,h,["controlId","damping","id","stiffness"]),T=L(w.controlId,`${h}.controlId`);O.has(T)||u("unknown-reference",`${h}.controlId`,T);let J=N(w.stiffness,`${h}.stiffness`),G=N(w.damping,`${h}.damping`);return(J<=0||G<0)&&u("invalid-spring",h,"expected stiffness > 0 and damping >= 0"),{id:L(w.id,`${h}.id`),controlId:T,stiffness:J,damping:G}});V(C.map(b=>b.id),"$.springs");let z=new Set(m.map(b=>b.id)),g=A(r.animations,"$.animations").map((b,R)=>{let h=`$.animations[${R}]`,w=I(b,h,["channels","durationMs","id","loop"]),T=N(w.durationMs,`${h}.durationMs`);T<=0&&u("invalid-duration",`${h}.durationMs`,"expected a positive duration");let J=A(w.channels,`${h}.channels`).map((W,Q)=>Fn(W,`${h}.channels[${Q}]`,{controlIds:O,jointIds:$,shapeIds:z,targetIds:f},T));J.length===0&&u("missing-channels",`${h}.channels`,"expected at least one channel");let G=J.map(W=>`${W.target}:${W.targetId}`);return V(G,`${h}.channels`),{id:L(w.id,`${h}.id`),durationMs:T,loop:ke(w.loop,`${h}.loop`),channels:J}});V(g.map(b=>b.id),"$.animations");let k=r.playback===null?null:Hn(r.playback,"$.playback",new Set(M.map(b=>b.id)),z);t==="prepared-playback"!=(k!==null)&&u("profile-mismatch","$.playback","playback is required only by the prepared-playback profile");let S=I(r.provenance,"$.provenance",["generator","generatorVersion","sources"]),B=A(S.sources,"$.provenance.sources").map((b,R)=>{let h=`$.provenance.sources[${R}]`,w=I(b,h,["id","kind","license","sha256","uri"]),T=F(w.kind,`${h}.kind`);T!=="authored"&&T!=="generated"&&T!=="open-data"&&u("invalid-source-kind",`${h}.kind`,T);let J=F(w.uri,`${h}.uri`);(J.startsWith("/")||J.startsWith("file:")||J.includes("\\"))&&u("invalid-source-uri",`${h}.uri`,"local filesystem paths are forbidden");let G=w.sha256===null?null:F(w.sha256,`${h}.sha256`);return G!==null&&!jn.test(G)&&u("invalid-hash",`${h}.sha256`,"expected lowercase SHA-256"),{id:L(w.id,`${h}.id`),kind:T,uri:J,sha256:G,license:F(w.license,`${h}.license`)}});B.length===0&&u("missing-provenance","$.provenance.sources","expected at least one source"),V(B.map(b=>b.id),"$.provenance.sources");let D={generator:L(S.generator,"$.provenance.generator"),generatorVersion:F(S.generatorVersion,"$.provenance.generatorVersion"),sources:B};Ye.test(D.generatorVersion)||u("invalid-revision","$.provenance.generatorVersion","expected x.y.z");let xe=zn(t,{controls:v,springs:C,animations:g});for(let b of xe)i.includes(b)||u("missing-capability","$.capabilities",`profile requires ${b}`);let oe=x.kind==="joint-skin"?x.joints.length:0,_=k?.frames.length??0,q=[["maxVertices",l.vertices.length,s.maxVertices],["maxPolygons",l.polygons.length,s.maxPolygons],["maxLeaves",M.length,s.maxLeaves],["maxFrames",_,s.maxFrames],["maxJoints",oe,s.maxJoints]];for(let[b,R,h]of q)R>h&&u("budget-exceeded",`$.budgets.${b}`,`${R} exceeds ${h}`);return{schema:X,identity:a,profile:t,capabilities:i,budgets:s,topology:l,materials:d,render:P,deformation:x,controls:v,springs:C,animations:g,playback:k,provenance:D}}function de(n){return Ke.test(n)}function we(n){try{return Ze(n,"$"),!0}catch{return!1}}var E=class extends Error{constructor(e,r,o,a={}){super(`${r}: ${o}`),this.name="PolyMorphPackageError",this.code=e,this.path=r,"cause"in a&&(this.cause=a.cause)}};function Ie(n,e,r){if(n===null)return"null";if(typeof n=="string"||typeof n=="boolean")return JSON.stringify(n);if(typeof n=="number"){if(!Number.isFinite(n))throw new E("invalid-json",e,"numbers must be finite");return JSON.stringify(Object.is(n,-0)?0:n)}if(Array.isArray(n)){if(r.has(n))throw new E("invalid-json",e,"cycles are forbidden");r.add(n);let o=`[${n.map((a,t)=>Ie(a,`${e}[${t}]`,r)).join(",")}]`;return r.delete(n),o}if(typeof n=="object"&&n){if(r.has(n))throw new E("invalid-json",e,"cycles are forbidden");let o=Object.getPrototypeOf(n);if(o!==Object.prototype&&o!==null)throw new E("invalid-json",e,"expected a plain object");r.add(n);let a=n,t=`{${Object.keys(a).sort().map(i=>{let c=a[i];if(c===void 0||typeof c=="function"||typeof c=="symbol")throw new E("invalid-json",`${e}.${i}`,"value is not JSON");return`${JSON.stringify(i)}:${Ie(c,`${e}.${i}`,r)}`}).join(",")}}`;return r.delete(n),t}throw new E("invalid-json",e,"value is not JSON")}function Xe(n){return Ie(n,"$",new WeakSet)}function pe(n){return new TextEncoder().encode(Xe(n))}function Gn(n,e="$"){let r;try{r=new TextDecoder("utf-8",{fatal:!0}).decode(n)}catch{throw new E("invalid-utf8",e,"expected UTF-8 bytes")}try{return JSON.parse(r)}catch{throw new E("invalid-json",e,"expected valid JSON")}}async function ae(n){if(!globalThis.crypto?.subtle)throw new E("missing-crypto","$","Web Crypto is required");let e=Uint8Array.from(n),r=await globalThis.crypto.subtle.digest("SHA-256",e);return[...new Uint8Array(r)].map(o=>o.toString(16).padStart(2,"0")).join("")}var qn=/^[a-f0-9]{64}$/,Wn=/^\d+\.\d+\.\d+$/,Yn=/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/,Kn=new Set(["joint-skin","morph-regions","prepared-playback","static-prepared"]),Zn=new Set(["data","image","model"]);function j(n,e,r){throw new E(n,e,r)}function ye(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&j("invalid-type",e,"expected an object");let o=Object.keys(n).sort(),a=[...r].sort();return(o.length!==a.length||o.some((t,i)=>t!==a[i]))&&j("invalid-keys",e,`expected exactly ${a.join(", ")}`),n}function en(n,e){return Array.isArray(n)||j("invalid-type",e,"expected an array"),n}function K(n,e){return(typeof n!="string"||n.length===0)&&j("invalid-string",e,"expected a non-empty string"),n}function Ae(n,e){let r=K(n,e);return de(r)||j("invalid-id",e,"expected a normalized kebab-case id"),r}function Re(n,e){let r=K(n,e);return we(r)||j("invalid-path",e,"expected a normalized package-relative path"),r}function nn(n,e){let r=K(n,e);return Wn.test(r)||j("invalid-revision",e,"expected x.y.z"),r}function rn(n,e){let r=K(n,e);return Kn.has(r)||j("invalid-profile",e,r),r}function on(n,e){let r=K(n,e);return qn.test(r)||j("invalid-hash",e,"expected lowercase SHA-256"),r}function Qn(n,e){return(typeof n!="number"||!Number.isSafeInteger(n)||n<0)&&j("invalid-bytes",e,"expected a non-negative safe integer"),n}function Xn(n,e){let r=ye(n,e,["bytes","mediaType","path","role","sha256"]),o=K(r.role,`${e}.role`);Zn.has(o)||j("invalid-role",`${e}.role`,o);let a=K(r.mediaType,`${e}.mediaType`).toLowerCase();return(!Yn.test(a)||a!==r.mediaType)&&j("invalid-media-type",`${e}.mediaType`,"expected a normalized type/subtype"),o==="image"&&!a.startsWith("image/")&&j("invalid-media-type",`${e}.mediaType`,"image resources require an image media type"),{path:Re(r.path,`${e}.path`),role:o,mediaType:a,bytes:Qn(r.bytes,`${e}.bytes`),sha256:on(r.sha256,`${e}.sha256`)}}function Se(n,e){let r=new Set;for(let o of n)r.has(o)&&j("duplicate",e,o),r.add(o)}function tn(n,e){n.some((r,o)=>o>0&&r<=n[o-1])&&j("non-canonical-order",e,"entries must be unique and sorted")}function Oe(n){let e=ye(n,"$",["identity","modelPath","profile","resources","schema"]);e.schema!==ne&&j("invalid-schema","$.schema",`expected ${ne}`);let r=ye(e.identity,"$.identity",["id","name","revision"]),o={id:Ae(r.id,"$.identity.id"),name:K(r.name,"$.identity.name"),revision:nn(r.revision,"$.identity.revision")},a=en(e.resources,"$.resources").map((s,l)=>Xn(s,`$.resources[${l}]`));a.length===0&&j("missing-resource","$.resources","expected at least the model resource");let t=a.map(s=>s.path);Se(t,"$.resources"),tn(t,"$.resources");let i=Re(e.modelPath,"$.modelPath"),c=a.filter(s=>s.role==="model");return(c.length!==1||c[0].path!==i)&&j("invalid-model-resource","$.resources","expected exactly one model resource matching modelPath"),c[0].mediaType!=="application/json"&&j("invalid-model-resource","$.resources","model resource must be application/json"),{schema:ne,identity:o,profile:rn(e.profile,"$.profile"),modelPath:i,resources:a}}function er(n,e){let r=ye(n,e,["id","manifestPath","manifestSha256","name","profile","revision"]),o=Re(r.manifestPath,`${e}.manifestPath`);return o.endsWith("/manifest.json")||j("invalid-manifest-path",`${e}.manifestPath`,"expected a package manifest.json path"),{id:Ae(r.id,`${e}.id`),name:K(r.name,`${e}.name`),revision:nn(r.revision,`${e}.revision`),profile:rn(r.profile,`${e}.profile`),manifestPath:o,manifestSha256:on(r.manifestSha256,`${e}.manifestSha256`)}}function Ce(n){let e=ye(n,"$",["defaultId","packages","schema"]);e.schema!==ee&&j("invalid-schema","$.schema",`expected ${ee}`);let r=en(e.packages,"$.packages").map((t,i)=>er(t,`$.packages[${i}]`));r.length===0&&j("missing-package","$.packages","expected at least one package");let o=r.map(t=>t.id);Se(o,"$.packages"),tn(o,"$.packages"),Se(r.map(t=>t.manifestPath),"$.packages[*].manifestPath");let a=Ae(e.defaultId,"$.defaultId");return o.includes(a)||j("unknown-default","$.defaultId",a),{schema:ee,defaultId:a,packages:r}}var je="model.json";function nr(n){return[...new Set(n.render.leaves.flatMap(e=>[...e.atlas?[e.atlas.resourcePath]:[],...e.fallback?[e.fallback.atlas.resourcePath]:[]]))].sort()}async function Te(n,e=[]){let r=ce(n),o=pe(r),a=new Map([[je,o]]),t=[{path:je,role:"model",mediaType:"application/json",bytes:o.byteLength,sha256:await ae(o)}];for(let l of e){if(a.has(l.path))throw new E("duplicate",l.path,"resource path is already present");let d=Uint8Array.from(l.bytes);a.set(l.path,d),t.push({path:l.path,role:l.role,mediaType:l.mediaType,bytes:d.byteLength,sha256:await ae(d)})}for(let l of nr(r)){let d=t.find(p=>p.path===l);if(!d)throw new E("missing-resource",l,"model image is not included in the package");if(d.role!=="image")throw new E("invalid-role",l,"model image resource must use the image role")}t.sort((l,d)=>l.path<d.path?-1:l.path>d.path?1:0);let i=Oe({schema:ne,identity:r.identity,profile:r.profile,modelPath:je,resources:t}),c=t.reduce((l,d)=>l+d.bytes,0);if(t.length>r.budgets.maxResources)throw new E("budget-exceeded","$.budgets.maxResources",`${t.length} resources exceed ${r.budgets.maxResources}`);if(c>r.budgets.maxBytes)throw new E("budget-exceeded","$.budgets.maxBytes",`${c} bytes exceed ${r.budgets.maxBytes}`);let s=pe(i);return{manifest:i,manifestBytes:s,manifestSha256:await ae(s),files:a}}async function rr(n,e){let r=e.map(t=>({id:t.manifest.identity.id,name:t.manifest.identity.name,revision:t.manifest.identity.revision,profile:t.manifest.profile,manifestPath:t.manifestPath,manifestSha256:t.manifestSha256}));r.sort((t,i)=>t.id<i.id?-1:t.id>i.id?1:0);let o=Ce({schema:ee,defaultId:n,packages:r}),a=pe(o);return{catalog:o,bytes:a,sha256:await ae(a)}}function or(n,e){if(e.identity.id!==n.identity.id||e.identity.name!==n.identity.name||e.identity.revision!==n.identity.revision||e.profile!==n.profile)throw new E("profile-mismatch","$.model","model identity or profile does not match its manifest")}import{readFile as tr}from"fs/promises";import{dirname as ar,isAbsolute as sn,relative as ir,resolve as an,sep as sr}from"path";var Pe=class extends Error{constructor(e,r,o){super(`${r}: ${o}`),this.name="PolyMorphPrepareError",this.code=e,this.path=r}};function y(n,e,r){throw new Pe(n,e,r)}var me="polycss-morph.prepare@1";function ie(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&y("invalid-config",e,"expected an object");let o=Object.keys(n).sort(),a=[...r].sort();return(o.length!==a.length||o.some((t,i)=>t!==a[i]))&&y("invalid-config",e,`expected exactly ${a.join(", ")}`),n}function ue(n,e){return Array.isArray(n)||y("invalid-config",e,"expected an array"),n}function Z(n,e){return(typeof n!="string"||n.length===0||n!==n.trim())&&y("invalid-config",e,"expected non-empty trimmed text"),n}function Le(n,e){let r=Z(n,e);return de(r)||y("invalid-config",e,"expected a normalized kebab-case id"),r}function ln(n,e){return(typeof n!="number"||!Number.isFinite(n))&&y("invalid-config",e,"expected a finite number"),n}function re(n,e){let r=ln(n,e);return(!Number.isSafeInteger(r)||r<1)&&y("invalid-config",e,"expected a positive integer"),r}function lr(n){let e=ie(n,"$.budgets",["maxBytes","maxFrames","maxJoints","maxLeaves","maxPolygons","maxResources","maxVertices"]);return{maxVertices:re(e.maxVertices,"$.budgets.maxVertices"),maxPolygons:re(e.maxPolygons,"$.budgets.maxPolygons"),maxLeaves:re(e.maxLeaves,"$.budgets.maxLeaves"),maxFrames:re(e.maxFrames,"$.budgets.maxFrames"),maxJoints:re(e.maxJoints,"$.budgets.maxJoints"),maxResources:re(e.maxResources,"$.budgets.maxResources"),maxBytes:re(e.maxBytes,"$.budgets.maxBytes")}}function cn(n){let e=ie(n,"$",["animations","budgets","controls","identity","morphAliases","profile","schema","source","springs","transform"]);e.schema!==me&&y("invalid-config","$.schema",`expected ${me}`);let r=ie(e.identity,"$.identity",["id","name","revision"]),o={id:Le(r.id,"$.identity.id"),name:Z(r.name,"$.identity.name"),revision:Z(r.revision,"$.identity.revision")};/^\d+\.\d+\.\d+$/u.test(o.revision)||y("invalid-config","$.identity.revision","expected x.y.z");let a=Z(e.profile,"$.profile");a!=="morph-regions"&&a!=="static-prepared"&&y("invalid-config","$.profile","generic preparation supports morph-regions or static-prepared");let t=ie(e.source,"$.source",["id","kind","license","path","uri"]),i=Z(t.kind,"$.source.kind");i!=="authored"&&i!=="generated"&&i!=="open-data"&&y("invalid-config","$.source.kind","unknown source kind");let c=Z(t.path,"$.source.path");(sn(c)||c.includes("\\")||c.split("/").some(f=>f===""||f==="."||f===".."))&&y("unsafe-path","$.source.path","expected a normalized config-relative path");let s={id:Le(t.id,"$.source.id"),kind:i,path:c,uri:Z(t.uri,"$.source.uri"),license:Z(t.license,"$.source.license")};(s.uri.startsWith("/")||s.uri.startsWith("file:")||s.uri.includes("\\"))&&y("invalid-config","$.source.uri","local filesystem paths are forbidden");let l=ie(e.transform,"$.transform",["axes","center","scale","signs"]),d=ue(l.axes,"$.transform.axes");(d.length!==3||d.some(f=>f!=="x"&&f!=="y"&&f!=="z")||new Set(d).size!==3)&&y("invalid-config","$.transform.axes","expected each source axis exactly once");let p=ue(l.signs,"$.transform.signs");(p.length!==3||p.some(f=>f!==-1&&f!==1))&&y("invalid-config","$.transform.signs","expected three values of -1 or 1");let m=ln(l.scale,"$.transform.scale");m>0||y("invalid-config","$.transform.scale","expected a positive scale"),typeof l.center!="boolean"&&y("invalid-config","$.transform.center","expected a boolean");let M=ie(e.morphAliases,"$.morphAliases",Object.keys(e.morphAliases??{})),P=Object.fromEntries(Object.entries(M).map(([f,$])=>[Z(f,"$.morphAliases key"),Le($,`$.morphAliases.${f}`)]).sort(([f],[$])=>f<$?-1:f>$?1:0));return new Set(Object.values(P)).size!==Object.keys(P).length&&y("invalid-config","$.morphAliases","prepared target ids must be unique"),a==="morph-regions"!=Object.keys(P).length>0&&y("invalid-config","$.morphAliases","morph-regions requires aliases and static-prepared forbids them"),{schema:me,identity:o,profile:a,source:s,transform:{axes:d,signs:p,scale:m,center:l.center},morphAliases:P,controls:structuredClone(ue(e.controls,"$.controls")),springs:structuredClone(ue(e.springs,"$.springs")),animations:structuredClone(ue(e.animations,"$.animations")),budgets:lr(e.budgets)}}async function Ee(n){let e;try{e=JSON.parse(await tr(n,"utf8"))}catch{y("invalid-config","$","config is not readable UTF-8 JSON")}return cn(e)}function Ne(n,e){let r=an(ar(n)),o=an(r,e),a=ir(r,o);return(a===".."||a.startsWith(`..${sr}`)||sn(a))&&y("unsafe-path","$.source.path","source escapes its authoring directory"),o}import{computeSolidTrianglePlanFromCssPoints as wr,SOLID_TRIANGLE_CANONICAL_SIZE as un}from"@layoutit/polycss";import{deflateSync as cr}from"zlib";import{computeTextureAtlasPlanPublic as dr,packTextureAtlasPlansWithScale as pr}from"@layoutit/polycss";var Me=1.5,se=4,yr=Uint8Array.from([137,80,78,71,13,10,26,10]);function H(n){let e=Number(n.toFixed(10));return Object.is(e,-0)?0:e}function pn(n,e){let r=n.split(",").map(Number);return(r.length!==16||r.some(o=>!Number.isFinite(o)))&&y("unrenderable-triangle",e,"PolyCSS produced an invalid fallback matrix"),r.map(H)}function mr(n,e){let r=new Array(16).fill(0);for(let o=0;o<4;o+=1)for(let a=0;a<4;a+=1){let t=0;for(let i=0;i<4;i+=1)t+=n[i*4+a]*e[o*4+i];r[o*4+a]=H(t)}return r}function ur(n,e){let r=n[0],o=n[4],a=n[8],t=n[1],i=n[5],c=n[9],s=n[2],l=n[6],d=n[10],p=r*(i*d-c*l)-o*(t*d-c*s)+a*(t*l-i*s);(!Number.isFinite(p)||Math.abs(p)<=1e-12)&&y("unrenderable-triangle",e,"solid triangle matrix is not invertible");let m=1/p,M=(i*d-c*l)*m,P=(a*l-o*d)*m,x=(o*c-a*i)*m,f=(c*s-t*d)*m,$=(r*d-a*s)*m,v=(a*t-r*c)*m,O=(t*l-i*s)*m,C=(o*s-r*l)*m,z=(r*i-o*t)*m,g=n[12],k=n[13],S=n[14];return[H(M),H(f),H(O),0,H(P),H($),H(C),0,H(x),H(v),H(z),0,H(-(M*g+P*k+x*S)),H(-(f*g+$*k+v*S)),H(-(O*g+C*k+z*S)),1]}function fr(n,e){if(e===0)return n;let r=pn(n,"$.render.fallback"),o=[...r];return o[12]-=e*r[0]+e*r[4],o[13]-=e*r[1]+e*r[5],o[14]-=e*r[2]+e*r[6],o.map(H).join(",")}function hr(n){let[e,r,o]=n,a=[r[0]-e[0],r[1]-e[1],r[2]-e[2]],t=[o[0]-e[0],o[1]-e[1],o[2]-e[2]],i=[a[1]*t[2]-a[2]*t[1],a[2]*t[0]-a[0]*t[2],a[0]*t[1]-a[1]*t[0]],c=Math.hypot(...i);if(c<=1e-12)return null;let s=[i[0]/c,i[1]/c,i[2]/c];return{normal:s,plane:s[0]*e[0]+s[1]*e[1]+s[2]*e[2]}}function gr(n){let e=n.map(a=>hr(a.vertices)),r=new Map;for(let a=0;a<n.length;a+=1){let t=n[a].vertexIndices;for(let i=0;i<3;i+=1){let c=t[i],s=t[(i+1)%3],l=c<s?`${c}:${s}`:`${s}:${c}`,d={polygonIndex:a,edgeIndex:i},p=r.get(l);p?p.push(d):r.set(l,[d])}}let o=Array.from({length:n.length},()=>new Set);for(let a of r.values())for(let t=0;t<a.length;t+=1)for(let i=t+1;i<a.length;i+=1){let c=a[t],s=a[i],l=n[c.polygonIndex],d=n[s.polygonIndex],p=e[c.polygonIndex],m=e[s.polygonIndex];l.materialId!==d.materialId||!p||!m||p.normal[0]*m.normal[0]+p.normal[1]*m.normal[1]+p.normal[2]*m.normal[2]<1-1e-6||Math.abs(p.plane-m.plane)>1e-5||(o[c.polygonIndex].add(c.edgeIndex),o[s.polygonIndex].add(s.edgeIndex))}return o}function Pr(n,e){return n.map((r,o)=>{let a={color:"#ffffff",vertices:r.vertices.map(([s,l,d])=>[l,s,d])},t=dr(a,o,{tileSize:1,layerElevation:1,seamBleed:0});t||y("unrenderable-triangle",`$.render.leaves[${o}].fallback`,"PolyCSS produced no per-polygon atlas plan");let i=e[o],c=i.size>0?Math.ceil(Me):0;return{...t,matrix:fr(t.matrix,c),canvasW:t.canvasW+c*2,canvasH:t.canvasH+c*2,screenPts:t.screenPts.map(s=>s+c),seamBleed:i.size>0?Me:void 0,seamBleedEdges:new Set(i),seamBleedEdgeAmounts:i.size>0?new Map([...i].map(s=>[s,Me])):void 0}})}function Mr(n,e,r,o){let a=0;for(let i=0;i<n.length;i+=2){let c=(i+2)%n.length;a+=n[i]*n[c+1]-n[c]*n[i+1]}let t=a>=0?1:-1;for(let i=0;i<n.length;i+=2){let c=i/2,s=(i+2)%n.length,l=n[i],d=n[i+1],p=n[s],m=n[s+1],M=p-l,P=m-d,x=Math.hypot(M,P);if(x<=1e-12||t*(M*(o-d)-P*(r-l))/x<-(e.has(c)?Me:0))return!1}return!0}function br(n,e,r){let o=0,a=n.seamBleedEdges??new Set;for(let t=0;t<se;t+=1)for(let i=0;i<se;i+=1)Mr(n.screenPts,a,e+(i+.5)/se,r+(t+.5)/se)&&(o+=1);return Math.round(o*255/(se*se))}function xr(n){let e=4294967295;for(let r of n){e^=r;for(let o=0;o<8;o+=1)e=e>>>1^3988292384&-(e&1)}return(e^4294967295)>>>0}function Ve(n,e){let r=new TextEncoder().encode(n),o=new Uint8Array(12+e.byteLength),a=new DataView(o.buffer);return a.setUint32(0,e.byteLength),o.set(r,4),o.set(e,8),a.setUint32(8+e.byteLength,xr(o.subarray(4,8+e.byteLength))),o}function $r(n){let e=new Uint8Array(n.reduce((o,a)=>o+a.byteLength,0)),r=0;for(let o of n)e.set(o,r),r+=o.byteLength;return e}function vr(n,e,r){let o=1+n*4,a=new Uint8Array(e*o);for(let c of r)for(let s=0;s<c.canvasH;s+=1)for(let l=0;l<c.canvasW;l+=1){let d=br(c,l,s);if(d===0)continue;let p=(c.y+s)*o+1+(c.x+l)*4;a[p]=255,a[p+1]=255,a[p+2]=255,a[p+3]=d}let t=new Uint8Array(13),i=new DataView(t.buffer);return i.setUint32(0,n),i.setUint32(4,e),t[8]=8,t[9]=6,$r([yr,Ve("IHDR",t),Ve("IDAT",cr(a,{level:9})),Ve("IEND",new Uint8Array)])}function dn(n){return`assets/solid-triangles-${String(n).padStart(3,"0")}.png`}function yn(n){let e=Pr(n,gr(n)),{packed:r,atlasScale:o}=pr(e,1,null,"local");o!==1&&y("invalid-atlas","$.render.fallback","per-polygon fallback atlas must retain CSS-pixel resolution");let a=n.map((i,c)=>{let s=r.entries[c];s||y("invalid-atlas",`$.render.leaves[${c}].fallback`,"per-polygon fallback was not packed");let l=r.pages[s.pageIndex],d=pn(s.atlasMatrix,`$.render.leaves[${c}].fallback.matrix`);return{width:s.canvasW,height:s.canvasH,matrixFromLeaf:mr(ur(i.leafMatrix,`$.render.leaves[${c}].matrix`),d),atlas:{resourcePath:dn(s.pageIndex),x:s.x,y:s.y,width:s.canvasW,height:s.canvasH,pageWidth:l.width,pageHeight:l.height}}}),t=r.pages.map((i,c)=>({path:dn(c),width:i.width,height:i.height,bytes:vr(i.width,i.height,i.entries)}));return{fallbacks:a,pages:t}}var mn={name:"@layoutit/polycss-morph",version:"0.2.10",description:"Prepared retained-model deformation and playback for PolyCSS.",type:"module",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",keywords:["polycss","morph","animation","skinning","3d","css","matrix3d","dom"],license:"MIT",repository:{type:"git",url:"https://github.com/LayoutitStudio/polycss.git",directory:"packages/morph"},bugs:{url:"https://github.com/LayoutitStudio/polycss/issues"},homepage:"https://github.com/LayoutitStudio/polycss#readme",files:["dist"],exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./prepare":{types:"./dist/prepare.d.ts",import:"./dist/prepare.js",require:"./dist/prepare.cjs"}},typesVersions:{"*":{prepare:["dist/prepare.d.ts"]}},scripts:{build:"tsup",test:"vitest run","test:package":"node scripts/certify-package.mjs","test:package:registry":"node scripts/certify-package.mjs --registry-dependencies","test:coverage":"vitest run --coverage",prepack:"node ../../.github/scripts/sync-package-readmes.mjs",prepublishOnly:"npm run build"},publishConfig:{access:"public"},dependencies:{"@layoutit/polycss":"workspace:^"},devDependencies:{"@types/node":"^25.0.0","@vitest/coverage-v8":"^3.1.1","happy-dom":"^20.7.0",tsup:"^8.0.1",typescript:"^5.3.3",vitest:"^3.1.1"}};var fn=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],Ir=mn.version;function be(n){let e=Number(n.toFixed(10));return Object.is(e,-0)?0:e}function _e(n){return[be(n[0]),be(n[1]),be(n[2])]}function hn(n,e){let o=n.normalize("NFKD").replace(/([a-z0-9])([A-Z])/gu,"$1-$2").replace(/[^A-Za-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").toLowerCase()||e;return/^[a-z]/u.test(o)?o:`item-${o}`}function Sr(n,[e,r,o]){let a=n[3]*e+n[7]*r+n[11]*o+n[15];return(!Number.isFinite(a)||Math.abs(a)<1e-12)&&y("invalid-transform","$.source.nodes","node has a singular projective transform"),[(n[0]*e+n[4]*r+n[8]*o+n[12])/a,(n[1]*e+n[5]*r+n[9]*o+n[13])/a,(n[2]*e+n[6]*r+n[10]*o+n[14])/a]}function Pn(n,[e,r,o]){return[n[0]*e+n[4]*r+n[8]*o,n[1]*e+n[5]*r+n[9]*o,n[2]*e+n[6]*r+n[10]*o]}function gn(n,e){let r={x:n[0],y:n[1],z:n[2]};return _e(e.transform.axes.map((o,a)=>r[o]*e.transform.signs[a]*e.transform.scale))}function Ar(n,e){let o=[[1,0,0],[0,1,0],[0,0,1]].map(s=>{let l=Pn(n,s),d={x:l[0],y:l[1],z:l[2]};return e.transform.axes.map((p,m)=>d[p]*e.transform.signs[m]*e.transform.scale)}),[a,t,i]=o;return a[0]*(t[1]*i[2]-t[2]*i[1])-t[0]*(a[1]*i[2]-a[2]*i[1])+i[0]*(a[1]*t[2]-a[2]*t[1])<0}function Be(n,e){return[n[0]-e[0],n[1]-e[1],n[2]-e[2]]}function Rr(n,e){return[n[1]*e[2]-n[2]*e[1],n[2]*e[0]-n[0]*e[2],n[0]*e[1]-n[1]*e[0]]}function Or(n,e){let r=Math.hypot(...n);return r>1e-10||y("degenerate-triangle",e,"triangle has zero area"),_e(n.map(o=>o/r))}function Cr(n,e){let r=Array.from({length:n.length},()=>[0,0,0]);for(let o of e){let[a,t,i]=o.vertexIndices.map(s=>n[s]),c=Rr(Be(t,a),Be(i,a));Math.hypot(...c)<=1e-10&&y("degenerate-triangle",`$.topology.${o.id}`,"triangle has zero area");for(let s of o.vertexIndices)r[s][0]+=c[0],r[s][1]+=c[1],r[s][2]+=c[2]}return r.map((o,a)=>Or(o,`$.topology.normals[${a}]`))}function jr(n,e){let r={vertices:n.map(l=>[...l])},[o,a,t]=n,i=wr(r,0,{seamBleed:0},{includeColor:!1,matrixDecimals:10,primitive:"border"},o[0],o[1],o[2],a[0],a[1],a[2],t[0],t[1],t[2]),s=/^matrix3d\(([^)]+)\)$/u.exec(i?.transformText??"")?.[1]?.split(",").map(Number);return(!s||s.length!==16||s.some(l=>!Number.isFinite(l)))&&y("unrenderable-triangle",e,"PolyCSS produced no stable matrix"),s.map(be)}function Tr(n){let e=new Set(["retained-render"]);return n.profile==="morph-regions"&&(e.add("morph-targets"),e.add("sparse-updates")),n.controls.length>0&&e.add("semantic-controls"),n.springs.length>0&&e.add("springs"),n.animations.length>0&&e.add("animation"),[...e].sort()}async function Mn(n,e){let r=[],o=[],a=[],t=Object.entries(e.morphAliases),i=new Map(t.map(([,g])=>[g,[]])),c=new Set,s=0,l=0;for(let g of n.instances){let k=Ar(g.matrix,e);for(let S of g.primitives){let B=`shape-${String(s).padStart(4,"0")}-${hn(`${g.meshName}-${S.primitiveIndex}`,"mesh")}`;a.push({id:B,matrix:fn});let D=new Map(S.targets.map(_=>[_.name,_]));t.some(([_])=>!D.has(_))&&y("missing-morph",`$.source.${B}`,"every primitive must contain every configured morph target");let xe=[...new Set(S.triangles.flat())].sort((_,q)=>_-q),oe=new Map;for(let _ of xe){let q=S.positions[_];oe.set(_,r.length);let b=Sr(g.matrix,q);r.push(gn(b,e));for(let[R,h]of t){let w=D.get(R).positionDeltas[_],T=Pn(g.matrix,w);i.get(h).push(gn(T,e))}}c.add(S.materialIndex);for(let _ of S.triangles){let q=k?[_[0],_[2],_[1]]:_;o.push({id:`polygon-${String(l).padStart(6,"0")}`,shapeId:B,materialIndex:S.materialIndex,vertexIndices:[oe.get(q[0]),oe.get(q[1]),oe.get(q[2])]}),l+=1}s+=1}}if(e.transform.center){let g=[1/0,1/0,1/0],k=[-1/0,-1/0,-1/0];for(let B of r)for(let D=0;D<3;D+=1)g[D]=Math.min(g[D],B[D]),k[D]=Math.max(k[D],B[D]);let S=g.map((B,D)=>(B+k[D])/2);for(let B=0;B<r.length;B+=1)r[B]=_e(Be(r[B],S))}let d=[...c].sort((g,k)=>g-k),p=new Map(n.materials.map(g=>[g.sourceIndex,g])),m=d.map(g=>{let k=g===-1?{name:"Default",color:[1,1,1,1]}:p.get(g);return k||y("invalid-material","$.source.materials",`primitive references missing material ${g}`),{sourceIndex:g,id:g===-1?"material-default":`material-${String(g).padStart(4,"0")}-${hn(k.name,"source")}`,color:k.color}}),M=new Map(m.map(g=>[g.sourceIndex,g.id])),P=o.map(g=>({id:g.id,vertexIndices:g.vertexIndices,normalIndices:g.vertexIndices})),x=Cr(r,P),f=t.map(([,g])=>({id:g,deltas:i.get(g).map((k,S)=>({position:k,vertexIndex:S})).filter(({position:k})=>Math.hypot(...k)>1e-12).map(({position:k,vertexIndex:S})=>({vertexIndex:S,position:k,normal:null}))}));f.some(g=>g.deltas.length===0)&&y("empty-morph","$.morphAliases","every configured morph target must move at least one vertex");let $=o.map(g=>{let k=M.get(g.materialIndex);return{id:`leaf-${g.id}`,polygonId:g.id,shapeId:g.shapeId,materialId:k,strategy:"solid-triangle",width:un,height:un,matrix:jr(g.vertexIndices.map(S=>r[S]),`$.render.${g.id}`),atlas:null,fallback:null}}),v=yn(o.map((g,k)=>({vertexIndices:g.vertexIndices,vertices:g.vertexIndices.map(S=>r[S]),materialId:M.get(g.materialIndex),leafMatrix:$[k].matrix}))),O=$.map((g,k)=>({...g,fallback:v.fallbacks[k]})),C={schema:X,identity:e.identity,profile:e.profile,capabilities:Tr(e),budgets:e.budgets,topology:{vertices:r,normals:x,polygons:P},materials:m.map(({id:g,color:k})=>({id:g,color:k})),render:{modelMatrix:fn,shapes:a,leaves:O},deformation:e.profile==="morph-regions"?{kind:"morph-regions",targets:f}:{kind:"none"},controls:e.controls,springs:e.springs,animations:e.animations,playback:null,provenance:{generator:"polycss-morph",generatorVersion:Ir,sources:[{id:e.source.id,kind:e.source.kind,uri:e.source.uri,sha256:n.contentSha256,license:e.source.license}]}};return{model:ce(C),fallbackAtlasPages:v.pages}}async function Je(n,e){let r=await Mn(n,e),o=await Te(r.model,[...r.fallbackAtlasPages.map(a=>({path:a.path,role:"image",mediaType:"image/png",bytes:a.bytes}))]);return{source:n,prepared:r,package:o}}import{createHash as Lr}from"crypto";import{readFile as xn}from"fs/promises";import{dirname as Er,extname as Nr,isAbsolute as $n,relative as Vr,resolve as vn,sep as Br}from"path";var _r={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT4:16},Jr={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4};function Ue(n){return Lr("sha256").update(n).digest("hex")}function kn(n,e){try{let r=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n));return(!r||typeof r!="object"||Array.isArray(r))&&y("invalid-gltf",e,"expected a JSON object"),r}catch(r){if(r instanceof Error&&r.name==="PolyMorphPrepareError")throw r;y("invalid-gltf",e,"expected UTF-8 JSON")}}function Ur(n){n.byteLength<20&&y("invalid-glb","$.source","GLB is truncated");let e=new DataView(n.buffer,n.byteOffset,n.byteLength);(e.getUint32(0,!0)!==1179937895||e.getUint32(4,!0)!==2||e.getUint32(8,!0)!==n.byteLength)&&y("invalid-glb","$.source","invalid GLB header");let r=12,o=null,a=null;for(;r<n.byteLength;){r+8>n.byteLength&&y("invalid-glb","$.source","truncated GLB chunk header");let t=e.getUint32(r,!0),i=e.getUint32(r+4,!0),c=r+8,s=c+t;(t%4!==0||s>n.byteLength)&&y("invalid-glb","$.source","invalid GLB chunk bounds"),i===1313821514?(o&&y("invalid-glb","$.source","duplicate JSON chunk"),o=kn(n.subarray(c,s),"$.source.json")):i===5130562?(a&&y("invalid-glb","$.source","duplicate binary chunk"),a=n.subarray(c,s)):y("invalid-glb","$.source",`unsupported GLB chunk type ${i}`),r=s}return o||y("invalid-glb","$.source","missing JSON chunk"),{json:o,binary:a}}function Dr(n,e){return(typeof n!="string"||n.length===0||$n(n)||n.includes("\\")||n.includes("?")||n.includes("#")||n.split("/").some(r=>r===""||r==="."||r===".."))&&y("unsafe-path",e,"expected a normalized source-relative path"),n}function Fr(n,e){let r=/^data:application\/(?:octet-stream|gltf-buffer);base64,([A-Za-z0-9+/]*={0,2})$/u.exec(n);return r||y("unsupported-uri",e,"expected a base64 glTF buffer data URI"),Uint8Array.from(Buffer.from(r[1],"base64"))}async function Hr(n,e,r){let o=Array.isArray(n.buffers)?n.buffers:[];o.length===0&&y("missing-buffer","$.source.buffers","expected at least one buffer");let a=Er(e),t=[],i=[];for(let[c,s]of o.entries()){let l=`$.source.buffers[${c}]`;(!Number.isSafeInteger(s?.byteLength)||s.byteLength<0)&&y("invalid-buffer",l,"invalid byteLength");let d,p;if(s.uri===void 0)(c!==0||!r)&&y("missing-buffer",l,"missing URI or GLB binary chunk"),d=r,p="<glb-bin>";else if(typeof s.uri=="string"&&s.uri.startsWith("data:"))d=Fr(s.uri,`${l}.uri`),p="<embedded-base64>";else{let P=Dr(s.uri,`${l}.uri`),x=vn(a,P),f=Vr(a,x);(f===".."||f.startsWith(`..${Br}`)||$n(f))&&y("unsafe-path",`${l}.uri`,"buffer escapes source directory"),d=new Uint8Array(await xn(x)),p=P}let m=s.byteLength;(d.byteLength<m||d.byteLength-m>3)&&y("invalid-buffer",l,"buffer length disagrees with byteLength");let M=d.subarray(0,m);t.push(M),i.push({path:p,sha256:Ue(M)})}return{buffers:t,files:i}}function zr(n,e,r){switch(e){case 5120:return n.getInt8(r);case 5121:return n.getUint8(r);case 5122:return n.getInt16(r,!0);case 5123:return n.getUint16(r,!0);case 5125:return n.getUint32(r,!0);case 5126:return n.getFloat32(r,!0);default:y("invalid-accessor","$.source.accessors",`unsupported component type ${e}`)}}function Gr(n,e){switch(e){case 5120:return Math.max(-1,n/127);case 5121:return n/255;case 5122:return Math.max(-1,n/32767);case 5123:return n/65535;case 5125:return n/4294967295;default:return n}}function qr(n,e){let r=Array.isArray(n.accessors)?n.accessors:[],o=Array.isArray(n.bufferViews)?n.bufferViews:[];return(a,t)=>{let i=r[a];(!i||i.sparse!==void 0||!Number.isSafeInteger(i.count)||i.count<0)&&y("invalid-accessor",t,"missing, sparse, or invalid accessor");let c=_r[i.type],s=Jr[i.componentType],l=o[i.bufferView];(!c||!s||!l||!Number.isSafeInteger(i.bufferView)||!Number.isSafeInteger(l.buffer))&&y("invalid-accessor",t,"unsupported accessor metadata");let d=e[l.buffer];d||y("invalid-accessor",t,"references an absent buffer");let p=c*s,m=l.byteStride??p,M=l.byteOffset??0,P=i.byteOffset??0,x=l.byteLength,f=M+P,$=f+Math.max(0,i.count-1)*m+p;(!Number.isSafeInteger(M)||M<0||!Number.isSafeInteger(x)||x<0||M+x>d.byteLength||!Number.isSafeInteger(P)||P<0||P%s!==0||!Number.isSafeInteger(m)||m<p||l.byteStride!==void 0&&(m>252||m%4!==0)||!Number.isSafeInteger(f)||f<0||f%s!==0||$>M+x)&&y("invalid-accessor",t,"invalid accessor byte layout");let v=new DataView(d.buffer,d.byteOffset,d.byteLength),O=[];for(let C=0;C<i.count;C+=1){let z=[];for(let g=0;g<c;g+=1){let k=zr(v,i.componentType,f+C*m+g*s),S=i.normalized?Gr(k,i.componentType):k;Number.isFinite(S)||y("invalid-accessor",`${t}[${C}][${g}]`,"non-finite component"),z.push(Object.is(S,-0)?0:S)}O.push(c===1?z[0]:z)}return O}}function bn(n,e){return n.map((r,o)=>((!Array.isArray(r)||r.length!==3)&&y("invalid-accessor",`${e}[${o}]`,"expected VEC3"),[r[0],r[1],r[2]]))}function Wr(n,e,r){let o=e.map((t,i)=>((!Number.isSafeInteger(t)||t<0)&&y("invalid-index",`${r}[${i}]`,"expected an unsigned integer"),t)),a=[];if(n===4){o.length%3!==0&&y("invalid-primitive",r,"incomplete triangle list");for(let t=0;t<o.length;t+=3)a.push([o[t],o[t+1],o[t+2]])}else if(n===5)for(let t=2;t<o.length;t+=1)a.push(t%2===0?[o[t-2],o[t-1],o[t]]:[o[t-1],o[t-2],o[t]]);else if(n===6)for(let t=2;t<o.length;t+=1)a.push([o[0],o[t-1],o[t]]);else y("unsupported-primitive",r,`mode ${n} is not triangles, triangle strip, or triangle fan`);return a.filter(([t,i,c])=>t!==i&&i!==c&&t!==c)}var Yr=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function Kr(n,e){let r=new Array(16).fill(0);for(let o=0;o<4;o+=1)for(let a=0;a<4;a+=1)for(let t=0;t<4;t+=1)r[o*4+a]+=n[t*4+a]*e[o*4+t];return r}function Zr(n,e){if(n.matrix!==void 0)return(!Array.isArray(n.matrix)||n.matrix.length!==16||n.matrix.some(C=>typeof C!="number"||!Number.isFinite(C))||n.translation!==void 0||n.rotation!==void 0||n.scale!==void 0)&&y("invalid-node",e,"invalid or ambiguous node matrix"),n.matrix;let r=n.translation??[0,0,0],o=n.rotation??[0,0,0,1],a=n.scale??[1,1,1];(!Array.isArray(r)||r.length!==3||!Array.isArray(o)||o.length!==4||!Array.isArray(a)||a.length!==3||[...r,...o,...a].some(C=>typeof C!="number"||!Number.isFinite(C)))&&y("invalid-node",e,"invalid node TRS");let[t,i,c,s]=o,l=Math.hypot(t,i,c,s);l>0||y("invalid-node",`${e}.rotation`,"zero quaternion");let d=t/l,p=i/l,m=c/l,M=s/l,[P,x,f]=a,[$,v,O]=r;return[(1-2*(p*p+m*m))*P,2*(d*p+m*M)*P,2*(d*m-p*M)*P,0,2*(d*p-m*M)*x,(1-2*(d*d+m*m))*x,2*(p*m+d*M)*x,0,2*(d*m+p*M)*f,2*(p*m-d*M)*f,(1-2*(d*d+p*p))*f,0,$,v,O,1]}function Qr(n){let e=Array.isArray(n.nodes)?n.nodes:[],r=Array.isArray(n.scenes)?n.scenes:[],o;if(r.length>0){let i=n.scene??0,c=r[i]?.nodes;Array.isArray(c)||y("invalid-scene","$.source.scene","default scene has no nodes"),o=c}else{let i=new Set(e.flatMap(c=>Array.isArray(c.children)?c.children:[]));o=e.map((c,s)=>s).filter(c=>!i.has(c))}let a=[],t=(i,c,s)=>{(!Number.isSafeInteger(i)||i<0||i>=e.length)&&y("invalid-node","$.source.nodes",`unknown node ${i}`),s.has(i)&&y("invalid-node","$.source.nodes",`node cycle at ${i}`);let l=e[i],d=Kr(c,Zr(l,`$.source.nodes[${i}]`));l.mesh!==void 0&&((!Number.isSafeInteger(l.mesh)||l.mesh<0)&&y("invalid-node",`$.source.nodes[${i}].mesh`,"invalid mesh index"),a.push({nodeIndex:i,nodeName:typeof l.name=="string"&&l.name.length>0?l.name:`node-${i}`,meshIndex:l.mesh,matrix:d}));let p=new Set(s).add(i),m=l.children??[];Array.isArray(m)||y("invalid-node",`$.source.nodes[${i}].children`,"expected an array");for(let M of m)t(M,d,p)};for(let i of o)t(i,Yr,new Set);return a}function Xr(n){return(Array.isArray(n.materials)?n.materials:[]).map((r,o)=>{(!r||typeof r!="object"||Array.isArray(r))&&y("invalid-material",`$.source.materials[${o}]`,"expected a material object");let a=r.pbrMetallicRoughness?.baseColorFactor??[1,1,1,1];return(!Array.isArray(a)||a.length!==4||a.some(t=>typeof t!="number"||!Number.isFinite(t)||t<0||t>1))&&y("invalid-material",`$.source.materials[${o}]`,"baseColorFactor must have four unit components"),{sourceIndex:o,name:typeof r.name=="string"&&r.name.length>0?r.name:`material-${o}`,color:[a[0],a[1],a[2],a[3]]}})}function eo(n,e,r){let o=qr(n,e),a=Array.isArray(n.meshes)?n.meshes:[];return r.map(t=>{let i=a[t.meshIndex];(!i||!Array.isArray(i.primitives)||i.primitives.length===0)&&y("invalid-mesh",`$.source.meshes[${t.meshIndex}]`,"mesh has no primitives");let c=Array.isArray(i.extras?.targetNames)?i.extras.targetNames.map(String):[],s=i.primitives.map((l,d)=>{let p=`$.source.meshes[${t.meshIndex}].primitives[${d}]`;(!l?.attributes||!Number.isSafeInteger(l.attributes.POSITION))&&y("invalid-primitive",p,"missing POSITION accessor");let m=bn(o(l.attributes.POSITION,`${p}.POSITION`),`${p}.POSITION`),M=l.indices===void 0?m.map(($,v)=>v):o(l.indices,`${p}.indices`),P=Wr(l.mode??4,M,`${p}.indices`);(P.length===0||P.some($=>$.some(v=>v>=m.length)))&&y("invalid-index",p,"triangle indices are empty or out of range");let x=Array.isArray(l.targets)?l.targets.map(($,v)=>{Number.isSafeInteger($.POSITION)||y("invalid-morph",`${p}.targets[${v}]`,"missing POSITION accessor");let O=bn(o($.POSITION,`${p}.targets[${v}].POSITION`),`${p}.targets[${v}].POSITION`);return O.length!==m.length&&y("invalid-morph",`${p}.targets[${v}]`,"target does not cover POSITION"),{index:v,name:c[v]??`morph-${v}`,positionDeltas:O}}):[],f=l.material??-1;return(!Number.isSafeInteger(f)||f<-1)&&y("invalid-material",`${p}.material`,"invalid material index"),{primitiveIndex:d,materialIndex:f,positions:m,triangles:P,targets:x}});return{...t,meshName:typeof i.name=="string"&&i.name.length>0?i.name:`mesh-${t.meshIndex}`,primitives:s}})}async function De(n){let e=vn(n),r=new Uint8Array(await xn(e)),o=Nr(e).toLowerCase(),a,t,i=null;o===".glb"?(a="glb",{json:t,binary:i}=Ur(r)):o===".gltf"?(a="gltf",t=kn(r,"$.source")):y("unsupported-format","$.source.path","expected .gltf or .glb"),(t.asset?.version!=="2.0"||Array.isArray(t.extensionsRequired)&&t.extensionsRequired.length>0)&&y("unsupported-gltf","$.source","expected core glTF 2.0 without required extensions");let c=await Hr(t,e,i),s=eo(t,c.buffers,Qr(t));s.length===0&&y("empty-model","$.source","default scene has no mesh instances");let l=Ue(r),d=Ue(new TextEncoder().encode(JSON.stringify({source:l,buffers:c.files})));return{format:a,sourceBytes:r.byteLength,sourceSha256:l,contentSha256:d,materials:Xr(t),instances:s}}import{existsSync as le}from"fs";import{mkdir as wn,mkdtemp as no,readFile as ro,readdir as oo,rename as Fe,rm as In,writeFile as to}from"fs/promises";import{basename as ao,dirname as Sn,isAbsolute as io,join as He,parse as so,relative as lo,resolve as ze,sep as co}from"path";function po(n){(typeof n!="string"||n.length===0)&&y("invalid-argument","$.outputRoot","expected a path");let e=ze(n);return e===so(e).root&&y("unsafe-path","$.outputRoot","filesystem root is forbidden"),e}async function An(n,e=""){let r=He(n,e),o=await oo(r,{withFileTypes:!0}),a=[];for(let t of o.sort((i,c)=>i.name<c.name?-1:i.name>c.name?1:0)){let i=e===""?t.name:`${e}/${t.name}`;t.isSymbolicLink()&&y("unsafe-output",i,"symbolic links are forbidden"),t.isDirectory()?a.push(...await An(n,i)):t.isFile()?a.push(i):y("unsafe-output",i,"unsupported filesystem entry")}return a}async function Rn(n,e){if(!le(n))return{path:"$.outputRoot",message:"prepared package is missing"};let r=await An(n),o=[...e.keys()].sort();if(r.length!==o.length||r.some((a,t)=>a!==o[t]))return{path:"$.outputRoot",message:`inventory differs: expected ${o.join(", ")}`};for(let a of o){let t=new Uint8Array(await ro(He(n,a))),i=e.get(a);if(t.byteLength!==i.byteLength||t.some((c,s)=>c!==i[s]))return{path:a,message:"prepared bytes differ"}}return null}async function yo(n,e){let r=await Rn(n,e);r&&y("drift",r.path,r.message)}async function mo(n,e){let r=Sn(n);await wn(r,{recursive:!0});let o=await no(He(r,`.polycss-morph-${ao(n)}-`)),a=`${n}.previous-${process.pid}`,i=[...[...e.keys()].filter(s=>s!=="manifest.json").sort(),"manifest.json"],c=!1;try{for(let s of i){let l=ze(o,s),d=lo(o,l);(d===".."||d.startsWith(`..${co}`)||io(d))&&y("unsafe-path",s,"package path escapes staging"),await wn(Sn(l),{recursive:!0}),await to(l,e.get(s))}return le(a)&&y("unsafe-output","$.outputRoot",`backup already exists at ${a}`),le(n)&&(await Fe(n,a),c=!0),await Fe(o,n),c&&await In(a,{recursive:!0,force:!0}).catch(()=>{}),i}catch(s){throw c&&!le(n)&&le(a)&&await Fe(a,n),s}finally{le(o)&&await In(o,{recursive:!0,force:!0})}}async function uo(n){(!n||typeof n!="object")&&y("invalid-argument","$","expected prepare options"),(typeof n.configPath!="string"||n.configPath.length===0)&&y("invalid-argument","$.configPath","expected a path"),n.check!==void 0&&typeof n.check!="boolean"&&y("invalid-argument","$.check","expected a boolean");let e=ze(n.configPath),r=po(n.outputRoot),o=await Ee(e),a=Ne(e,o.source.path),t=await De(a),i=await Je(t,o),c=new Map(i.package.files);c.set("manifest.json",i.package.manifestBytes);let s=[...c.keys()].sort();if(n.check)return await yo(r,c),{config:o,source:t,model:i.prepared.model,manifest:i.package.manifest,manifestSha256:i.package.manifestSha256,outputRoot:r,files:s,writeOrder:[],checked:!0,changed:!1};if(await Rn(r,c)===null)return{config:o,source:t,model:i.prepared.model,manifest:i.package.manifest,manifestSha256:i.package.manifestSha256,outputRoot:r,files:s,writeOrder:[],checked:!1,changed:!1};let l=await mo(r,c);return{config:o,source:t,model:i.prepared.model,manifest:i.package.manifest,manifestSha256:i.package.manifestSha256,outputRoot:r,files:s,writeOrder:l,checked:!1,changed:!0}}export{ee as POLY_MORPH_CATALOG_SCHEMA,X as POLY_MORPH_MODEL_SCHEMA,ne as POLY_MORPH_PACKAGE_SCHEMA,me as POLY_MORPH_PREPARE_SCHEMA,he as PolyMorphContractError,E as PolyMorphPackageError,Pe as PolyMorphPrepareError,or as assertPolyMorphPackageModelBinding,rr as buildPolyMorphCatalog,Te as buildPolyMorphPackage,Je as buildPolyMorphPreparedPackage,Mn as compilePolyMorphSource,Gn as decodePolyMorphJson,pe as encodePolyMorphCanonicalJson,y as failPolyMorphPrepare,ae as hashPolyMorphBytes,de as isPolyMorphId,we as isPolyMorphResourcePath,De as loadPolyMorphGltf,cn as parsePolyMorphPrepareConfig,uo as preparePolyMorphModel,Ee as readPolyMorphPrepareConfig,Ne as resolvePolyMorphSourcePath,Xe as stringifyPolyMorphCanonicalJson,Ce as validatePolyMorphCatalog,ce as validatePolyMorphModel,Oe as validatePolyMorphPackageManifest};
1
+ var X="polycss-morph.model@1",ee="polycss-morph.catalog@1",ne="polycss-morph.package@1";var Ke=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,Cn=/^[a-z0-9][a-z0-9._-]*$/,Ye=/^\d+\.\d+\.\d+$/,jn=/^[a-f0-9]{64}$/,Tn=new Set(["joint-skin","morph-regions","prepared-playback","static-prepared"]),Ln=new Set(["animation","joint-skinning","morph-targets","prepared-playback","retained-render","semantic-controls","sparse-updates","springs"]),En=new Set(["atlas-slice","direct-image","solid-quad","solid-triangle"]),Nn=new Set(["control-value","joint-rotation","joint-scale","joint-translation","morph-weight","shape-matrix"]),he=class extends TypeError{constructor(e,r,o){super(`${r}: ${o}`),this.name="PolyMorphContractError",this.code=e,this.path=r}};function u(n,e,r){throw new he(n,e,r)}function I(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&u("invalid-type",e,"expected an object");let o=Object.keys(n).sort(),a=[...r].sort();return(o.length!==a.length||o.some((t,i)=>t!==a[i]))&&u("invalid-keys",e,`expected exactly ${a.join(", ")}`),n}function A(n,e){return Array.isArray(n)||u("invalid-type",e,"expected an array"),n}function F(n,e){return(typeof n!="string"||n.length===0)&&u("invalid-string",e,"expected a non-empty string"),n}function N(n,e){return(typeof n!="number"||!Number.isFinite(n))&&u("invalid-number",e,"expected a finite number"),n}function U(n,e,r=0){let o=N(n,e);return(!Number.isSafeInteger(o)||o<r)&&u("invalid-integer",e,`expected an integer >= ${r}`),o}function ke(n,e){return typeof n!="boolean"&&u("invalid-boolean",e,"expected a boolean"),n}function L(n,e){let r=F(n,e);return Ke.test(r)||u("invalid-id",e,"expected a normalized kebab-case id"),r}function V(n,e){let r=new Set;for(let o of n)r.has(o)&&u("duplicate-id",e,`duplicate id ${o}`),r.add(o)}function te(n,e){let r=A(n,e);return r.length!==3&&u("invalid-vector",e,"expected three components"),r.map((o,a)=>N(o,`${e}[${a}]`))}function Y(n,e){let r=A(n,e);return r.length!==16&&u("invalid-matrix",e,"expected sixteen components"),r.map((o,a)=>N(o,`${e}[${a}]`))}function Ze(n,e){let r=F(n,e);return r.split("/").some(o=>!Cn.test(o))&&u("invalid-path",e,"expected lowercase URL-safe package path segments"),r}function ge(n,e,r){let o=U(n,e);return o>=r&&u("out-of-range",e,`expected an index below ${r}`),o}function Vn(n,e){let r=I(n,e,["normals","polygons","vertices"]),o=A(r.vertices,`${e}.vertices`).map((i,c)=>te(i,`${e}.vertices[${c}]`)),a=A(r.normals,`${e}.normals`).map((i,c)=>te(i,`${e}.normals[${c}]`));o.length===0&&u("missing-topology",`${e}.vertices`,"expected at least one vertex"),a.length===0&&u("missing-topology",`${e}.normals`,"expected at least one normal");let t=A(r.polygons,`${e}.polygons`).map((i,c)=>{let s=`${e}.polygons[${c}]`,l=I(i,s,["id","normalIndices","vertexIndices"]),d=A(l.vertexIndices,`${s}.vertexIndices`).map((m,M)=>ge(m,`${s}.vertexIndices[${M}]`,o.length)),p=A(l.normalIndices,`${s}.normalIndices`).map((m,M)=>ge(m,`${s}.normalIndices[${M}]`,a.length));return d.length<3&&u("invalid-polygon",s,"expected at least three vertices"),p.length!==d.length&&u("invalid-polygon",s,"normal and vertex index counts must match"),new Set(d).size!==d.length&&u("invalid-polygon",s,"vertex indices must be unique"),{id:L(l.id,`${s}.id`),vertexIndices:d,normalIndices:p}});return t.length===0&&u("missing-topology",`${e}.polygons`,"expected at least one polygon"),V(t.map(i=>i.id),`${e}.polygons`),{vertices:o,normals:a,polygons:t}}function Bn(n,e,r){let o=I(n,e,["atlas","fallback","height","id","materialId","matrix","polygonId","shapeId","strategy","width"]),a=F(o.strategy,`${e}.strategy`);En.has(a)||u("invalid-strategy",`${e}.strategy`,"unknown render strategy");let t=L(o.polygonId,`${e}.polygonId`),i=L(o.shapeId,`${e}.shapeId`),c=L(o.materialId,`${e}.materialId`);r.polygonIds.has(t)||u("unknown-reference",`${e}.polygonId`,t),r.shapeIds.has(i)||u("unknown-reference",`${e}.shapeId`,i),r.materialIds.has(c)||u("unknown-reference",`${e}.materialId`,c);let s=N(o.width,`${e}.width`),l=N(o.height,`${e}.height`);(s<=0||l<=0)&&u("invalid-size",e,"leaf dimensions must be positive");let d=a==="atlas-slice"||a==="direct-image",p=o.atlas===null?null:Qe(o.atlas,`${e}.atlas`);d!==(p!==null)&&u("invalid-strategy",`${e}.atlas`,d?"image strategies require an atlas/source slice":"solid strategies cannot declare an atlas/source slice");let m=o.fallback===null?null:_n(o.fallback,`${e}.fallback`);return m!==null&&a!=="solid-triangle"&&u("invalid-strategy",`${e}.fallback`,"only solid-triangle leaves may declare a prepared fallback"),{id:L(o.id,`${e}.id`),polygonId:t,shapeId:i,materialId:c,strategy:a,width:s,height:l,matrix:Y(o.matrix,`${e}.matrix`),atlas:p,fallback:m}}function _n(n,e){let r=I(n,e,["atlas","height","matrixFromLeaf","width"]),o=U(r.width,`${e}.width`,1),a=U(r.height,`${e}.height`,1),t=Qe(r.atlas,`${e}.atlas`);return(t.width!==o||t.height!==a)&&u("invalid-size",e,"fallback dimensions must match its per-polygon atlas slice"),{width:o,height:a,matrixFromLeaf:Y(r.matrixFromLeaf,`${e}.matrixFromLeaf`),atlas:t}}function Qe(n,e){let r=I(n,e,["height","pageHeight","pageWidth","resourcePath","width","x","y"]),o={resourcePath:Ze(r.resourcePath,`${e}.resourcePath`),x:U(r.x,`${e}.x`),y:U(r.y,`${e}.y`),width:U(r.width,`${e}.width`,1),height:U(r.height,`${e}.height`,1),pageWidth:U(r.pageWidth,`${e}.pageWidth`,1),pageHeight:U(r.pageHeight,`${e}.pageHeight`,1)};return(o.x+o.width>o.pageWidth||o.y+o.height>o.pageHeight)&&u("out-of-range",e,"slice must fit inside its page"),o}function Jn(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&u("invalid-type",e,"expected a deformation object");let o=F(n.kind,`${e}.kind`);if(o==="none")return I(n,e,["kind"]),{kind:o};if(o==="morph-regions"){let a=I(n,e,["kind","targets"]),t=A(a.targets,`${e}.targets`).map((i,c)=>{let s=`${e}.targets[${c}]`,l=I(i,s,["deltas","id"]),d=A(l.deltas,`${s}.deltas`).map((m,M)=>{let P=`${s}.deltas[${M}]`,x=I(m,P,["normal","position","vertexIndex"]),f=x.position===null?null:te(x.position,`${P}.position`),$=x.normal===null?null:te(x.normal,`${P}.normal`);return f===null&&$===null&&u("empty-delta",P,"expected a position or normal delta"),{vertexIndex:ge(x.vertexIndex,`${P}.vertexIndex`,r.vertices.length),position:f,normal:$}});d.length===0&&u("missing-deltas",`${s}.deltas`,"expected at least one delta");let p=d.map(m=>String(m.vertexIndex));return V(p,`${s}.deltas`),{id:L(l.id,`${s}.id`),deltas:d}});return t.length===0&&u("missing-targets",`${e}.targets`,"expected at least one target"),V(t.map(i=>i.id),`${e}.targets`),{kind:o,targets:t}}if(o==="joint-skin"){let a=I(n,e,["joints","kind","vertices"]),t=A(a.joints,`${e}.joints`).map((l,d)=>{let p=`${e}.joints[${d}]`,m=I(l,p,["id","inverseBindMatrix","parentId","restMatrix"]);return{id:L(m.id,`${p}.id`),parentId:m.parentId===null?null:L(m.parentId,`${p}.parentId`),restMatrix:Y(m.restMatrix,`${p}.restMatrix`),inverseBindMatrix:Y(m.inverseBindMatrix,`${p}.inverseBindMatrix`)}});t.length===0&&u("missing-joints",`${e}.joints`,"expected at least one joint"),V(t.map(l=>l.id),`${e}.joints`),Un(t,`${e}.joints`);let i=new Set(t.map(l=>l.id)),c=A(a.vertices,`${e}.vertices`).map((l,d)=>{let p=`${e}.vertices[${d}]`,m=I(l,p,["influences","vertexIndex"]),M=ge(m.vertexIndex,`${p}.vertexIndex`,r.vertices.length),P=A(m.influences,`${p}.influences`).map((f,$)=>{let v=`${p}.influences[${$}]`,O=I(f,v,["jointId","weight"]),C=L(O.jointId,`${v}.jointId`);i.has(C)||u("unknown-reference",`${v}.jointId`,C);let z=N(O.weight,`${v}.weight`);return(z<=0||z>1)&&u("invalid-weight",`${v}.weight`,"expected 0 < weight <= 1"),{jointId:C,weight:z}});P.length===0&&u("missing-influences",`${p}.influences`,"expected at least one influence"),V(P.map(f=>f.jointId),`${p}.influences`);let x=P.reduce((f,$)=>f+$.weight,0);return Math.abs(x-1)>1e-6&&u("invalid-weight",`${p}.influences`,"weights must sum to 1"),{vertexIndex:M,influences:P}});c.length!==r.vertices.length&&u("missing-skin-vertex",`${e}.vertices`,"every topology vertex must have one skin record");let s=c.map(l=>String(l.vertexIndex));return V(s,`${e}.vertices`),{kind:o,joints:t,vertices:c}}u("invalid-deformation",`${e}.kind`,`unknown deformation kind ${o}`)}function Un(n,e){let r=new Map(n.map(a=>[a.id,a]));n.filter(a=>a.parentId===null).length!==1&&u("invalid-hierarchy",e,"expected exactly one root joint");for(let a of n){a.parentId!==null&&!r.has(a.parentId)&&u("unknown-reference",e,`joint ${a.id} references ${a.parentId}`);let t=new Set,i=a;for(;i;)t.has(i.id)&&u("invalid-hierarchy",e,`cycle at joint ${i.id}`),t.add(i.id),i=i.parentId===null?void 0:r.get(i.parentId)}}function Dn(n){return n==="control-value"||n==="morph-weight"?1:n==="joint-rotation"?4:n==="shape-matrix"?16:3}function Fn(n,e,r,o){let a=I(n,e,["interpolation","target","targetId","timesMs","values"]),t=F(a.target,`${e}.target`);Nn.has(t)||u("invalid-animation-target",`${e}.target`,t);let i=L(a.targetId,`${e}.targetId`);(t==="control-value"?r.controlIds:t==="morph-weight"?r.targetIds:t==="shape-matrix"?r.shapeIds:r.jointIds).has(i)||u("unknown-reference",`${e}.targetId`,i);let s=F(a.interpolation,`${e}.interpolation`);s!=="linear"&&s!=="step"&&u("invalid-interpolation",`${e}.interpolation`,s),t==="shape-matrix"&&s!=="step"&&u("invalid-interpolation",`${e}.interpolation`,"shape matrices require step interpolation");let l=A(a.timesMs,`${e}.timesMs`).map((p,m)=>N(p,`${e}.timesMs[${m}]`)),d=A(a.values,`${e}.values`).map((p,m)=>{let M=A(p,`${e}.values[${m}]`),P=Dn(t);M.length!==P&&u("invalid-animation-value",`${e}.values[${m}]`,`expected ${P} components`);let x=M.map((f,$)=>N(f,`${e}.values[${m}][${$}]`));return t==="joint-rotation"&&Math.hypot(...x)<=1e-12&&u("invalid-animation-value",`${e}.values[${m}]`,"quaternion must be non-zero"),x});return(l.length===0||l.length!==d.length)&&u("invalid-animation-samples",e,"times and values must have the same non-zero length"),(l[0]!==0||l.some((p,m)=>p<0||p>o||m>0&&p<=l[m-1]))&&u("invalid-animation-time",`${e}.timesMs`,"times must start at zero and increase within the clip"),{target:t,targetId:i,interpolation:s,timesMs:l,values:d}}function Hn(n,e,r,o){let a=I(n,e,["durationMs","frames","loop"]),t=N(a.durationMs,`${e}.durationMs`);t<=0&&u("invalid-duration",`${e}.durationMs`,"expected a positive duration");let i=A(a.frames,`${e}.frames`).map((c,s)=>{let l=`${e}.frames[${s}]`,d=I(c,l,["leaves","modelMatrix","shapes","timeMs"]),p=N(d.timeMs,`${l}.timeMs`),m=A(d.shapes,`${l}.shapes`).map((P,x)=>{let f=`${l}.shapes[${x}]`,$=I(P,f,["matrix","shapeId"]),v=L($.shapeId,`${f}.shapeId`);return o.has(v)||u("unknown-reference",`${f}.shapeId`,v),{shapeId:v,matrix:Y($.matrix,`${f}.matrix`)}});V(m.map(P=>P.shapeId),`${l}.shapes`);let M=A(d.leaves,`${l}.leaves`).map((P,x)=>{let f=`${l}.leaves[${x}]`,$=I(P,f,["atlasRow","leafId","matrix","opacity","visible"]),v=L($.leafId,`${f}.leafId`);r.has(v)||u("unknown-reference",`${f}.leafId`,v);let O=$.opacity===null?null:N($.opacity,`${f}.opacity`);return O!==null&&(O<0||O>1)&&u("out-of-range",`${f}.opacity`,"expected 0 <= opacity <= 1"),{leafId:v,matrix:$.matrix===null?null:Y($.matrix,`${f}.matrix`),visible:$.visible===null?null:ke($.visible,`${f}.visible`),opacity:O,atlasRow:$.atlasRow===null?null:U($.atlasRow,`${f}.atlasRow`)}});return V(M.map(P=>P.leafId),`${l}.leaves`),{timeMs:p,modelMatrix:d.modelMatrix===null?null:Y(d.modelMatrix,`${l}.modelMatrix`),shapes:m,leaves:M}});return i.length===0&&u("missing-frames",`${e}.frames`,"expected at least one frame"),(i[0].timeMs!==0||i.some((c,s)=>c.timeMs<0||c.timeMs>t||s>0&&c.timeMs<=i[s-1].timeMs))&&u("invalid-frame-time",`${e}.frames`,"frames must start at zero and increase within the timeline"),{durationMs:t,loop:ke(a.loop,`${e}.loop`),frames:i}}function zn(n,e){let r=["retained-render"];return n==="morph-regions"&&r.push("morph-targets","sparse-updates"),n==="joint-skin"&&r.push("joint-skinning","sparse-updates"),n==="prepared-playback"&&r.push("prepared-playback","sparse-updates"),e.controls.length>0&&r.push("semantic-controls"),e.springs.length>0&&r.push("springs"),e.animations.length>0&&r.push("animation"),r}function ce(n){let r=I(n,"$",["animations","budgets","capabilities","controls","deformation","identity","materials","playback","profile","provenance","render","schema","springs","topology"]);r.schema!==X&&u("invalid-schema","$.schema",`expected ${X}`);let o=I(r.identity,"$.identity",["id","name","revision"]),a={id:L(o.id,"$.identity.id"),name:F(o.name,"$.identity.name"),revision:F(o.revision,"$.identity.revision")};Ye.test(a.revision)||u("invalid-revision","$.identity.revision","expected x.y.z");let t=F(r.profile,"$.profile");Tn.has(t)||u("invalid-profile","$.profile",t);let i=A(r.capabilities,"$.capabilities").map((b,R)=>{let h=F(b,`$.capabilities[${R}]`);return Ln.has(h)||u("invalid-capability",`$.capabilities[${R}]`,h),h});V(i,"$.capabilities"),i.some((b,R)=>R>0&&b<=i[R-1])&&u("non-canonical-order","$.capabilities","capabilities must be sorted");let c=I(r.budgets,"$.budgets",["maxBytes","maxFrames","maxJoints","maxLeaves","maxPolygons","maxResources","maxVertices"]),s={maxVertices:U(c.maxVertices,"$.budgets.maxVertices"),maxPolygons:U(c.maxPolygons,"$.budgets.maxPolygons"),maxLeaves:U(c.maxLeaves,"$.budgets.maxLeaves"),maxFrames:U(c.maxFrames,"$.budgets.maxFrames"),maxJoints:U(c.maxJoints,"$.budgets.maxJoints"),maxResources:U(c.maxResources,"$.budgets.maxResources"),maxBytes:U(c.maxBytes,"$.budgets.maxBytes")},l=Vn(r.topology,"$.topology"),d=A(r.materials,"$.materials").map((b,R)=>{let h=`$.materials[${R}]`,w=I(b,h,["color","id"]),T=A(w.color,`${h}.color`);T.length!==4&&u("invalid-color",`${h}.color`,"expected four components");let J=T.map((G,W)=>{let Q=N(G,`${h}.color[${W}]`);return(Q<0||Q>1)&&u("out-of-range",`${h}.color[${W}]`,"expected 0 <= component <= 1"),Q});return{id:L(w.id,`${h}.id`),color:J}});d.length===0&&u("missing-materials","$.materials","expected at least one material"),V(d.map(b=>b.id),"$.materials");let p=I(r.render,"$.render",["leaves","modelMatrix","shapes"]),m=A(p.shapes,"$.render.shapes").map((b,R)=>{let h=`$.render.shapes[${R}]`,w=I(b,h,["id","matrix"]);return{id:L(w.id,`${h}.id`),matrix:Y(w.matrix,`${h}.matrix`)}});m.length===0&&u("missing-shapes","$.render.shapes","expected at least one shape"),V(m.map(b=>b.id),"$.render.shapes");let M=A(p.leaves,"$.render.leaves").map((b,R)=>Bn(b,`$.render.leaves[${R}]`,{polygonIds:new Set(l.polygons.map(h=>h.id)),shapeIds:new Set(m.map(h=>h.id)),materialIds:new Set(d.map(h=>h.id))}));V(M.map(b=>b.id),"$.render.leaves"),V(M.map(b=>b.polygonId),"$.render.leaves[*].polygonId"),M.length!==l.polygons.length&&u("unstable-topology","$.render.leaves","every polygon must bind exactly one retained leaf");let P={modelMatrix:Y(p.modelMatrix,"$.render.modelMatrix"),shapes:m,leaves:M},x=Jn(r.deformation,"$.deformation",l);(t==="static-prepared"||t==="prepared-playback"?x.kind!=="none":x.kind!==t)&&u("profile-mismatch","$.deformation.kind",`does not match profile ${t}`);let f=new Set(x.kind==="morph-regions"?x.targets.map(b=>b.id):[]),$=new Set(x.kind==="joint-skin"?x.joints.map(b=>b.id):[]),v=A(r.controls,"$.controls").map((b,R)=>{let h=`$.controls[${R}]`,w=I(b,h,["anchor","axis","id","initial","maximum","minimum","radius","targets"]),T=N(w.minimum,`${h}.minimum`),J=N(w.maximum,`${h}.maximum`),G=N(w.initial,`${h}.initial`);(T>J||G<T||G>J)&&u("invalid-control-bounds",h,"expected minimum <= initial <= maximum");let W=te(w.anchor,`${h}.anchor`),Q=te(w.axis,`${h}.axis`);Math.hypot(...Q)<1e-9&&u("invalid-control-axis",`${h}.axis`,"axis must be non-zero");let Ge=N(w.radius,`${h}.radius`);Ge<=0&&u("invalid-control-radius",`${h}.radius`,"radius must be positive");let qe=A(w.targets,`${h}.targets`).map(($e,On)=>{let fe=`${h}.targets[${On}]`,We=I($e,fe,["scale","targetId"]),ve=L(We.targetId,`${fe}.targetId`);return f.has(ve)||u("unknown-reference",`${fe}.targetId`,ve),{targetId:ve,scale:N(We.scale,`${fe}.scale`)}});return V(qe.map($e=>$e.targetId),`${h}.targets`),{id:L(w.id,`${h}.id`),anchor:W,axis:Q,radius:Ge,minimum:T,maximum:J,initial:G,targets:qe}});V(v.map(b=>b.id),"$.controls");let O=new Set(v.map(b=>b.id)),C=A(r.springs,"$.springs").map((b,R)=>{let h=`$.springs[${R}]`,w=I(b,h,["controlId","damping","id","stiffness"]),T=L(w.controlId,`${h}.controlId`);O.has(T)||u("unknown-reference",`${h}.controlId`,T);let J=N(w.stiffness,`${h}.stiffness`),G=N(w.damping,`${h}.damping`);return(J<=0||G<0)&&u("invalid-spring",h,"expected stiffness > 0 and damping >= 0"),{id:L(w.id,`${h}.id`),controlId:T,stiffness:J,damping:G}});V(C.map(b=>b.id),"$.springs");let z=new Set(m.map(b=>b.id)),g=A(r.animations,"$.animations").map((b,R)=>{let h=`$.animations[${R}]`,w=I(b,h,["channels","durationMs","id","loop"]),T=N(w.durationMs,`${h}.durationMs`);T<=0&&u("invalid-duration",`${h}.durationMs`,"expected a positive duration");let J=A(w.channels,`${h}.channels`).map((W,Q)=>Fn(W,`${h}.channels[${Q}]`,{controlIds:O,jointIds:$,shapeIds:z,targetIds:f},T));J.length===0&&u("missing-channels",`${h}.channels`,"expected at least one channel");let G=J.map(W=>`${W.target}:${W.targetId}`);return V(G,`${h}.channels`),{id:L(w.id,`${h}.id`),durationMs:T,loop:ke(w.loop,`${h}.loop`),channels:J}});V(g.map(b=>b.id),"$.animations");let k=r.playback===null?null:Hn(r.playback,"$.playback",new Set(M.map(b=>b.id)),z);t==="prepared-playback"!=(k!==null)&&u("profile-mismatch","$.playback","playback is required only by the prepared-playback profile");let S=I(r.provenance,"$.provenance",["generator","generatorVersion","sources"]),B=A(S.sources,"$.provenance.sources").map((b,R)=>{let h=`$.provenance.sources[${R}]`,w=I(b,h,["id","kind","license","sha256","uri"]),T=F(w.kind,`${h}.kind`);T!=="authored"&&T!=="generated"&&T!=="open-data"&&u("invalid-source-kind",`${h}.kind`,T);let J=F(w.uri,`${h}.uri`);(J.startsWith("/")||J.startsWith("file:")||J.includes("\\"))&&u("invalid-source-uri",`${h}.uri`,"local filesystem paths are forbidden");let G=w.sha256===null?null:F(w.sha256,`${h}.sha256`);return G!==null&&!jn.test(G)&&u("invalid-hash",`${h}.sha256`,"expected lowercase SHA-256"),{id:L(w.id,`${h}.id`),kind:T,uri:J,sha256:G,license:F(w.license,`${h}.license`)}});B.length===0&&u("missing-provenance","$.provenance.sources","expected at least one source"),V(B.map(b=>b.id),"$.provenance.sources");let D={generator:L(S.generator,"$.provenance.generator"),generatorVersion:F(S.generatorVersion,"$.provenance.generatorVersion"),sources:B};Ye.test(D.generatorVersion)||u("invalid-revision","$.provenance.generatorVersion","expected x.y.z");let xe=zn(t,{controls:v,springs:C,animations:g});for(let b of xe)i.includes(b)||u("missing-capability","$.capabilities",`profile requires ${b}`);let oe=x.kind==="joint-skin"?x.joints.length:0,_=k?.frames.length??0,q=[["maxVertices",l.vertices.length,s.maxVertices],["maxPolygons",l.polygons.length,s.maxPolygons],["maxLeaves",M.length,s.maxLeaves],["maxFrames",_,s.maxFrames],["maxJoints",oe,s.maxJoints]];for(let[b,R,h]of q)R>h&&u("budget-exceeded",`$.budgets.${b}`,`${R} exceeds ${h}`);return{schema:X,identity:a,profile:t,capabilities:i,budgets:s,topology:l,materials:d,render:P,deformation:x,controls:v,springs:C,animations:g,playback:k,provenance:D}}function de(n){return Ke.test(n)}function we(n){try{return Ze(n,"$"),!0}catch{return!1}}var E=class extends Error{constructor(e,r,o,a={}){super(`${r}: ${o}`),this.name="PolyMorphPackageError",this.code=e,this.path=r,"cause"in a&&(this.cause=a.cause)}};function Ie(n,e,r){if(n===null)return"null";if(typeof n=="string"||typeof n=="boolean")return JSON.stringify(n);if(typeof n=="number"){if(!Number.isFinite(n))throw new E("invalid-json",e,"numbers must be finite");return JSON.stringify(Object.is(n,-0)?0:n)}if(Array.isArray(n)){if(r.has(n))throw new E("invalid-json",e,"cycles are forbidden");r.add(n);let o=`[${n.map((a,t)=>Ie(a,`${e}[${t}]`,r)).join(",")}]`;return r.delete(n),o}if(typeof n=="object"&&n){if(r.has(n))throw new E("invalid-json",e,"cycles are forbidden");let o=Object.getPrototypeOf(n);if(o!==Object.prototype&&o!==null)throw new E("invalid-json",e,"expected a plain object");r.add(n);let a=n,t=`{${Object.keys(a).sort().map(i=>{let c=a[i];if(c===void 0||typeof c=="function"||typeof c=="symbol")throw new E("invalid-json",`${e}.${i}`,"value is not JSON");return`${JSON.stringify(i)}:${Ie(c,`${e}.${i}`,r)}`}).join(",")}}`;return r.delete(n),t}throw new E("invalid-json",e,"value is not JSON")}function Xe(n){return Ie(n,"$",new WeakSet)}function pe(n){return new TextEncoder().encode(Xe(n))}function Gn(n,e="$"){let r;try{r=new TextDecoder("utf-8",{fatal:!0}).decode(n)}catch{throw new E("invalid-utf8",e,"expected UTF-8 bytes")}try{return JSON.parse(r)}catch{throw new E("invalid-json",e,"expected valid JSON")}}async function ae(n){if(!globalThis.crypto?.subtle)throw new E("missing-crypto","$","Web Crypto is required");let e=Uint8Array.from(n),r=await globalThis.crypto.subtle.digest("SHA-256",e);return[...new Uint8Array(r)].map(o=>o.toString(16).padStart(2,"0")).join("")}var qn=/^[a-f0-9]{64}$/,Wn=/^\d+\.\d+\.\d+$/,Yn=/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/,Kn=new Set(["joint-skin","morph-regions","prepared-playback","static-prepared"]),Zn=new Set(["data","image","model"]);function j(n,e,r){throw new E(n,e,r)}function ye(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&j("invalid-type",e,"expected an object");let o=Object.keys(n).sort(),a=[...r].sort();return(o.length!==a.length||o.some((t,i)=>t!==a[i]))&&j("invalid-keys",e,`expected exactly ${a.join(", ")}`),n}function en(n,e){return Array.isArray(n)||j("invalid-type",e,"expected an array"),n}function K(n,e){return(typeof n!="string"||n.length===0)&&j("invalid-string",e,"expected a non-empty string"),n}function Ae(n,e){let r=K(n,e);return de(r)||j("invalid-id",e,"expected a normalized kebab-case id"),r}function Re(n,e){let r=K(n,e);return we(r)||j("invalid-path",e,"expected a normalized package-relative path"),r}function nn(n,e){let r=K(n,e);return Wn.test(r)||j("invalid-revision",e,"expected x.y.z"),r}function rn(n,e){let r=K(n,e);return Kn.has(r)||j("invalid-profile",e,r),r}function on(n,e){let r=K(n,e);return qn.test(r)||j("invalid-hash",e,"expected lowercase SHA-256"),r}function Qn(n,e){return(typeof n!="number"||!Number.isSafeInteger(n)||n<0)&&j("invalid-bytes",e,"expected a non-negative safe integer"),n}function Xn(n,e){let r=ye(n,e,["bytes","mediaType","path","role","sha256"]),o=K(r.role,`${e}.role`);Zn.has(o)||j("invalid-role",`${e}.role`,o);let a=K(r.mediaType,`${e}.mediaType`).toLowerCase();return(!Yn.test(a)||a!==r.mediaType)&&j("invalid-media-type",`${e}.mediaType`,"expected a normalized type/subtype"),o==="image"&&!a.startsWith("image/")&&j("invalid-media-type",`${e}.mediaType`,"image resources require an image media type"),{path:Re(r.path,`${e}.path`),role:o,mediaType:a,bytes:Qn(r.bytes,`${e}.bytes`),sha256:on(r.sha256,`${e}.sha256`)}}function Se(n,e){let r=new Set;for(let o of n)r.has(o)&&j("duplicate",e,o),r.add(o)}function tn(n,e){n.some((r,o)=>o>0&&r<=n[o-1])&&j("non-canonical-order",e,"entries must be unique and sorted")}function Oe(n){let e=ye(n,"$",["identity","modelPath","profile","resources","schema"]);e.schema!==ne&&j("invalid-schema","$.schema",`expected ${ne}`);let r=ye(e.identity,"$.identity",["id","name","revision"]),o={id:Ae(r.id,"$.identity.id"),name:K(r.name,"$.identity.name"),revision:nn(r.revision,"$.identity.revision")},a=en(e.resources,"$.resources").map((s,l)=>Xn(s,`$.resources[${l}]`));a.length===0&&j("missing-resource","$.resources","expected at least the model resource");let t=a.map(s=>s.path);Se(t,"$.resources"),tn(t,"$.resources");let i=Re(e.modelPath,"$.modelPath"),c=a.filter(s=>s.role==="model");return(c.length!==1||c[0].path!==i)&&j("invalid-model-resource","$.resources","expected exactly one model resource matching modelPath"),c[0].mediaType!=="application/json"&&j("invalid-model-resource","$.resources","model resource must be application/json"),{schema:ne,identity:o,profile:rn(e.profile,"$.profile"),modelPath:i,resources:a}}function er(n,e){let r=ye(n,e,["id","manifestPath","manifestSha256","name","profile","revision"]),o=Re(r.manifestPath,`${e}.manifestPath`);return o.endsWith("/manifest.json")||j("invalid-manifest-path",`${e}.manifestPath`,"expected a package manifest.json path"),{id:Ae(r.id,`${e}.id`),name:K(r.name,`${e}.name`),revision:nn(r.revision,`${e}.revision`),profile:rn(r.profile,`${e}.profile`),manifestPath:o,manifestSha256:on(r.manifestSha256,`${e}.manifestSha256`)}}function Ce(n){let e=ye(n,"$",["defaultId","packages","schema"]);e.schema!==ee&&j("invalid-schema","$.schema",`expected ${ee}`);let r=en(e.packages,"$.packages").map((t,i)=>er(t,`$.packages[${i}]`));r.length===0&&j("missing-package","$.packages","expected at least one package");let o=r.map(t=>t.id);Se(o,"$.packages"),tn(o,"$.packages"),Se(r.map(t=>t.manifestPath),"$.packages[*].manifestPath");let a=Ae(e.defaultId,"$.defaultId");return o.includes(a)||j("unknown-default","$.defaultId",a),{schema:ee,defaultId:a,packages:r}}var je="model.json";function nr(n){return[...new Set(n.render.leaves.flatMap(e=>[...e.atlas?[e.atlas.resourcePath]:[],...e.fallback?[e.fallback.atlas.resourcePath]:[]]))].sort()}async function Te(n,e=[]){let r=ce(n),o=pe(r),a=new Map([[je,o]]),t=[{path:je,role:"model",mediaType:"application/json",bytes:o.byteLength,sha256:await ae(o)}];for(let l of e){if(a.has(l.path))throw new E("duplicate",l.path,"resource path is already present");let d=Uint8Array.from(l.bytes);a.set(l.path,d),t.push({path:l.path,role:l.role,mediaType:l.mediaType,bytes:d.byteLength,sha256:await ae(d)})}for(let l of nr(r)){let d=t.find(p=>p.path===l);if(!d)throw new E("missing-resource",l,"model image is not included in the package");if(d.role!=="image")throw new E("invalid-role",l,"model image resource must use the image role")}t.sort((l,d)=>l.path<d.path?-1:l.path>d.path?1:0);let i=Oe({schema:ne,identity:r.identity,profile:r.profile,modelPath:je,resources:t}),c=t.reduce((l,d)=>l+d.bytes,0);if(t.length>r.budgets.maxResources)throw new E("budget-exceeded","$.budgets.maxResources",`${t.length} resources exceed ${r.budgets.maxResources}`);if(c>r.budgets.maxBytes)throw new E("budget-exceeded","$.budgets.maxBytes",`${c} bytes exceed ${r.budgets.maxBytes}`);let s=pe(i);return{manifest:i,manifestBytes:s,manifestSha256:await ae(s),files:a}}async function rr(n,e){let r=e.map(t=>({id:t.manifest.identity.id,name:t.manifest.identity.name,revision:t.manifest.identity.revision,profile:t.manifest.profile,manifestPath:t.manifestPath,manifestSha256:t.manifestSha256}));r.sort((t,i)=>t.id<i.id?-1:t.id>i.id?1:0);let o=Ce({schema:ee,defaultId:n,packages:r}),a=pe(o);return{catalog:o,bytes:a,sha256:await ae(a)}}function or(n,e){if(e.identity.id!==n.identity.id||e.identity.name!==n.identity.name||e.identity.revision!==n.identity.revision||e.profile!==n.profile)throw new E("profile-mismatch","$.model","model identity or profile does not match its manifest")}import{readFile as tr}from"fs/promises";import{dirname as ar,isAbsolute as sn,relative as ir,resolve as an,sep as sr}from"path";var Pe=class extends Error{constructor(e,r,o){super(`${r}: ${o}`),this.name="PolyMorphPrepareError",this.code=e,this.path=r}};function y(n,e,r){throw new Pe(n,e,r)}var me="polycss-morph.prepare@1";function ie(n,e,r){(!n||typeof n!="object"||Array.isArray(n))&&y("invalid-config",e,"expected an object");let o=Object.keys(n).sort(),a=[...r].sort();return(o.length!==a.length||o.some((t,i)=>t!==a[i]))&&y("invalid-config",e,`expected exactly ${a.join(", ")}`),n}function ue(n,e){return Array.isArray(n)||y("invalid-config",e,"expected an array"),n}function Z(n,e){return(typeof n!="string"||n.length===0||n!==n.trim())&&y("invalid-config",e,"expected non-empty trimmed text"),n}function Le(n,e){let r=Z(n,e);return de(r)||y("invalid-config",e,"expected a normalized kebab-case id"),r}function ln(n,e){return(typeof n!="number"||!Number.isFinite(n))&&y("invalid-config",e,"expected a finite number"),n}function re(n,e){let r=ln(n,e);return(!Number.isSafeInteger(r)||r<1)&&y("invalid-config",e,"expected a positive integer"),r}function lr(n){let e=ie(n,"$.budgets",["maxBytes","maxFrames","maxJoints","maxLeaves","maxPolygons","maxResources","maxVertices"]);return{maxVertices:re(e.maxVertices,"$.budgets.maxVertices"),maxPolygons:re(e.maxPolygons,"$.budgets.maxPolygons"),maxLeaves:re(e.maxLeaves,"$.budgets.maxLeaves"),maxFrames:re(e.maxFrames,"$.budgets.maxFrames"),maxJoints:re(e.maxJoints,"$.budgets.maxJoints"),maxResources:re(e.maxResources,"$.budgets.maxResources"),maxBytes:re(e.maxBytes,"$.budgets.maxBytes")}}function cn(n){let e=ie(n,"$",["animations","budgets","controls","identity","morphAliases","profile","schema","source","springs","transform"]);e.schema!==me&&y("invalid-config","$.schema",`expected ${me}`);let r=ie(e.identity,"$.identity",["id","name","revision"]),o={id:Le(r.id,"$.identity.id"),name:Z(r.name,"$.identity.name"),revision:Z(r.revision,"$.identity.revision")};/^\d+\.\d+\.\d+$/u.test(o.revision)||y("invalid-config","$.identity.revision","expected x.y.z");let a=Z(e.profile,"$.profile");a!=="morph-regions"&&a!=="static-prepared"&&y("invalid-config","$.profile","generic preparation supports morph-regions or static-prepared");let t=ie(e.source,"$.source",["id","kind","license","path","uri"]),i=Z(t.kind,"$.source.kind");i!=="authored"&&i!=="generated"&&i!=="open-data"&&y("invalid-config","$.source.kind","unknown source kind");let c=Z(t.path,"$.source.path");(sn(c)||c.includes("\\")||c.split("/").some(f=>f===""||f==="."||f===".."))&&y("unsafe-path","$.source.path","expected a normalized config-relative path");let s={id:Le(t.id,"$.source.id"),kind:i,path:c,uri:Z(t.uri,"$.source.uri"),license:Z(t.license,"$.source.license")};(s.uri.startsWith("/")||s.uri.startsWith("file:")||s.uri.includes("\\"))&&y("invalid-config","$.source.uri","local filesystem paths are forbidden");let l=ie(e.transform,"$.transform",["axes","center","scale","signs"]),d=ue(l.axes,"$.transform.axes");(d.length!==3||d.some(f=>f!=="x"&&f!=="y"&&f!=="z")||new Set(d).size!==3)&&y("invalid-config","$.transform.axes","expected each source axis exactly once");let p=ue(l.signs,"$.transform.signs");(p.length!==3||p.some(f=>f!==-1&&f!==1))&&y("invalid-config","$.transform.signs","expected three values of -1 or 1");let m=ln(l.scale,"$.transform.scale");m>0||y("invalid-config","$.transform.scale","expected a positive scale"),typeof l.center!="boolean"&&y("invalid-config","$.transform.center","expected a boolean");let M=ie(e.morphAliases,"$.morphAliases",Object.keys(e.morphAliases??{})),P=Object.fromEntries(Object.entries(M).map(([f,$])=>[Z(f,"$.morphAliases key"),Le($,`$.morphAliases.${f}`)]).sort(([f],[$])=>f<$?-1:f>$?1:0));return new Set(Object.values(P)).size!==Object.keys(P).length&&y("invalid-config","$.morphAliases","prepared target ids must be unique"),a==="morph-regions"!=Object.keys(P).length>0&&y("invalid-config","$.morphAliases","morph-regions requires aliases and static-prepared forbids them"),{schema:me,identity:o,profile:a,source:s,transform:{axes:d,signs:p,scale:m,center:l.center},morphAliases:P,controls:structuredClone(ue(e.controls,"$.controls")),springs:structuredClone(ue(e.springs,"$.springs")),animations:structuredClone(ue(e.animations,"$.animations")),budgets:lr(e.budgets)}}async function Ee(n){let e;try{e=JSON.parse(await tr(n,"utf8"))}catch{y("invalid-config","$","config is not readable UTF-8 JSON")}return cn(e)}function Ne(n,e){let r=an(ar(n)),o=an(r,e),a=ir(r,o);return(a===".."||a.startsWith(`..${sr}`)||sn(a))&&y("unsafe-path","$.source.path","source escapes its authoring directory"),o}import{computeSolidTrianglePlanFromCssPoints as wr,SOLID_TRIANGLE_CANONICAL_SIZE as un}from"@layoutit/polycss";import{deflateSync as cr}from"zlib";import{computeTextureAtlasPlanPublic as dr,packTextureAtlasPlansWithScale as pr}from"@layoutit/polycss";var Me=1.5,se=4,yr=Uint8Array.from([137,80,78,71,13,10,26,10]);function H(n){let e=Number(n.toFixed(10));return Object.is(e,-0)?0:e}function pn(n,e){let r=n.split(",").map(Number);return(r.length!==16||r.some(o=>!Number.isFinite(o)))&&y("unrenderable-triangle",e,"PolyCSS produced an invalid fallback matrix"),r.map(H)}function mr(n,e){let r=new Array(16).fill(0);for(let o=0;o<4;o+=1)for(let a=0;a<4;a+=1){let t=0;for(let i=0;i<4;i+=1)t+=n[i*4+a]*e[o*4+i];r[o*4+a]=H(t)}return r}function ur(n,e){let r=n[0],o=n[4],a=n[8],t=n[1],i=n[5],c=n[9],s=n[2],l=n[6],d=n[10],p=r*(i*d-c*l)-o*(t*d-c*s)+a*(t*l-i*s);(!Number.isFinite(p)||Math.abs(p)<=1e-12)&&y("unrenderable-triangle",e,"solid triangle matrix is not invertible");let m=1/p,M=(i*d-c*l)*m,P=(a*l-o*d)*m,x=(o*c-a*i)*m,f=(c*s-t*d)*m,$=(r*d-a*s)*m,v=(a*t-r*c)*m,O=(t*l-i*s)*m,C=(o*s-r*l)*m,z=(r*i-o*t)*m,g=n[12],k=n[13],S=n[14];return[H(M),H(f),H(O),0,H(P),H($),H(C),0,H(x),H(v),H(z),0,H(-(M*g+P*k+x*S)),H(-(f*g+$*k+v*S)),H(-(O*g+C*k+z*S)),1]}function fr(n,e){if(e===0)return n;let r=pn(n,"$.render.fallback"),o=[...r];return o[12]-=e*r[0]+e*r[4],o[13]-=e*r[1]+e*r[5],o[14]-=e*r[2]+e*r[6],o.map(H).join(",")}function hr(n){let[e,r,o]=n,a=[r[0]-e[0],r[1]-e[1],r[2]-e[2]],t=[o[0]-e[0],o[1]-e[1],o[2]-e[2]],i=[a[1]*t[2]-a[2]*t[1],a[2]*t[0]-a[0]*t[2],a[0]*t[1]-a[1]*t[0]],c=Math.hypot(...i);if(c<=1e-12)return null;let s=[i[0]/c,i[1]/c,i[2]/c];return{normal:s,plane:s[0]*e[0]+s[1]*e[1]+s[2]*e[2]}}function gr(n){let e=n.map(a=>hr(a.vertices)),r=new Map;for(let a=0;a<n.length;a+=1){let t=n[a].vertexIndices;for(let i=0;i<3;i+=1){let c=t[i],s=t[(i+1)%3],l=c<s?`${c}:${s}`:`${s}:${c}`,d={polygonIndex:a,edgeIndex:i},p=r.get(l);p?p.push(d):r.set(l,[d])}}let o=Array.from({length:n.length},()=>new Set);for(let a of r.values())for(let t=0;t<a.length;t+=1)for(let i=t+1;i<a.length;i+=1){let c=a[t],s=a[i],l=n[c.polygonIndex],d=n[s.polygonIndex],p=e[c.polygonIndex],m=e[s.polygonIndex];l.materialId!==d.materialId||!p||!m||p.normal[0]*m.normal[0]+p.normal[1]*m.normal[1]+p.normal[2]*m.normal[2]<1-1e-6||Math.abs(p.plane-m.plane)>1e-5||(o[c.polygonIndex].add(c.edgeIndex),o[s.polygonIndex].add(s.edgeIndex))}return o}function Pr(n,e){return n.map((r,o)=>{let a={color:"#ffffff",vertices:r.vertices.map(([s,l,d])=>[l,s,d])},t=dr(a,o,{tileSize:1,layerElevation:1,seamBleed:0});t||y("unrenderable-triangle",`$.render.leaves[${o}].fallback`,"PolyCSS produced no per-polygon atlas plan");let i=e[o],c=i.size>0?Math.ceil(Me):0;return{...t,matrix:fr(t.matrix,c),canvasW:t.canvasW+c*2,canvasH:t.canvasH+c*2,screenPts:t.screenPts.map(s=>s+c),seamBleed:i.size>0?Me:void 0,seamBleedEdges:new Set(i),seamBleedEdgeAmounts:i.size>0?new Map([...i].map(s=>[s,Me])):void 0}})}function Mr(n,e,r,o){let a=0;for(let i=0;i<n.length;i+=2){let c=(i+2)%n.length;a+=n[i]*n[c+1]-n[c]*n[i+1]}let t=a>=0?1:-1;for(let i=0;i<n.length;i+=2){let c=i/2,s=(i+2)%n.length,l=n[i],d=n[i+1],p=n[s],m=n[s+1],M=p-l,P=m-d,x=Math.hypot(M,P);if(x<=1e-12||t*(M*(o-d)-P*(r-l))/x<-(e.has(c)?Me:0))return!1}return!0}function br(n,e,r){let o=0,a=n.seamBleedEdges??new Set;for(let t=0;t<se;t+=1)for(let i=0;i<se;i+=1)Mr(n.screenPts,a,e+(i+.5)/se,r+(t+.5)/se)&&(o+=1);return Math.round(o*255/(se*se))}function xr(n){let e=4294967295;for(let r of n){e^=r;for(let o=0;o<8;o+=1)e=e>>>1^3988292384&-(e&1)}return(e^4294967295)>>>0}function Ve(n,e){let r=new TextEncoder().encode(n),o=new Uint8Array(12+e.byteLength),a=new DataView(o.buffer);return a.setUint32(0,e.byteLength),o.set(r,4),o.set(e,8),a.setUint32(8+e.byteLength,xr(o.subarray(4,8+e.byteLength))),o}function $r(n){let e=new Uint8Array(n.reduce((o,a)=>o+a.byteLength,0)),r=0;for(let o of n)e.set(o,r),r+=o.byteLength;return e}function vr(n,e,r){let o=1+n*4,a=new Uint8Array(e*o);for(let c of r)for(let s=0;s<c.canvasH;s+=1)for(let l=0;l<c.canvasW;l+=1){let d=br(c,l,s);if(d===0)continue;let p=(c.y+s)*o+1+(c.x+l)*4;a[p]=255,a[p+1]=255,a[p+2]=255,a[p+3]=d}let t=new Uint8Array(13),i=new DataView(t.buffer);return i.setUint32(0,n),i.setUint32(4,e),t[8]=8,t[9]=6,$r([yr,Ve("IHDR",t),Ve("IDAT",cr(a,{level:9})),Ve("IEND",new Uint8Array)])}function dn(n){return`assets/solid-triangles-${String(n).padStart(3,"0")}.png`}function yn(n){let e=Pr(n,gr(n)),{packed:r,atlasScale:o}=pr(e,1,null,"local");o!==1&&y("invalid-atlas","$.render.fallback","per-polygon fallback atlas must retain CSS-pixel resolution");let a=n.map((i,c)=>{let s=r.entries[c];s||y("invalid-atlas",`$.render.leaves[${c}].fallback`,"per-polygon fallback was not packed");let l=r.pages[s.pageIndex],d=pn(s.atlasMatrix,`$.render.leaves[${c}].fallback.matrix`);return{width:s.canvasW,height:s.canvasH,matrixFromLeaf:mr(ur(i.leafMatrix,`$.render.leaves[${c}].matrix`),d),atlas:{resourcePath:dn(s.pageIndex),x:s.x,y:s.y,width:s.canvasW,height:s.canvasH,pageWidth:l.width,pageHeight:l.height}}}),t=r.pages.map((i,c)=>({path:dn(c),width:i.width,height:i.height,bytes:vr(i.width,i.height,i.entries)}));return{fallbacks:a,pages:t}}var mn={name:"@layoutit/polycss-morph",version:"0.2.11",description:"Prepared retained-model deformation and playback for PolyCSS.",type:"module",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",keywords:["polycss","morph","animation","skinning","3d","css","matrix3d","dom"],license:"MIT",repository:{type:"git",url:"https://github.com/LayoutitStudio/polycss.git",directory:"packages/morph"},bugs:{url:"https://github.com/LayoutitStudio/polycss/issues"},homepage:"https://github.com/LayoutitStudio/polycss#readme",files:["dist"],exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./prepare":{types:"./dist/prepare.d.ts",import:"./dist/prepare.js",require:"./dist/prepare.cjs"}},typesVersions:{"*":{prepare:["dist/prepare.d.ts"]}},scripts:{build:"tsup",test:"vitest run","test:package":"node scripts/certify-package.mjs","test:package:registry":"node scripts/certify-package.mjs --registry-dependencies","test:coverage":"vitest run --coverage",prepack:"node ../../.github/scripts/sync-package-readmes.mjs",prepublishOnly:"npm run build"},publishConfig:{access:"public"},dependencies:{"@layoutit/polycss":"workspace:^"},devDependencies:{"@types/node":"^25.0.0","@vitest/coverage-v8":"^3.1.1","happy-dom":"^20.7.0",tsup:"^8.0.1",typescript:"^5.3.3",vitest:"^3.1.1"}};var fn=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],Ir=mn.version;function be(n){let e=Number(n.toFixed(10));return Object.is(e,-0)?0:e}function _e(n){return[be(n[0]),be(n[1]),be(n[2])]}function hn(n,e){let o=n.normalize("NFKD").replace(/([a-z0-9])([A-Z])/gu,"$1-$2").replace(/[^A-Za-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").toLowerCase()||e;return/^[a-z]/u.test(o)?o:`item-${o}`}function Sr(n,[e,r,o]){let a=n[3]*e+n[7]*r+n[11]*o+n[15];return(!Number.isFinite(a)||Math.abs(a)<1e-12)&&y("invalid-transform","$.source.nodes","node has a singular projective transform"),[(n[0]*e+n[4]*r+n[8]*o+n[12])/a,(n[1]*e+n[5]*r+n[9]*o+n[13])/a,(n[2]*e+n[6]*r+n[10]*o+n[14])/a]}function Pn(n,[e,r,o]){return[n[0]*e+n[4]*r+n[8]*o,n[1]*e+n[5]*r+n[9]*o,n[2]*e+n[6]*r+n[10]*o]}function gn(n,e){let r={x:n[0],y:n[1],z:n[2]};return _e(e.transform.axes.map((o,a)=>r[o]*e.transform.signs[a]*e.transform.scale))}function Ar(n,e){let o=[[1,0,0],[0,1,0],[0,0,1]].map(s=>{let l=Pn(n,s),d={x:l[0],y:l[1],z:l[2]};return e.transform.axes.map((p,m)=>d[p]*e.transform.signs[m]*e.transform.scale)}),[a,t,i]=o;return a[0]*(t[1]*i[2]-t[2]*i[1])-t[0]*(a[1]*i[2]-a[2]*i[1])+i[0]*(a[1]*t[2]-a[2]*t[1])<0}function Be(n,e){return[n[0]-e[0],n[1]-e[1],n[2]-e[2]]}function Rr(n,e){return[n[1]*e[2]-n[2]*e[1],n[2]*e[0]-n[0]*e[2],n[0]*e[1]-n[1]*e[0]]}function Or(n,e){let r=Math.hypot(...n);return r>1e-10||y("degenerate-triangle",e,"triangle has zero area"),_e(n.map(o=>o/r))}function Cr(n,e){let r=Array.from({length:n.length},()=>[0,0,0]);for(let o of e){let[a,t,i]=o.vertexIndices.map(s=>n[s]),c=Rr(Be(t,a),Be(i,a));Math.hypot(...c)<=1e-10&&y("degenerate-triangle",`$.topology.${o.id}`,"triangle has zero area");for(let s of o.vertexIndices)r[s][0]+=c[0],r[s][1]+=c[1],r[s][2]+=c[2]}return r.map((o,a)=>Or(o,`$.topology.normals[${a}]`))}function jr(n,e){let r={vertices:n.map(l=>[...l])},[o,a,t]=n,i=wr(r,0,{seamBleed:0},{includeColor:!1,matrixDecimals:10,primitive:"border"},o[0],o[1],o[2],a[0],a[1],a[2],t[0],t[1],t[2]),s=/^matrix3d\(([^)]+)\)$/u.exec(i?.transformText??"")?.[1]?.split(",").map(Number);return(!s||s.length!==16||s.some(l=>!Number.isFinite(l)))&&y("unrenderable-triangle",e,"PolyCSS produced no stable matrix"),s.map(be)}function Tr(n){let e=new Set(["retained-render"]);return n.profile==="morph-regions"&&(e.add("morph-targets"),e.add("sparse-updates")),n.controls.length>0&&e.add("semantic-controls"),n.springs.length>0&&e.add("springs"),n.animations.length>0&&e.add("animation"),[...e].sort()}async function Mn(n,e){let r=[],o=[],a=[],t=Object.entries(e.morphAliases),i=new Map(t.map(([,g])=>[g,[]])),c=new Set,s=0,l=0;for(let g of n.instances){let k=Ar(g.matrix,e);for(let S of g.primitives){let B=`shape-${String(s).padStart(4,"0")}-${hn(`${g.meshName}-${S.primitiveIndex}`,"mesh")}`;a.push({id:B,matrix:fn});let D=new Map(S.targets.map(_=>[_.name,_]));t.some(([_])=>!D.has(_))&&y("missing-morph",`$.source.${B}`,"every primitive must contain every configured morph target");let xe=[...new Set(S.triangles.flat())].sort((_,q)=>_-q),oe=new Map;for(let _ of xe){let q=S.positions[_];oe.set(_,r.length);let b=Sr(g.matrix,q);r.push(gn(b,e));for(let[R,h]of t){let w=D.get(R).positionDeltas[_],T=Pn(g.matrix,w);i.get(h).push(gn(T,e))}}c.add(S.materialIndex);for(let _ of S.triangles){let q=k?[_[0],_[2],_[1]]:_;o.push({id:`polygon-${String(l).padStart(6,"0")}`,shapeId:B,materialIndex:S.materialIndex,vertexIndices:[oe.get(q[0]),oe.get(q[1]),oe.get(q[2])]}),l+=1}s+=1}}if(e.transform.center){let g=[1/0,1/0,1/0],k=[-1/0,-1/0,-1/0];for(let B of r)for(let D=0;D<3;D+=1)g[D]=Math.min(g[D],B[D]),k[D]=Math.max(k[D],B[D]);let S=g.map((B,D)=>(B+k[D])/2);for(let B=0;B<r.length;B+=1)r[B]=_e(Be(r[B],S))}let d=[...c].sort((g,k)=>g-k),p=new Map(n.materials.map(g=>[g.sourceIndex,g])),m=d.map(g=>{let k=g===-1?{name:"Default",color:[1,1,1,1]}:p.get(g);return k||y("invalid-material","$.source.materials",`primitive references missing material ${g}`),{sourceIndex:g,id:g===-1?"material-default":`material-${String(g).padStart(4,"0")}-${hn(k.name,"source")}`,color:k.color}}),M=new Map(m.map(g=>[g.sourceIndex,g.id])),P=o.map(g=>({id:g.id,vertexIndices:g.vertexIndices,normalIndices:g.vertexIndices})),x=Cr(r,P),f=t.map(([,g])=>({id:g,deltas:i.get(g).map((k,S)=>({position:k,vertexIndex:S})).filter(({position:k})=>Math.hypot(...k)>1e-12).map(({position:k,vertexIndex:S})=>({vertexIndex:S,position:k,normal:null}))}));f.some(g=>g.deltas.length===0)&&y("empty-morph","$.morphAliases","every configured morph target must move at least one vertex");let $=o.map(g=>{let k=M.get(g.materialIndex);return{id:`leaf-${g.id}`,polygonId:g.id,shapeId:g.shapeId,materialId:k,strategy:"solid-triangle",width:un,height:un,matrix:jr(g.vertexIndices.map(S=>r[S]),`$.render.${g.id}`),atlas:null,fallback:null}}),v=yn(o.map((g,k)=>({vertexIndices:g.vertexIndices,vertices:g.vertexIndices.map(S=>r[S]),materialId:M.get(g.materialIndex),leafMatrix:$[k].matrix}))),O=$.map((g,k)=>({...g,fallback:v.fallbacks[k]})),C={schema:X,identity:e.identity,profile:e.profile,capabilities:Tr(e),budgets:e.budgets,topology:{vertices:r,normals:x,polygons:P},materials:m.map(({id:g,color:k})=>({id:g,color:k})),render:{modelMatrix:fn,shapes:a,leaves:O},deformation:e.profile==="morph-regions"?{kind:"morph-regions",targets:f}:{kind:"none"},controls:e.controls,springs:e.springs,animations:e.animations,playback:null,provenance:{generator:"polycss-morph",generatorVersion:Ir,sources:[{id:e.source.id,kind:e.source.kind,uri:e.source.uri,sha256:n.contentSha256,license:e.source.license}]}};return{model:ce(C),fallbackAtlasPages:v.pages}}async function Je(n,e){let r=await Mn(n,e),o=await Te(r.model,[...r.fallbackAtlasPages.map(a=>({path:a.path,role:"image",mediaType:"image/png",bytes:a.bytes}))]);return{source:n,prepared:r,package:o}}import{createHash as Lr}from"crypto";import{readFile as xn}from"fs/promises";import{dirname as Er,extname as Nr,isAbsolute as $n,relative as Vr,resolve as vn,sep as Br}from"path";var _r={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT4:16},Jr={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4};function Ue(n){return Lr("sha256").update(n).digest("hex")}function kn(n,e){try{let r=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n));return(!r||typeof r!="object"||Array.isArray(r))&&y("invalid-gltf",e,"expected a JSON object"),r}catch(r){if(r instanceof Error&&r.name==="PolyMorphPrepareError")throw r;y("invalid-gltf",e,"expected UTF-8 JSON")}}function Ur(n){n.byteLength<20&&y("invalid-glb","$.source","GLB is truncated");let e=new DataView(n.buffer,n.byteOffset,n.byteLength);(e.getUint32(0,!0)!==1179937895||e.getUint32(4,!0)!==2||e.getUint32(8,!0)!==n.byteLength)&&y("invalid-glb","$.source","invalid GLB header");let r=12,o=null,a=null;for(;r<n.byteLength;){r+8>n.byteLength&&y("invalid-glb","$.source","truncated GLB chunk header");let t=e.getUint32(r,!0),i=e.getUint32(r+4,!0),c=r+8,s=c+t;(t%4!==0||s>n.byteLength)&&y("invalid-glb","$.source","invalid GLB chunk bounds"),i===1313821514?(o&&y("invalid-glb","$.source","duplicate JSON chunk"),o=kn(n.subarray(c,s),"$.source.json")):i===5130562?(a&&y("invalid-glb","$.source","duplicate binary chunk"),a=n.subarray(c,s)):y("invalid-glb","$.source",`unsupported GLB chunk type ${i}`),r=s}return o||y("invalid-glb","$.source","missing JSON chunk"),{json:o,binary:a}}function Dr(n,e){return(typeof n!="string"||n.length===0||$n(n)||n.includes("\\")||n.includes("?")||n.includes("#")||n.split("/").some(r=>r===""||r==="."||r===".."))&&y("unsafe-path",e,"expected a normalized source-relative path"),n}function Fr(n,e){let r=/^data:application\/(?:octet-stream|gltf-buffer);base64,([A-Za-z0-9+/]*={0,2})$/u.exec(n);return r||y("unsupported-uri",e,"expected a base64 glTF buffer data URI"),Uint8Array.from(Buffer.from(r[1],"base64"))}async function Hr(n,e,r){let o=Array.isArray(n.buffers)?n.buffers:[];o.length===0&&y("missing-buffer","$.source.buffers","expected at least one buffer");let a=Er(e),t=[],i=[];for(let[c,s]of o.entries()){let l=`$.source.buffers[${c}]`;(!Number.isSafeInteger(s?.byteLength)||s.byteLength<0)&&y("invalid-buffer",l,"invalid byteLength");let d,p;if(s.uri===void 0)(c!==0||!r)&&y("missing-buffer",l,"missing URI or GLB binary chunk"),d=r,p="<glb-bin>";else if(typeof s.uri=="string"&&s.uri.startsWith("data:"))d=Fr(s.uri,`${l}.uri`),p="<embedded-base64>";else{let P=Dr(s.uri,`${l}.uri`),x=vn(a,P),f=Vr(a,x);(f===".."||f.startsWith(`..${Br}`)||$n(f))&&y("unsafe-path",`${l}.uri`,"buffer escapes source directory"),d=new Uint8Array(await xn(x)),p=P}let m=s.byteLength;(d.byteLength<m||d.byteLength-m>3)&&y("invalid-buffer",l,"buffer length disagrees with byteLength");let M=d.subarray(0,m);t.push(M),i.push({path:p,sha256:Ue(M)})}return{buffers:t,files:i}}function zr(n,e,r){switch(e){case 5120:return n.getInt8(r);case 5121:return n.getUint8(r);case 5122:return n.getInt16(r,!0);case 5123:return n.getUint16(r,!0);case 5125:return n.getUint32(r,!0);case 5126:return n.getFloat32(r,!0);default:y("invalid-accessor","$.source.accessors",`unsupported component type ${e}`)}}function Gr(n,e){switch(e){case 5120:return Math.max(-1,n/127);case 5121:return n/255;case 5122:return Math.max(-1,n/32767);case 5123:return n/65535;case 5125:return n/4294967295;default:return n}}function qr(n,e){let r=Array.isArray(n.accessors)?n.accessors:[],o=Array.isArray(n.bufferViews)?n.bufferViews:[];return(a,t)=>{let i=r[a];(!i||i.sparse!==void 0||!Number.isSafeInteger(i.count)||i.count<0)&&y("invalid-accessor",t,"missing, sparse, or invalid accessor");let c=_r[i.type],s=Jr[i.componentType],l=o[i.bufferView];(!c||!s||!l||!Number.isSafeInteger(i.bufferView)||!Number.isSafeInteger(l.buffer))&&y("invalid-accessor",t,"unsupported accessor metadata");let d=e[l.buffer];d||y("invalid-accessor",t,"references an absent buffer");let p=c*s,m=l.byteStride??p,M=l.byteOffset??0,P=i.byteOffset??0,x=l.byteLength,f=M+P,$=f+Math.max(0,i.count-1)*m+p;(!Number.isSafeInteger(M)||M<0||!Number.isSafeInteger(x)||x<0||M+x>d.byteLength||!Number.isSafeInteger(P)||P<0||P%s!==0||!Number.isSafeInteger(m)||m<p||l.byteStride!==void 0&&(m>252||m%4!==0)||!Number.isSafeInteger(f)||f<0||f%s!==0||$>M+x)&&y("invalid-accessor",t,"invalid accessor byte layout");let v=new DataView(d.buffer,d.byteOffset,d.byteLength),O=[];for(let C=0;C<i.count;C+=1){let z=[];for(let g=0;g<c;g+=1){let k=zr(v,i.componentType,f+C*m+g*s),S=i.normalized?Gr(k,i.componentType):k;Number.isFinite(S)||y("invalid-accessor",`${t}[${C}][${g}]`,"non-finite component"),z.push(Object.is(S,-0)?0:S)}O.push(c===1?z[0]:z)}return O}}function bn(n,e){return n.map((r,o)=>((!Array.isArray(r)||r.length!==3)&&y("invalid-accessor",`${e}[${o}]`,"expected VEC3"),[r[0],r[1],r[2]]))}function Wr(n,e,r){let o=e.map((t,i)=>((!Number.isSafeInteger(t)||t<0)&&y("invalid-index",`${r}[${i}]`,"expected an unsigned integer"),t)),a=[];if(n===4){o.length%3!==0&&y("invalid-primitive",r,"incomplete triangle list");for(let t=0;t<o.length;t+=3)a.push([o[t],o[t+1],o[t+2]])}else if(n===5)for(let t=2;t<o.length;t+=1)a.push(t%2===0?[o[t-2],o[t-1],o[t]]:[o[t-1],o[t-2],o[t]]);else if(n===6)for(let t=2;t<o.length;t+=1)a.push([o[0],o[t-1],o[t]]);else y("unsupported-primitive",r,`mode ${n} is not triangles, triangle strip, or triangle fan`);return a.filter(([t,i,c])=>t!==i&&i!==c&&t!==c)}var Yr=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function Kr(n,e){let r=new Array(16).fill(0);for(let o=0;o<4;o+=1)for(let a=0;a<4;a+=1)for(let t=0;t<4;t+=1)r[o*4+a]+=n[t*4+a]*e[o*4+t];return r}function Zr(n,e){if(n.matrix!==void 0)return(!Array.isArray(n.matrix)||n.matrix.length!==16||n.matrix.some(C=>typeof C!="number"||!Number.isFinite(C))||n.translation!==void 0||n.rotation!==void 0||n.scale!==void 0)&&y("invalid-node",e,"invalid or ambiguous node matrix"),n.matrix;let r=n.translation??[0,0,0],o=n.rotation??[0,0,0,1],a=n.scale??[1,1,1];(!Array.isArray(r)||r.length!==3||!Array.isArray(o)||o.length!==4||!Array.isArray(a)||a.length!==3||[...r,...o,...a].some(C=>typeof C!="number"||!Number.isFinite(C)))&&y("invalid-node",e,"invalid node TRS");let[t,i,c,s]=o,l=Math.hypot(t,i,c,s);l>0||y("invalid-node",`${e}.rotation`,"zero quaternion");let d=t/l,p=i/l,m=c/l,M=s/l,[P,x,f]=a,[$,v,O]=r;return[(1-2*(p*p+m*m))*P,2*(d*p+m*M)*P,2*(d*m-p*M)*P,0,2*(d*p-m*M)*x,(1-2*(d*d+m*m))*x,2*(p*m+d*M)*x,0,2*(d*m+p*M)*f,2*(p*m-d*M)*f,(1-2*(d*d+p*p))*f,0,$,v,O,1]}function Qr(n){let e=Array.isArray(n.nodes)?n.nodes:[],r=Array.isArray(n.scenes)?n.scenes:[],o;if(r.length>0){let i=n.scene??0,c=r[i]?.nodes;Array.isArray(c)||y("invalid-scene","$.source.scene","default scene has no nodes"),o=c}else{let i=new Set(e.flatMap(c=>Array.isArray(c.children)?c.children:[]));o=e.map((c,s)=>s).filter(c=>!i.has(c))}let a=[],t=(i,c,s)=>{(!Number.isSafeInteger(i)||i<0||i>=e.length)&&y("invalid-node","$.source.nodes",`unknown node ${i}`),s.has(i)&&y("invalid-node","$.source.nodes",`node cycle at ${i}`);let l=e[i],d=Kr(c,Zr(l,`$.source.nodes[${i}]`));l.mesh!==void 0&&((!Number.isSafeInteger(l.mesh)||l.mesh<0)&&y("invalid-node",`$.source.nodes[${i}].mesh`,"invalid mesh index"),a.push({nodeIndex:i,nodeName:typeof l.name=="string"&&l.name.length>0?l.name:`node-${i}`,meshIndex:l.mesh,matrix:d}));let p=new Set(s).add(i),m=l.children??[];Array.isArray(m)||y("invalid-node",`$.source.nodes[${i}].children`,"expected an array");for(let M of m)t(M,d,p)};for(let i of o)t(i,Yr,new Set);return a}function Xr(n){return(Array.isArray(n.materials)?n.materials:[]).map((r,o)=>{(!r||typeof r!="object"||Array.isArray(r))&&y("invalid-material",`$.source.materials[${o}]`,"expected a material object");let a=r.pbrMetallicRoughness?.baseColorFactor??[1,1,1,1];return(!Array.isArray(a)||a.length!==4||a.some(t=>typeof t!="number"||!Number.isFinite(t)||t<0||t>1))&&y("invalid-material",`$.source.materials[${o}]`,"baseColorFactor must have four unit components"),{sourceIndex:o,name:typeof r.name=="string"&&r.name.length>0?r.name:`material-${o}`,color:[a[0],a[1],a[2],a[3]]}})}function eo(n,e,r){let o=qr(n,e),a=Array.isArray(n.meshes)?n.meshes:[];return r.map(t=>{let i=a[t.meshIndex];(!i||!Array.isArray(i.primitives)||i.primitives.length===0)&&y("invalid-mesh",`$.source.meshes[${t.meshIndex}]`,"mesh has no primitives");let c=Array.isArray(i.extras?.targetNames)?i.extras.targetNames.map(String):[],s=i.primitives.map((l,d)=>{let p=`$.source.meshes[${t.meshIndex}].primitives[${d}]`;(!l?.attributes||!Number.isSafeInteger(l.attributes.POSITION))&&y("invalid-primitive",p,"missing POSITION accessor");let m=bn(o(l.attributes.POSITION,`${p}.POSITION`),`${p}.POSITION`),M=l.indices===void 0?m.map(($,v)=>v):o(l.indices,`${p}.indices`),P=Wr(l.mode??4,M,`${p}.indices`);(P.length===0||P.some($=>$.some(v=>v>=m.length)))&&y("invalid-index",p,"triangle indices are empty or out of range");let x=Array.isArray(l.targets)?l.targets.map(($,v)=>{Number.isSafeInteger($.POSITION)||y("invalid-morph",`${p}.targets[${v}]`,"missing POSITION accessor");let O=bn(o($.POSITION,`${p}.targets[${v}].POSITION`),`${p}.targets[${v}].POSITION`);return O.length!==m.length&&y("invalid-morph",`${p}.targets[${v}]`,"target does not cover POSITION"),{index:v,name:c[v]??`morph-${v}`,positionDeltas:O}}):[],f=l.material??-1;return(!Number.isSafeInteger(f)||f<-1)&&y("invalid-material",`${p}.material`,"invalid material index"),{primitiveIndex:d,materialIndex:f,positions:m,triangles:P,targets:x}});return{...t,meshName:typeof i.name=="string"&&i.name.length>0?i.name:`mesh-${t.meshIndex}`,primitives:s}})}async function De(n){let e=vn(n),r=new Uint8Array(await xn(e)),o=Nr(e).toLowerCase(),a,t,i=null;o===".glb"?(a="glb",{json:t,binary:i}=Ur(r)):o===".gltf"?(a="gltf",t=kn(r,"$.source")):y("unsupported-format","$.source.path","expected .gltf or .glb"),(t.asset?.version!=="2.0"||Array.isArray(t.extensionsRequired)&&t.extensionsRequired.length>0)&&y("unsupported-gltf","$.source","expected core glTF 2.0 without required extensions");let c=await Hr(t,e,i),s=eo(t,c.buffers,Qr(t));s.length===0&&y("empty-model","$.source","default scene has no mesh instances");let l=Ue(r),d=Ue(new TextEncoder().encode(JSON.stringify({source:l,buffers:c.files})));return{format:a,sourceBytes:r.byteLength,sourceSha256:l,contentSha256:d,materials:Xr(t),instances:s}}import{existsSync as le}from"fs";import{mkdir as wn,mkdtemp as no,readFile as ro,readdir as oo,rename as Fe,rm as In,writeFile as to}from"fs/promises";import{basename as ao,dirname as Sn,isAbsolute as io,join as He,parse as so,relative as lo,resolve as ze,sep as co}from"path";function po(n){(typeof n!="string"||n.length===0)&&y("invalid-argument","$.outputRoot","expected a path");let e=ze(n);return e===so(e).root&&y("unsafe-path","$.outputRoot","filesystem root is forbidden"),e}async function An(n,e=""){let r=He(n,e),o=await oo(r,{withFileTypes:!0}),a=[];for(let t of o.sort((i,c)=>i.name<c.name?-1:i.name>c.name?1:0)){let i=e===""?t.name:`${e}/${t.name}`;t.isSymbolicLink()&&y("unsafe-output",i,"symbolic links are forbidden"),t.isDirectory()?a.push(...await An(n,i)):t.isFile()?a.push(i):y("unsafe-output",i,"unsupported filesystem entry")}return a}async function Rn(n,e){if(!le(n))return{path:"$.outputRoot",message:"prepared package is missing"};let r=await An(n),o=[...e.keys()].sort();if(r.length!==o.length||r.some((a,t)=>a!==o[t]))return{path:"$.outputRoot",message:`inventory differs: expected ${o.join(", ")}`};for(let a of o){let t=new Uint8Array(await ro(He(n,a))),i=e.get(a);if(t.byteLength!==i.byteLength||t.some((c,s)=>c!==i[s]))return{path:a,message:"prepared bytes differ"}}return null}async function yo(n,e){let r=await Rn(n,e);r&&y("drift",r.path,r.message)}async function mo(n,e){let r=Sn(n);await wn(r,{recursive:!0});let o=await no(He(r,`.polycss-morph-${ao(n)}-`)),a=`${n}.previous-${process.pid}`,i=[...[...e.keys()].filter(s=>s!=="manifest.json").sort(),"manifest.json"],c=!1;try{for(let s of i){let l=ze(o,s),d=lo(o,l);(d===".."||d.startsWith(`..${co}`)||io(d))&&y("unsafe-path",s,"package path escapes staging"),await wn(Sn(l),{recursive:!0}),await to(l,e.get(s))}return le(a)&&y("unsafe-output","$.outputRoot",`backup already exists at ${a}`),le(n)&&(await Fe(n,a),c=!0),await Fe(o,n),c&&await In(a,{recursive:!0,force:!0}).catch(()=>{}),i}catch(s){throw c&&!le(n)&&le(a)&&await Fe(a,n),s}finally{le(o)&&await In(o,{recursive:!0,force:!0})}}async function uo(n){(!n||typeof n!="object")&&y("invalid-argument","$","expected prepare options"),(typeof n.configPath!="string"||n.configPath.length===0)&&y("invalid-argument","$.configPath","expected a path"),n.check!==void 0&&typeof n.check!="boolean"&&y("invalid-argument","$.check","expected a boolean");let e=ze(n.configPath),r=po(n.outputRoot),o=await Ee(e),a=Ne(e,o.source.path),t=await De(a),i=await Je(t,o),c=new Map(i.package.files);c.set("manifest.json",i.package.manifestBytes);let s=[...c.keys()].sort();if(n.check)return await yo(r,c),{config:o,source:t,model:i.prepared.model,manifest:i.package.manifest,manifestSha256:i.package.manifestSha256,outputRoot:r,files:s,writeOrder:[],checked:!0,changed:!1};if(await Rn(r,c)===null)return{config:o,source:t,model:i.prepared.model,manifest:i.package.manifest,manifestSha256:i.package.manifestSha256,outputRoot:r,files:s,writeOrder:[],checked:!1,changed:!1};let l=await mo(r,c);return{config:o,source:t,model:i.prepared.model,manifest:i.package.manifest,manifestSha256:i.package.manifestSha256,outputRoot:r,files:s,writeOrder:l,checked:!1,changed:!0}}export{ee as POLY_MORPH_CATALOG_SCHEMA,X as POLY_MORPH_MODEL_SCHEMA,ne as POLY_MORPH_PACKAGE_SCHEMA,me as POLY_MORPH_PREPARE_SCHEMA,he as PolyMorphContractError,E as PolyMorphPackageError,Pe as PolyMorphPrepareError,or as assertPolyMorphPackageModelBinding,rr as buildPolyMorphCatalog,Te as buildPolyMorphPackage,Je as buildPolyMorphPreparedPackage,Mn as compilePolyMorphSource,Gn as decodePolyMorphJson,pe as encodePolyMorphCanonicalJson,y as failPolyMorphPrepare,ae as hashPolyMorphBytes,de as isPolyMorphId,we as isPolyMorphResourcePath,De as loadPolyMorphGltf,cn as parsePolyMorphPrepareConfig,uo as preparePolyMorphModel,Ee as readPolyMorphPrepareConfig,Ne as resolvePolyMorphSourcePath,Xe as stringifyPolyMorphCanonicalJson,Ce as validatePolyMorphCatalog,ce as validatePolyMorphModel,Oe as validatePolyMorphPackageManifest};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layoutit/polycss-morph",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "Prepared retained-model deformation and playback for PolyCSS.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -52,7 +52,7 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "@layoutit/polycss": "^0.2.10"
55
+ "@layoutit/polycss": "^0.2.11"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node": "^25.0.0",