@cratefit/pack 0.1.0

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/index.js ADDED
@@ -0,0 +1,360 @@
1
+ /**
2
+ * CrateFit SDK v0.1.0
3
+ * Copyright (c) 2026 supra126 (https://github.com/supra126)
4
+ * Licensed under CrateFit SDK License
5
+ * https://github.com/supra126/cratefit
6
+ */
7
+ var y={RT_WHD:0,RT_HWD:1,RT_HDW:2,RT_DHW:3,RT_DWH:4,RT_WDH:5};function D(t,e){return {minX:t.x,maxX:t.x+e.width,minY:t.y,maxY:t.y+e.height,minZ:t.z,maxZ:t.z+e.depth}}function B(t,e){return !(t.maxX<=e.minX||e.maxX<=t.minX||t.maxY<=e.minY||e.maxY<=t.minY||t.maxZ<=e.minZ||e.maxZ<=t.minZ)}function oi(t,e){return t.minX<=e.minX&&t.maxX>=e.maxX&&t.minY<=e.minY&&t.maxY>=e.maxY&&t.minZ<=e.minZ&&t.maxZ>=e.maxZ}function ri(t){return (t.maxX-t.minX)*(t.maxY-t.minY)*(t.maxZ-t.minZ)}function P(t){return t.width*t.height*t.depth}function v(t){return D(t.position,t.dimensions)}function _(t,e){let i=Math.max(0,Math.min(t.maxX,e.maxX)-Math.max(t.minX,e.minX)),n=Math.max(0,Math.min(t.maxZ,e.maxZ)-Math.max(t.minZ,e.minZ));return i*n}function ai(t,e){let i=v(t),n=v(e);return i.minY!==n.maxY?false:_(i,n)>0}var yt=class{items=[];insert(t){this.items.push(t);}remove(t){let e=this.items.findIndex(i=>i.item.id===t.item.id);e!==-1&&this.items.splice(e,1);}query(t){return this.items.filter(e=>{let i=v(e);return B(i,t)})}clear(){this.items=[];}getAll(){return [...this.items]}get size(){return this.items.length}};function O(){return new yt}function L(t,e,i){let n=D(t,e),s=i.query(n);for(let o of s){let r=v(o);if(B(n,r))return true}return false}function X(t,e,i){return t.x>=0&&t.y>=0&&t.z>=0&&t.x+e.width<=i.width&&t.y+e.height<=i.height&&t.z+e.depth<=i.depth}function N(t,e,i){if(!i.excludeZones||i.excludeZones.length===0)return false;let n=D(t,e);for(let s of i.excludeZones)if(B(n,s))return true;return false}function Y(t,e,i){if(!i.maxWeight)return true;let n=t.reduce((o,r)=>o+(r.item.weight||0),0),s=e.weight||0;return n+s<=i.maxWeight}function zt(t){return t.reduce((e,i)=>e+(i.item.weight||0),0)}function ot(t,e){let i=0,n=0,s=0,o=0;for(let r of t){let a=r.item.weight||0;if(a<=0)continue;let u=r.position.x+r.dimensions.width/2,h=r.position.y+r.dimensions.height/2,d=r.position.z+r.dimensions.depth/2;n+=a*u,s+=a*h,o+=a*d,i+=a;}return i<=0?{x:e.width/2,y:0,z:e.depth/2}:{x:n/i,y:s/i,z:o/i}}function hi(t,e,i=.15){let n=ot(t,e),s=e.width/2,o=e.depth/2;return Math.abs(n.x-s)<e.width*i&&Math.abs(n.z-o)<e.depth*i}function rt(t,e,i){if(t.y===0)return e.width*e.depth;let n=D(t,e),s=0;for(let o of i){let r=v(o);r.maxY===n.minY&&(s+=_(n,r));}return s}function V(t,e,i,n=.7){if(t.y===0)return true;let s=e.width*e.depth;return s<=0?false:rt(t,e,i)/s>=n}function ui(t,e,i){if(!t.item.maxStackWeight)return true;let n=v(t),s=e;for(let o of i){let r=v(o);r.minY>=n.maxY&&_(r,n)>0&&(s+=o.item.weight||0);}return s<=t.item.maxStackWeight}function I(t,e,i,n){switch(n){case y.RT_WHD:return {width:t,height:e,depth:i};case y.RT_HWD:return {width:e,height:t,depth:i};case y.RT_HDW:return {width:e,height:i,depth:t};case y.RT_DHW:return {width:i,height:e,depth:t};case y.RT_DWH:return {width:i,height:t,depth:e};case y.RT_WDH:return {width:t,height:i,depth:e};default:return {width:t,height:e,depth:i}}}function T(t){switch(t){case "all":return [y.RT_WHD,y.RT_HWD,y.RT_HDW,y.RT_DHW,y.RT_DWH,y.RT_WDH];case "horizontal":return [y.RT_WHD,y.RT_DWH];case "fixed":return [y.RT_WHD];default:return [y.RT_WHD]}}function ci(t,e,i,n){return n.map(s=>({rotation:s,dimensions:I(t,e,i,s)}))}function G(t,e,i={}){let n=O(),s=[],o=[],r={projectToSupport:i.features?.supportCheck??true,maxPoints:3e3};if(t.existingItems)for(let u of t.existingItems)n.insert(u),s.push(u);let a=Mt(t);if(t.existingItems)for(let u of t.existingItems)a=K(a,u,t,s,r);for(let u of e){let h=bt(u,a,t,s,n,i);if(h){let d={item:u,position:{x:h.point.x,y:h.point.y,z:h.point.z},rotation:h.rotation,dimensions:h.dimensions};s.push(d),n.insert(d),a=K(a,d,t,s,r);}else o.push(u);}return {packed:s,unpacked:o}}function bt(t,e,i,n,s,o,r){let a=t.allowedRotations||T(t.rotationType||"all"),u=[],h=[...e].sort((d,c)=>d.score-c.score);for(let d of h)for(let c of a){let l=I(t.width,t.height,t.depth,c);if(!X(d,l,i)||N(d,l,i)||L(d,l,s)||!Y(n,t,i))continue;if(o.features?.supportCheck){let m=t.requiresSupport??.5;if(!V(d,l,n,m))continue}let p=vt(d,l,i,n),f={point:d,rotation:c,dimensions:l,score:p};return f;}return u.length>0?(u.sort((d,c)=>d.score-c.score),u[0]):null}function vt(t,e,i,n){let s=t.x/i.width,o=t.y/i.height,r=t.z/i.depth,a=o*100+r*10+s;t.y===0&&(a-=50);let u=t.x===0||t.x+e.width===i.width,h=t.z===0||t.z+e.depth===i.depth;u&&(a-=5),h&&(a-=5);let d=Bt(t,e,n);a-=d*3;let c=rt(t,e,n),l=e.width*e.depth;return t.y>0&&c<l*.9&&(a+=10),a}function Bt(t,e,i){let n=0,s=.001;for(let o of i){let r=o.position.x,a=o.position.y,u=o.position.z,h=o.dimensions,d=(Math.abs(t.x-(r+h.width))<s||Math.abs(t.x+e.width-r)<s)&&kt(t,e,o),c=(Math.abs(t.y-(a+h.height))<s||Math.abs(t.y+e.height-a)<s)&&St(t,e,o),l=(Math.abs(t.z-(u+h.depth))<s||Math.abs(t.z+e.depth-u)<s)&&It(t,e,o);(d||c||l)&&n++;}return n}function kt(t,e,i){let n=i.position,s=i.dimensions;return t.y<n.y+s.height&&t.y+e.height>n.y&&t.z<n.z+s.depth&&t.z+e.depth>n.z}function St(t,e,i){let n=i.position,s=i.dimensions;return t.x<n.x+s.width&&t.x+e.width>n.x&&t.z<n.z+s.depth&&t.z+e.depth>n.z}function It(t,e,i){let n=i.position,s=i.dimensions;return t.x<n.x+s.width&&t.x+e.width>n.x&&t.y<n.y+s.height&&t.y+e.height>n.y}function K(t,e,i,n,s){let{position:o,dimensions:r}=e,a=[],u=$(o.x+r.width,o.y,o.z,i,n,s);u&&a.push(u);let h=$(o.x,o.y+r.height,o.z,i,n,s);h&&a.push(h);let d=$(o.x,o.y,o.z+r.depth,i,n,s);d&&a.push(d);let c=$(o.x+r.width,o.y,o.z+r.depth,i,n,s);c&&a.push(c);let l=$(o.x+r.width,o.y+r.height,o.z,i,n,s);l&&a.push(l);let p=$(o.x,o.y+r.height,o.z+r.depth,i,n,s);p&&a.push(p);let f=D(o,r);for(let g of t){let x=D(g,{width:.001,height:.001,depth:.001});B(x,f)||a.push(g);}let m=at(a);return s.maxPoints&&m.length>s.maxPoints?(m.sort((g,x)=>g.score-x.score),m.slice(0,s.maxPoints)):m}function $(t,e,i,n,s,o){if(t<0||t>=n.width||e<0||e>=n.height||i<0||i>=n.depth)return null;let r=e,a=e===0;if(o.projectToSupport&&e>0){let h=At(t,i,s,e);h!==null?(r=h,a=true):e>0&&(a=false);}let u=E(t,r,i,n,a);return {x:t,y:r,z:i,score:u,onSupport:a}}function At(t,e,i,n){let s=null;for(let o of i){let r=o.position.x,a=o.position.y,u=o.position.z,h=o.dimensions;if(t>=r&&t<r+h.width&&e>=u&&e<u+h.depth){let d=a+h.height;d<=n&&(s===null||d>s)&&(s=d);}}return s}function E(t,e,i,n,s){let o=t/n.width,r=e/n.height,a=i/n.depth,u=r*100+a*10+o;return e===0&&(u-=20),s&&(u-=10),t===0&&(u-=5),i===0&&(u-=5),u}function at(t){let e=[];for(let n of t)e.some(o=>Math.abs(o.x-n.x)<.001&&Math.abs(o.y-n.y)<.001&&Math.abs(o.z-n.z)<.001)||e.push(n);return e}function Mt(t,e){let i=[],n={x:0,y:0,z:0,score:0,onSupport:true};if(i.push(n),!t.excludeZones||t.excludeZones.length===0)return i;for(let s of t.excludeZones)if(!(s.minY>0)){if(s.minX===0&&s.maxX<t.width){let o={x:s.maxX,y:0,z:0,score:E(s.maxX,0,0,t,true),onSupport:true};i.push(o),s.minZ===0&&s.maxZ<t.depth&&(i.push({x:0,y:0,z:s.maxZ,score:E(0,0,s.maxZ,t,true),onSupport:true}),i.push({x:s.maxX,y:0,z:s.maxZ,score:E(s.maxX,0,s.maxZ,t,true),onSupport:true}));}if(s.minZ===0&&s.maxZ<t.depth&&s.minX!==0){let o={x:0,y:0,z:s.maxZ,score:E(0,0,s.maxZ,t,true),onSupport:true};i.push(o);}s.minX>0&&i.push({x:0,y:0,z:0,score:0,onSupport:true}),s.minZ>0&&i.push({x:0,y:0,z:0,score:0,onSupport:true});}return at(i)}function $t(t,e,i={}){let n=O(),s=[],o=[];({heightTolerance:Math.min(t.height*.1,50)});let a=0;if(t.existingItems)for(let d of t.existingItems)n.insert(d),s.push(d),a=Math.max(a,d.position.y+d.dimensions.height);let h=[...[...e].sort((d,c)=>{let l=Math.max(d.height,d.width,d.depth);return Math.max(c.height,c.width,c.depth)-l})];for(;h.length>0&&a<t.height;){let d=Ct(h,t,a,s,n,i);if(d.items.length===0)break;for(let c of d.items){s.push(c),n.insert(c);let l=h.findIndex(p=>p.id===c.item.id);l!==-1&&h.splice(l,1);}a=d.yLevel+d.height;}return o.push(...h),{packed:s,unpacked:o}}function Ct(t,e,i,n,s,o,r){let a={yLevel:i,height:0,items:[],spaces:[{x:0,z:0,width:e.width,depth:e.depth}]},u=0,h=[...t];for(let d of h){if(a.items.some(l=>l.item.id===d.id))continue;let c=Dt(d,a,e,i,n,s,o);if(c){u===0&&(u=c.dimensions.height);let l={item:d,position:c.position,rotation:c.rotation,dimensions:c.dimensions};a.items.push(l),a.height=Math.max(a.height,c.dimensions.height),a.spaces=Tt(a.spaces,{x:c.position.x,z:c.position.z,width:c.dimensions.width,depth:c.dimensions.depth});}}return a}function Dt(t,e,i,n,s,o,r,a,u){let h=t.allowedRotations||T(t.rotationType||"all"),d=[...e.spaces].sort((c,l)=>c.z!==l.z?c.z-l.z:c.x-l.x);for(let c of d)for(let l of h){let p=I(t.width,t.height,t.depth,l);if(p.width>c.width||p.depth>c.depth)continue;let f={x:c.x,y:n,z:c.z};if(X(f,p,i)&&!N(f,p,i)&&!L(f,p,o)&&Y([...s,...e.items],t,i)){if(r.features?.supportCheck){let m=[...s,...e.items],g=t.requiresSupport??.5;if(!V(f,p,m,g))continue}return {position:f,rotation:l,dimensions:p}}}return null}function Tt(t,e){let i=[];for(let n of t){if(!Wt(n,e)){i.push(n);continue}let s=Et(n,e);i.push(...s);}return Pt(i)}function Wt(t,e){return !(t.x+t.width<=e.x||e.x+e.width<=t.x||t.z+t.depth<=e.z||e.z+e.depth<=t.z)}function Et(t,e){let i=[];return e.x+e.width<t.x+t.width&&i.push({x:e.x+e.width,z:t.z,width:t.x+t.width-(e.x+e.width),depth:t.depth}),e.z+e.depth<t.z+t.depth&&i.push({x:t.x,z:e.z+e.depth,width:t.width,depth:t.z+t.depth-(e.z+e.depth)}),t.x<e.x&&i.push({x:t.x,z:t.z,width:e.x-t.x,depth:t.depth}),t.z<e.z&&i.push({x:t.x,z:t.z,width:t.width,depth:e.z-t.z}),i}function Pt(t){return t.filter(i=>i.width>=1&&i.depth>=1)}function di(t,e,i){let n=new Map;for(let r of t){let a=r.position.y;n.has(a)||n.set(a,[]),n.get(a).push(r);}let s=[],o=[...n.keys()].sort((r,a)=>r-a);for(let r of o){let a=n.get(r),u=Math.max(...a.map(d=>d.dimensions.height)),h=0;if(e&&i){let d=e*i;d>0&&(h=a.reduce((l,p)=>l+p.dimensions.width*p.dimensions.depth,0)/d);}s.push({yLevel:r,height:u,items:a,coverage:h});}return s}function Ft(t,e,i={}){let n=O(),s=[],o=[];({depthTolerance:Math.min(t.depth*.1,50)});let a=0;if(t.existingItems)for(let d of t.existingItems)n.insert(d),s.push(d),a=Math.max(a,d.position.z+d.dimensions.depth);let h=[...[...e].sort((d,c)=>{let l=Math.max(d.depth,d.width,d.height);return Math.max(c.depth,c.width,c.height)-l})];for(;h.length>0&&a<t.depth;){let d=Rt(h,t,a,s,n,i);if(d.items.length===0)break;for(let c of d.items){s.push(c),n.insert(c);let l=h.findIndex(p=>p.id===c.item.id);l!==-1&&h.splice(l,1);}a=d.zStart+d.depth;}return o.push(...h),{packed:s,unpacked:o}}function Rt(t,e,i,n,s,o,r){let a={zStart:i,depth:0,items:[],spaces:[{x:0,y:0,width:e.width,height:e.height}]},u=0,h=[...t];for(let d of h){if(a.items.some(l=>l.item.id===d.id))continue;let c=Zt(d,a,e,i,n,s,o);if(c){u===0&&(u=c.dimensions.depth);let l={item:d,position:c.position,rotation:c.rotation,dimensions:c.dimensions};a.items.push(l),a.depth=Math.max(a.depth,c.dimensions.depth),a.spaces=Ot(a.spaces,{x:c.position.x,y:c.position.y,width:c.dimensions.width,height:c.dimensions.height});}}return a}function Zt(t,e,i,n,s,o,r,a,u){let h=t.allowedRotations||T(t.rotationType||"all"),d=[...e.spaces].sort((c,l)=>c.y!==l.y?c.y-l.y:c.x-l.x);for(let c of d)for(let l of h){let p=I(t.width,t.height,t.depth,l);if(p.width>c.width||p.height>c.height||n+p.depth>i.depth)continue;let f={x:c.x,y:c.y,z:n};if(X(f,p,i)&&!N(f,p,i)&&!L(f,p,o)&&Y([...s,...e.items],t,i)){if(r.features?.supportCheck){let m=[...s,...e.items],g=t.requiresSupport??.5;if(!V(f,p,m,g))continue}return {position:f,rotation:l,dimensions:p}}}return null}function Ot(t,e){let i=[];for(let n of t){if(!Lt(n,e)){i.push(n);continue}let s=Xt(n,e);i.push(...s);}return Nt(i)}function Lt(t,e){return !(t.x+t.width<=e.x||e.x+e.width<=t.x||t.y+t.height<=e.y||e.y+e.height<=t.y)}function Xt(t,e){let i=[];return e.x+e.width<t.x+t.width&&i.push({x:e.x+e.width,y:t.y,width:t.x+t.width-(e.x+e.width),height:t.height}),e.y+e.height<t.y+t.height&&i.push({x:t.x,y:e.y+e.height,width:t.width,height:t.y+t.height-(e.y+e.height)}),t.x<e.x&&i.push({x:t.x,y:t.y,width:e.x-t.x,height:t.height}),t.y<e.y&&i.push({x:t.x,y:t.y,width:t.width,height:e.y-t.y}),i}function Nt(t){return t.filter(i=>i.width>=1&&i.height>=1)}function li(t,e){let i=e.depth*.05,n=new Map;for(let r of t){let a=r.position.z,u=false;for(let[h]of n)if(Math.abs(a-h)<=i){n.get(h).push(r),u=true;break}u||n.set(a,[r]);}let s=[],o=[...n.keys()].sort((r,a)=>r-a);for(let r of o){let a=n.get(r),u=Math.max(...a.map(c=>c.position.z+c.dimensions.depth)),h=e.width*e.height,d=a.reduce((c,l)=>c+l.dimensions.width*l.dimensions.height,0);s.push({zStart:r,zEnd:u,items:a,utilization:d/h});}return s}function Yt(t,e,i={}){let n=O(),s=[],o=0;if(t.existingItems)for(let a of t.existingItems)n.insert(a),s.push(a),o=Math.max(o,a.position.y+a.dimensions.height);let r=[...e];for(;r.length>0&&o<t.height;){let a=Vt(r,t,o);if(!a||a.potentialItems.length===0)break;let u=Ut(r,t,o,a.height,s,n,i);if(u.placedItems.length===0)break;for(let h of u.placedItems){s.push(h),n.insert(h);let d=r.findIndex(c=>c.id===h.item.id);d!==-1&&r.splice(d,1);}o+=a.height;}return {packed:s,unpacked:r}}function Vt(t,e,i){let n=e.height-i,s=new Set;for(let r of t)r.width<=n&&s.add(r.width),r.height<=n&&s.add(r.height),r.depth<=n&&s.add(r.depth);if(s.size===0)return null;let o=[];for(let r of s){let a=Ht(t,e,r,n);o.push(a);}return o.sort((r,a)=>a.score-r.score),o[0]}function Ht(t,e,i,n){let s=[],o=0,r=0;for(let l of t){let p=l.allowedRotations||T(l.rotationType||"all");for(let f of p){let m=I(l.width,l.height,l.depth,f);if(m.height<=i){s.push(l),o+=m.width*m.depth,Math.abs(m.height-i)<1&&r++;break}}}let a=e.width*e.depth,u=Math.min(o/a,1),h=i/n,d=r/Math.max(s.length,1),c=u*100+(1-h)*20+d*30;return {height:i,score:c,potentialItems:s}}function Ut(t,e,i,n,s,o,r){let a=[],u=[{x:0,y:i,z:0,width:e.width,height:n,depth:e.depth}],h=[...t].sort((d,c)=>{let l=d.width*d.height*d.depth;return c.width*c.height*c.depth-l});for(let d of h){if(a.some(l=>l.item.id===d.id))continue;let c=jt(d,u,e,i,n,s,a,o,r);if(c){let l={item:d,position:c.position,rotation:c.rotation,dimensions:c.dimensions};a.push(l),Gt(u,c.position,c.dimensions);}}return {placedItems:a,gaps:u}}function jt(t,e,i,n,s,o,r,a,u){let h=t.allowedRotations||T(t.rotationType||"all"),d=null,c=[...e].sort((l,p)=>l.z!==p.z?l.z-p.z:l.x!==p.x?l.x-p.x:l.y-p.y);for(let l of c)for(let p of h){let f=I(t.width,t.height,t.depth,p);if(f.width>l.width||f.height>l.height||f.depth>l.depth||f.height>s)continue;let m={x:l.x,y:l.y,z:l.z};if(!X(m,f,i)||N(m,f,i)||L(m,f,a))continue;let g=[...o,...r];if(!Y(g,t,i))continue;if(u.features?.supportCheck){let w=t.requiresSupport??.5;if(!V(m,f,g,w))continue}let x=_t(l,f);(!d||x<d.score)&&(d={position:m,rotation:p,dimensions:f,score:x});}return d}function _t(t,e){let i=t.width-e.width,n=t.height-e.height,s=t.depth-e.depth,o=i*n*s,r=0;i===0&&(r-=100),n===0&&(r-=100),s===0&&(r-=100);let a=t.z+t.x*.1+t.y*.01;return o+r+a}function Gt(t,e,i){let n=e.x+i.width,s=e.y+i.height,o=e.z+i.depth,r=[];for(let u=0;u<t.length;u++){let h=t[u];if(e.x>=h.x+h.width||n<=h.x||e.y>=h.y+h.height||s<=h.y||e.z>=h.z+h.depth||o<=h.z){r.push(h);continue}n<h.x+h.width&&r.push({x:n,y:h.y,z:h.z,width:h.x+h.width-n,height:h.height,depth:h.depth}),s<h.y+h.height&&r.push({x:h.x,y:s,z:h.z,width:h.width,height:h.y+h.height-s,depth:h.depth}),o<h.z+h.depth&&r.push({x:h.x,y:h.y,z:o,width:h.width,height:h.height,depth:h.z+h.depth-o}),e.x>h.x&&r.push({x:h.x,y:h.y,z:h.z,width:e.x-h.x,height:h.height,depth:h.depth}),e.y>h.y&&r.push({x:h.x,y:h.y,z:h.z,width:h.width,height:e.y-h.y,depth:h.depth}),e.z>h.z&&r.push({x:h.x,y:h.y,z:h.z,width:h.width,height:h.height,depth:e.z-h.z});}t.length=0;let a=1;for(let u of r)u.width>=a&&u.height>=a&&u.depth>=a&&t.push(u);qt(t);}function qt(t){let e=true,i=0,n=Math.max(t.length*t.length,1e3);for(;e&&i<n;){e=false,i++;for(let s=0;s<t.length;s++){for(let o=s+1;o<t.length;o++){let r=t[s],a=t[o],u=Kt(r,a);if(u){t[s]=u,t.splice(o,1),e=true;break}}if(e)break}}}function Kt(t,e){return Math.abs(t.x+t.width-e.x)<.001&&Math.abs(t.y-e.y)<.001&&Math.abs(t.height-e.height)<.001&&Math.abs(t.z-e.z)<.001&&Math.abs(t.depth-e.depth)<.001?{x:t.x,y:t.y,z:t.z,width:t.width+e.width,height:t.height,depth:t.depth}:Math.abs(t.y+t.height-e.y)<.001&&Math.abs(t.x-e.x)<.001&&Math.abs(t.width-e.width)<.001&&Math.abs(t.z-e.z)<.001&&Math.abs(t.depth-e.depth)<.001?{x:t.x,y:t.y,z:t.z,width:t.width,height:t.height+e.height,depth:t.depth}:Math.abs(t.z+t.depth-e.z)<.001&&Math.abs(t.x-e.x)<.001&&Math.abs(t.width-e.width)<.001&&Math.abs(t.y-e.y)<.001&&Math.abs(t.height-e.height)<.001?{x:t.x,y:t.y,z:t.z,width:t.width,height:t.height,depth:t.depth+e.depth}:null}function Jt(t,e={}){let i=e.populationSize??30,n=e.generations??50,s=e.crossoverRate??.8,o=e.mutationRate??.2,r=e.elitismCount??2,a=e.timeBudgetMs??5e3,u=Date.now(),h=[],d=[];for(let g of t.packed){d.push(g.bin);for(let x of g.items)h.push(x.item);}if(h.push(...t.unpacked),h.length===0||d.length===0)return t;let c=d[0],l=te(h,i);J(l,h,c,e.packOptions);for(let g=0;g<n&&!(Date.now()-u>a);g++){let x=[];l.sort((w,z)=>z.fitness-w.fitness);for(let w=0;w<r&&w<l.length;w++)x.push({...l[w]});for(;x.length<i;){let w=Q(l),z=Q(l),b;Math.random()<s?b=ee(w,z):b={ordering:[...w.ordering],fitness:0},Math.random()<o&&ie(b),x.push(b);}J(x,h,c,e.packOptions),l=x;}l.sort((g,x)=>x.fitness-g.fitness);let p=l[0],f=t.packed[0]?.utilization??0,m=p.fitness;if(m>f&&p.result){let g=c.width*c.height*c.depth,x=p.result.packed.reduce((M,k)=>M+k.dimensions.width*k.dimensions.height*k.dimensions.depth,0),w=p.result.packed.reduce((M,k)=>M+(k.item.weight||0),0),z=Qt(p.result.packed);return {packed:[{bin:c,items:p.result.packed,utilization:m,weight:w,centerOfGravity:z}],unpacked:p.result.unpacked,stats:{totalBins:1,totalItems:h.length,packedItems:p.result.packed.length,unpackedItems:p.result.unpacked.length,avgUtilization:m,totalVolume:g,usedVolume:x,totalWeight:w,actualWeight:w}}}return t}function Qt(t){if(t.length===0)return {x:0,y:0,z:0};let e=0,i=0,n=0,s=0;for(let o of t){let r=o.item.weight||1,a=o.position.x+o.dimensions.width/2,u=o.position.y+o.dimensions.height/2,h=o.position.z+o.dimensions.depth/2;i+=a*r,n+=u*r,s+=h*r,e+=r;}return {x:i/e,y:n/e,z:s/e}}function te(t,e){let i=[];i.push({ordering:t.map(o=>o.id),fitness:0});let n=[...t].sort((o,r)=>{let a=o.width*o.height*o.depth;return r.width*r.height*r.depth-a});i.push({ordering:n.map(o=>o.id),fitness:0});let s=[...t].sort((o,r)=>{let a=o.width*o.depth;return r.width*r.depth-a});for(i.push({ordering:s.map(o=>o.id),fitness:0});i.length<e;){let o=ne(t.map(r=>r.id));i.push({ordering:o,fitness:0});}return i}function J(t,e,i,n){let s=new Map(e.map(o=>[o.id,o]));for(let o of t)if(o.fitness===0){let r=o.ordering.map(p=>s.get(p)).filter(p=>p!==void 0),a=G(i,r,n),u=i.width*i.height*i.depth,h=a.packed.reduce((p,f)=>p+f.dimensions.width*f.dimensions.height*f.dimensions.depth,0),d=u>0?h/u:0,c=a.unpacked.length*.05,l=(isNaN(d)?0:d)-c;o.fitness=Math.max(0,l),o.result=a;}}function Q(t,e=3){let i=null;for(let n=0;n<e;n++){let s=Math.floor(Math.random()*t.length),o=t[s];(!i||o.fitness>i.fitness)&&(i=o);}return i}function ee(t,e){let i=t.ordering.length;if(i<3)return {ordering:[...t.ordering],fitness:0};let n=Math.floor(Math.random()*i),s=n+Math.floor(Math.random()*(i-n)),o=new Array(i).fill(null),r=new Set;for(let u=n;u<=s;u++)o[u]=t.ordering[u],r.add(t.ordering[u]);let a=(s+1)%i;for(let u of e.ordering)if(!r.has(u)){for(;o[a]!==null;)a=(a+1)%i;o[a]=u,a=(a+1)%i;}return {ordering:o,fitness:0}}function ie(t){let e=t.ordering.length;if(!(e<2)){if(Math.random()<.5){let i=Math.floor(Math.random()*e),n=Math.floor(Math.random()*e);for(;n===i;)n=Math.floor(Math.random()*e);let s=t.ordering[i];t.ordering[i]=t.ordering[n],t.ordering[n]=s;}else {let i=Math.floor(Math.random()*e),n=Math.floor(Math.random()*e),[s]=t.ordering.splice(i,1);t.ordering.splice(n,0,s);}t.fitness=0,t.result=void 0;}}function ne(t){let e=[...t];for(let i=e.length-1;i>0;i--){let n=Math.floor(Math.random()*(i+1));[e[i],e[n]]=[e[n],e[i]];}return e}function Z(t){return {ordering:[...t],fitness:0,result:void 0}}function C(t){return {ordering:[...t.ordering],fitness:t.fitness,result:t.result?{...t.result}:void 0}}function F(t,e,i,n){let s=new Map(e.map(c=>[c.id,c])),o=t.ordering.map(c=>s.get(c)).filter(c=>c!==void 0),r=G(i,o,n),a=i.width*i.height*i.depth,u=r.packed.reduce((c,l)=>c+l.dimensions.width*l.dimensions.height*l.dimensions.depth,0),h=a>0?u/a:0,d=r.unpacked.length*.05;t.fitness=Math.max(0,h-d),t.result=r;}function se(t,e){let i=[...t],{type:n,i:s,j:o}=e;switch(n){case "swap":[i[s],i[o]]=[i[o],i[s]];break;case "insert":let[r]=i.splice(s,1);i.splice(o,0,r);break;case "reverse":let a=Math.min(s,o),u=Math.max(s,o),h=i.slice(a,u+1).reverse();i.splice(a,u-a+1,...h);break;case "2-opt":let d=Math.min(s,o),c=Math.max(s,o);for(;d<c;)[i[d],i[c]]=[i[c],i[d]],d++,c--;break}return i}function ht(t,e=["swap","insert"]){let i=t.length;if(i<2)return {ordering:[...t],move:{type:"swap",i:0,j:0}};let n=e[Math.floor(Math.random()*e.length)],s=Math.floor(Math.random()*i),o=Math.floor(Math.random()*i);for(;o===s;)o=Math.floor(Math.random()*i);let r={type:n,i:s,j:o};return {ordering:se(t,r),move:r}}function oe(t,e,i=["swap","insert"]){let n=[],s=new Set;for(;n.length<e;){let o=ht(t,i),r=o.ordering.join(",");if(s.has(r)||(s.add(r),n.push(o)),s.size>e*3)break}return n}function re(t){if(t.length===0)return {x:0,y:0,z:0};let e=0,i=0,n=0,s=0;for(let o of t){let r=o.item.weight||1,a=o.position.x+o.dimensions.width/2,u=o.position.y+o.dimensions.height/2,h=o.position.z+o.dimensions.depth/2;i+=a*r,n+=u*r,s+=h*r,e+=r;}return {x:i/e,y:n/e,z:s/e}}function ut(t,e,i){if(!t.result)return {packed:[],unpacked:i,stats:{totalBins:1,totalItems:i.length,packedItems:0,unpackedItems:i.length,avgUtilization:0,totalVolume:e.width*e.height*e.depth,usedVolume:0,totalWeight:0,actualWeight:0}};let n=e.width*e.height*e.depth,s=t.result.packed.reduce((u,h)=>u+h.dimensions.width*h.dimensions.height*h.dimensions.depth,0),o=t.result.packed.reduce((u,h)=>u+(h.item.weight||0),0),r=re(t.result.packed);return {packed:[{bin:e,items:t.result.packed,utilization:t.fitness,weight:o,centerOfGravity:r}],unpacked:t.result.unpacked,stats:{totalBins:1,totalItems:i.length,packedItems:t.result.packed.length,unpackedItems:t.result.unpacked.length,avgUtilization:t.fitness,totalVolume:n,usedVolume:s,totalWeight:o,actualWeight:o}}}function ct(t){let e=[];e.push(t.map(r=>r.id));let i=[...t].sort((r,a)=>{let u=r.width*r.height*r.depth;return a.width*a.height*a.depth-u});e.push(i.map(r=>r.id));let n=[...t].sort((r,a)=>{let u=r.width*r.depth;return a.width*a.depth-u});e.push(n.map(r=>r.id));let s=[...t].sort((r,a)=>a.height-r.height);e.push(s.map(r=>r.id));let o=[...t].sort((r,a)=>(a.weight||0)-(r.weight||0));return e.push(o.map(r=>r.id)),e}function ae(t,e,i){if(e>t)return 1;let n=e-t;return Math.exp(n/i)}function he(t,e,i,n,s){let{initialTemperature:o,finalTemperature:r,coolingRate:a,iterationsPerTemp:u,timeBudgetMs:h,maxIterations:d,packOptions:c,onProgress:l}=n,p=o,f=C(t),m=C(f),g=0;for(F(f,e,i,c),m.fitness=f.fitness,m.result=f.result;p>r&&!(g>=d||Date.now()-s>h);){for(let x=0;x<u;x++){g++;let{ordering:w}=ht(f.ordering,["swap","insert"]),z=Z(w);F(z,e,i,c);let b=ae(f.fitness,z.fitness,p);Math.random()<b&&(f=z,f.fitness>m.fitness&&(m=C(f))),l&&g%50===0&&l({iteration:g,bestFitness:m.fitness,currentFitness:f.fitness,elapsedMs:Date.now()-s,info:{temperature:p}});}p*=a;}return {best:m,iterations:g}}function ue(t,e={}){let i={initialTemperature:Math.max(.001,e.initialTemperature??1),finalTemperature:Math.max(1e-4,e.finalTemperature??.001),coolingRate:Math.max(.5,Math.min(.9999,e.coolingRate??.995)),iterationsPerTemp:Math.max(1,e.iterationsPerTemp??10),restarts:Math.max(1,e.restarts??1),maxIterations:Math.max(1,e.maxIterations??5e3),timeBudgetMs:Math.max(100,e.timeBudgetMs??5e3),packOptions:e.packOptions,onProgress:e.onProgress},n=Date.now(),s=[],o=[];for(let c of t.packed){o.push(c.bin);for(let l of c.items)s.push(l.item);}if(s.push(...t.unpacked),s.length===0||o.length===0)return t;let r=o[0],a=t.packed[0]?.utilization??0,u=ct(s),h=null;for(let c=0;c<i.restarts&&!(Date.now()-n>i.timeBudgetMs);c++){let l=u[c%u.length],p=Z(l),{best:f}=he(p,s,r,i,n);(!h||f.fitness>h.fitness)&&(h=f);}return h&&h.fitness>a?ut(h,r,s):t}function dt(t){let[e,i]=[Math.min(t.i,t.j),Math.max(t.i,t.j)];return `${t.type}:${e}:${i}`}function ce(t,e,i){let n=dt(e),s=t.get(n);return s!==void 0&&s>i}function de(t,e,i,n){let s=dt(e);t.set(s,i+n);}function le(t,e){for(let[i,n]of t)n<=e&&t.delete(i);}function pe(t,e,i,n,s){let{tabuListSize:o,neighborhoodSize:r,useAspiration:a,diversificationFreq:u,maxIterations:h,timeBudgetMs:d,packOptions:c,onProgress:l}=n,p=C(t),f=C(p),m=new Map;F(p,e,i,c),f.fitness=p.fitness,f.result=p.result;let g=0,x=0;for(;g<h&&!(Date.now()-s>d);){g++,x++;let w=oe(p.ordering,r,["swap","insert"]),z=null,b=null,M=-1/0;for(let{ordering:k,move:q}of w){let W=Z(k);F(W,e,i,c);let xt=ce(m,q,g),wt=a&&W.fitness>f.fitness;(!xt||wt)&&W.fitness>M&&(z=W,b=q,M=W.fitness);}if(z&&b&&(p=z,de(m,b,g,o),p.fitness>f.fitness&&(f=C(p),x=0)),u>0&&x>=u){let k=[...p.ordering].sort(()=>Math.random()-.5);p=Z(k),F(p,e,i,c),x=0,m.clear();}g%20===0&&le(m,g),l&&g%20===0&&l({iteration:g,bestFitness:f.fitness,currentFitness:p.fitness,elapsedMs:Date.now()-s,info:{tabuListSize:m.size}});}return {best:f,iterations:g}}function fe(t,e={}){let i={tabuListSize:e.tabuListSize??20,neighborhoodSize:e.neighborhoodSize??30,useAspiration:e.useAspiration??true,diversificationFreq:e.diversificationFreq??50,restarts:e.restarts??1,maxIterations:e.maxIterations??1e3,timeBudgetMs:e.timeBudgetMs??5e3,packOptions:e.packOptions,onProgress:e.onProgress},n=Date.now(),s=[],o=[];for(let c of t.packed){o.push(c.bin);for(let l of c.items)s.push(l.item);}if(s.push(...t.unpacked),s.length===0||o.length===0)return t;let r=o[0],a=t.packed[0]?.utilization??0,u=ct(s),h=null;for(let c=0;c<i.restarts&&!(Date.now()-n>i.timeBudgetMs);c++){let l=u[c%u.length],p=Z(l),{best:f}=pe(p,s,r,i,n);(!h||f.fitness>h.fitness)&&(h=f);}return h&&h.fitness>a?ut(h,r,s):t}function pi(t,e){if(!e.incompatibleWith||e.incompatibleWith.length===0)return true;for(let i of t){let n=i.item.groupId;if(n&&e.incompatibleWith.includes(n))return false}return true}function fi(t){let e=new Map;for(let i of t){let n=i.groupId||"__ungrouped__";e.has(n)||e.set(n,[]),e.get(n).push(i);}return e}function me(t){return [...t].sort((e,i)=>{let n=e.deliveryOrder??0;return (i.deliveryOrder??0)-n})}function ge(t,e=false){return [...t].sort((i,n)=>{let s=i.width*i.height*i.depth,o=n.width*n.height*n.depth;return e?s-o:o-s})}function xe(t,e=false){return [...t].sort((i,n)=>{let s=i.weight??0,o=n.weight??0;return e?s-o:o-s})}var we={algorithm:"extreme-point",preprocessor:"none",enhancer:"none",features:{supportCheck:true,weightBalance:false,stackingLimit:true},constraints:{respectDeliveryOrder:false,keepGroupsTogether:false,enforceIncompatibility:true},optimize:{target:"space"},binSelection:"first-fit",spatialIndex:"naive"};function A(t){let e={...we,...t.options},{bins:i,items:n}=t;if(i.length===0)return ve(n);let s=[...n];e.constraints?.respectDeliveryOrder?s=me(s):s=ge(s),e.features?.weightBalance&&(s=xe(s));let o=[],r=[...s];for(let u of i){if(r.length===0)break;let{packed:h,unpacked:d}=ze(u,r,e);h.length>0&&o.push(be(u,h)),r=d;}let a=Be(o,r,n.length);return e.enhancer&&e.enhancer!=="none"?ye(a,e):a}function ye(t,e){let i={timeBudgetMs:e.timeBudgetMs??5e3,packOptions:e};switch(e.enhancer){case "genetic":return Jt(t,i);case "simulated-annealing":return ue(t,i);case "tabu-search":return fe(t,i);default:return t}}function ze(t,e,i){switch(i.algorithm){case "layer-building":return $t(t,e,i);case "wall-building":return Ft(t,e,i);case "eb-afit":return Yt(t,e,i);default:return G(t,e,i)}}function be(t,e){let i=t.width*t.height*t.depth,n=e.reduce((r,a)=>r+P(a.dimensions),0),s=zt(e),o=ot(e,t);return {bin:t,items:e,utilization:i>0?n/i:0,weight:s,centerOfGravity:o}}function ve(t){return {packed:[],unpacked:t,stats:lt([],t.length)}}function Be(t,e,i){return {packed:t,unpacked:e,stats:lt(t,i)}}function lt(t,e){let i=t.reduce((u,h)=>u+h.items.length,0),n=t.reduce((u,h)=>u+h.bin.width*h.bin.height*h.bin.depth,0),s=t.reduce((u,h)=>u+h.items.reduce((d,c)=>d+P(c.dimensions),0),0),o=t.reduce((u,h)=>u+h.weight,0),r=t.reduce((u,h)=>u+(h.bin.cost||0),0),a=t.length>0?t.reduce((u,h)=>u+h.utilization,0)/t.length:0;return {totalBins:t.length,totalItems:e,packedItems:i,unpackedItems:e-i,avgUtilization:a,totalVolume:n,usedVolume:s,totalWeight:o,totalCost:r>0?r:void 0,actualWeight:o}}var ke=class{bins=[];items=[];options={};addBin(t){return this.bins.push(t),this}addBins(t){return this.bins.push(...t),this}addItem(t){return this.items.push(t),this}addItems(t){return this.items.push(...t),this}setOptions(t){return this.options={...this.options,...t},this}pack(t){let e={...this.options,...t};return A({bins:this.bins,items:this.items,options:e})}reset(){return this.bins=[],this.items=[],this.options={},this}getBins(){return [...this.bins]}getItems(){return [...this.items]}getOptions(){return {...this.options}}};function mi(){return new ke}function gi(t,e={}){let i=e.minBlockSize??2,n=e.maxBlockSize??27,s=e.tolerancePct??0,o=[],r=[],a=Se(t,s);for(let[,u]of a)if(u.length>=i){let h=Ie(u,n,e);o.push(...h.blocks),r.push(...h.remaining);}else r.push(...u);return {blocks:o,remaining:r}}function Se(t,e){let i=new Map;for(let n of t){let o=[n.width,n.height,n.depth].sort((r,a)=>r-a).map(r=>Math.round(r/(1+e))).join("x");i.has(o)||i.set(o,[]),i.get(o).push(n);}return i}function Ie(t,e,i){let n=[],s=[...t],o=t[0],r={width:o.width,height:o.height,depth:o.depth},a=Ae(e);if(a.sort((u,h)=>{let d=u.countX*u.countY*u.countZ;return h.countX*h.countY*h.countZ-d}),i.optimizeForContainer){let u=i.optimizeForContainer;a.sort((h,d)=>{let c={width:h.countX*r.width,height:h.countY*r.height,depth:h.countZ*r.depth},l={width:d.countX*r.width,height:d.countY*r.height,depth:d.countZ*r.depth},p=tt(c,u);return tt(l,u)-p});}for(let u of a){let h=u.countX*u.countY*u.countZ;for(;s.length>=h;){let d=s.splice(0,h),c=Me(d,u,r);n.push(c);}if(s.length===0)break}return {blocks:n,remaining:s}}function Ae(t){let e=[];for(let i=1;i<=t;i++)for(let n=1;n<=t/i;n++)for(let s=1;s<=t/(i*n);s++){let o=i*n*s;o>=2&&o<=t&&e.push({countX:i,countY:n,countZ:s,itemWidth:0,itemHeight:0,itemDepth:0});}return e}function tt(t,e){if(t.width<=0||t.depth<=0||t.width>e.width||t.height>e.height||t.depth>e.depth)return 0;let i=e.width/t.width,n=e.depth/t.depth,s=e.width%t.width,o=e.depth%t.depth,r=(s+o)/(e.width+e.depth);return Math.floor(i)*Math.floor(n)*(1-r)}function Me(t,e,i){let n=t.reduce((s,o)=>s+(o.weight||0),0);return {id:`block_${t[0].id}_${t.length}`,originalItems:t,width:e.countX*i.width,height:e.countY*i.height,depth:e.countZ*i.depth,weight:n,count:t.length,arrangement:{...e,itemWidth:i.width,itemHeight:i.height,itemDepth:i.depth}}}function xi(t){let e=[];for(let i of t)e.push(...i.originalItems);return e}var $e={maxItemsPerNode:8,maxDepth:8,minNodeSize:1},et=class S{bounds;items=[];children=null;depth;constructor(e,i){this.bounds=e,this.depth=i;}isLeaf(){return this.children===null}getCenter(){return {x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2,z:(this.bounds.minZ+this.bounds.maxZ)/2}}subdivide(){let e=this.getCenter(),{minX:i,minY:n,minZ:s,maxX:o,maxY:r,maxZ:a}=this.bounds;this.children=[new S({minX:i,minY:n,minZ:s,maxX:e.x,maxY:e.y,maxZ:e.z},this.depth+1),new S({minX:e.x,minY:n,minZ:s,maxX:o,maxY:e.y,maxZ:e.z},this.depth+1),new S({minX:i,minY:e.y,minZ:s,maxX:e.x,maxY:r,maxZ:e.z},this.depth+1),new S({minX:e.x,minY:e.y,minZ:s,maxX:o,maxY:r,maxZ:e.z},this.depth+1),new S({minX:i,minY:n,minZ:e.z,maxX:e.x,maxY:e.y,maxZ:a},this.depth+1),new S({minX:e.x,minY:n,minZ:e.z,maxX:o,maxY:e.y,maxZ:a},this.depth+1),new S({minX:i,minY:e.y,minZ:e.z,maxX:e.x,maxY:r,maxZ:a},this.depth+1),new S({minX:e.x,minY:e.y,minZ:e.z,maxX:o,maxY:r,maxZ:a},this.depth+1)];}},Ce=class{root;config;itemCount=0;itemMap=new Map;constructor(t,e={}){this.config={...$e,...e},this.root=new et(t,0);}insert(t){let e=v(t);if(!B(e,this.root.bounds)){this.root.items.push(t),this.itemMap.set(t.item.id,t),this.itemCount++;return}this.insertIntoNode(this.root,t,e),this.itemMap.set(t.item.id,t),this.itemCount++;}insertIntoNode(t,e,i){if(t.isLeaf()){t.items.push(e),this.shouldSubdivide(t)&&this.subdivideNode(t);return}let n=false;for(let s of t.children)B(i,s.bounds)&&(this.insertIntoNode(s,e,i),n=true);n||t.items.push(e);}shouldSubdivide(t){if(t.items.length<=this.config.maxItemsPerNode||t.depth>=this.config.maxDepth)return false;let e=t.bounds.maxX-t.bounds.minX,i=t.bounds.maxY-t.bounds.minY,n=t.bounds.maxZ-t.bounds.minZ;return !(e/2<this.config.minNodeSize||i/2<this.config.minNodeSize||n/2<this.config.minNodeSize)}subdivideNode(t){t.subdivide();let e=t.items;t.items=[];for(let i of e){let n=v(i),s=false;for(let o of t.children)B(n,o.bounds)&&(o.items.push(i),s=true);s||t.items.push(i);}}remove(t){this.itemMap.has(t.item.id)&&(this.removeFromNode(this.root,t),this.itemMap.delete(t.item.id),this.itemCount--);}removeFromNode(t,e){let i=t.items.findIndex(n=>n.item.id===e.item.id);if(i!==-1)return t.items.splice(i,1),true;if(!t.isLeaf()){let n=v(e);for(let s of t.children)if(B(n,s.bounds)&&this.removeFromNode(s,e))return true}return false}query(t){let e=[],i=new Set;return this.queryNode(this.root,t,e,i),e}queryNode(t,e,i,n){for(let s of t.items)if(!n.has(s.item.id)){let o=v(s);B(o,e)&&(i.push(s),n.add(s.item.id));}if(!t.isLeaf())for(let s of t.children)B(s.bounds,e)&&this.queryNode(s,e,i,n);}clear(){this.root=new et(this.root.bounds,0),this.itemMap.clear(),this.itemCount=0;}getAll(){return Array.from(this.itemMap.values())}get size(){return this.itemCount}getStats(){let t={totalNodes:0,leafNodes:0,maxDepth:0,itemCount:this.itemCount,avgItemsPerLeaf:0},e=0;return this.collectStats(this.root,t,i=>{e+=i;}),t.avgItemsPerLeaf=t.leafNodes>0?e/t.leafNodes:0,t}collectStats(t,e,i){if(e.totalNodes++,e.maxDepth=Math.max(e.maxDepth,t.depth),t.isLeaf())e.leafNodes++,i(t.items.length);else for(let n of t.children)this.collectStats(n,e,i);}};function wi(t,e){return new Ce(t,e)}var De=1e3,U=De;function yi(t){U=t;}function zi(){return U}function bi(t){return Math.round(t*U)}function vi(t){return t/U}function Te(t,e,i,n,s={}){let o=[],r=[],a=We(e,i,n);a&&o.push(a);let u=Ee(t,e);o.push(...u);let h=Pe(e);o.push(...h);let d=Re(e);if(d&&o.push(d),s.checkSupport){let f=it(e);o.push(...f);}else {let f=it(e);for(let m of f)r.push({type:"gap",message:m.message});}let c=t.width*t.height*t.depth,l=e.reduce((f,m)=>f+m.dimensions.width*m.dimensions.height*m.dimensions.depth,0),p=c>0?l/c:0;return p<.5&&e.length>0&&r.push({type:"utilization",message:`Low utilization: ${(p*100).toFixed(1)}%`}),{valid:o.length===0,errors:o,warnings:r}}function We(t,e,i){let n=new Set(t.map(a=>a.item.id)),s=new Set(e.map(a=>a.id)),o=new Set(i.map(a=>a.id));if(n.size!==t.length)return {type:"count",message:"Duplicate items found in packed result"};let r=n.size+s.size;if(r!==o.size)return {type:"count",message:`Item count mismatch: ${r} in result vs ${o.size} original`};for(let a of o)if(!n.has(a)&&!s.has(a))return {type:"count",message:`Missing item: ${a}`,items:[a]};return null}function Ee(t,e){let i=[];for(let n of e){let{position:s,dimensions:o}=n;(s.x<0||s.y<0||s.z<0)&&i.push({type:"boundary",message:`Item ${n.item.id} has negative position: (${s.x}, ${s.y}, ${s.z})`,items:[n.item.id]}),s.x+o.width>t.width+.001&&i.push({type:"boundary",message:`Item ${n.item.id} exceeds bin width: ${s.x+o.width} > ${t.width}`,items:[n.item.id]}),s.y+o.height>t.height+.001&&i.push({type:"boundary",message:`Item ${n.item.id} exceeds bin height: ${s.y+o.height} > ${t.height}`,items:[n.item.id]}),s.z+o.depth>t.depth+.001&&i.push({type:"boundary",message:`Item ${n.item.id} exceeds bin depth: ${s.z+o.depth} > ${t.depth}`,items:[n.item.id]});}return i}function Pe(t){let e=[];for(let n=0;n<t.length;n++)for(let s=n+1;s<t.length;s++){let o=t[n],r=t[s];Fe(o.position,o.dimensions,r.position,r.dimensions,.001)&&e.push({type:"collision",message:`Collision detected between ${o.item.id} and ${r.item.id}`,items:[o.item.id,r.item.id]});}return e}function Fe(t,e,i,n,s){let o=t.x+e.width<=i.x+s||i.x+n.width<=t.x+s,r=t.y+e.height<=i.y+s||i.y+n.height<=t.y+s,a=t.z+e.depth<=i.z+s||i.z+n.depth<=t.z+s;return !(o||r||a)}function Re(t){for(let e of t){let{item:i,dimensions:n}=e,s=i.width*i.height*i.depth,o=n.width*n.height*n.depth;if(Math.abs(s-o)>.01)return {type:"volume",message:`Volume mismatch for ${i.id}: original ${s} vs placed ${o}`,items:[i.id]}}return null}function it(t){let e=[];for(let n of t){if(n.position.y<.001)continue;let s=false;for(let o of t){if(o.item.id===n.item.id)continue;let r=o.position.y+o.dimensions.height;if(Math.abs(r-n.position.y)<.001){let a=n.position.x<o.position.x+o.dimensions.width&&n.position.x+n.dimensions.width>o.position.x,u=n.position.z<o.position.z+o.dimensions.depth&&n.position.z+n.dimensions.depth>o.position.z;if(a&&u){s=true;break}}}s||e.push({type:"support",message:`Item ${n.item.id} is floating at y=${n.position.y}`,items:[n.item.id]});}return e}function Bi(t,e,i,n,s={}){return Te(t,e,i,n,s).valid}function Ze(t,e){let i={...t,bins:t.bins.map(n=>({...n,steps:n.steps.map(s=>{let{placedItem:o,...r}=s;return e.includeCoordinates?r:{...r,position:{description:r.position.description,referenceItemId:r.position.referenceItemId,relationship:r.position.relationship}}})}))};return JSON.stringify(i,null,2)}var Oe={en:{title:"Packing Instructions",generatedAt:"Generated at",summary:"Summary",binInfo:"Bin Information",binId:"Bin ID",binType:"Type",dimensions:"Dimensions",itemCount:"Item Count",totalWeight:"Total Weight",layerCount:"Layer Count",utilization:"Utilization",packingSteps:"Packing Steps",layer:"Layer",step:"Step",item:"Item",position:"Position",orientation:"Orientation",size:"Size",notes:"Notes",warnings:"Warnings",unpackedWarning:"items could not be packed",noItems:"No items to pack",actions:{place:"Place",stack:"Stack",rotate:"Place (rotated)"}},"zh-TW":{title:"\u88DD\u7BB1\u6307\u793A",generatedAt:"\u7522\u751F\u6642\u9593",summary:"\u6458\u8981",binInfo:"\u5BB9\u5668\u8CC7\u8A0A",binId:"\u5BB9\u5668 ID",binType:"\u985E\u578B",dimensions:"\u5C3A\u5BF8",itemCount:"\u7269\u54C1\u6578\u91CF",totalWeight:"\u7E3D\u91CD\u91CF",layerCount:"\u5C64\u6578",utilization:"\u7A7A\u9593\u4F7F\u7528\u7387",packingSteps:"\u88DD\u7BB1\u6B65\u9A5F",layer:"\u7B2C",step:"\u6B65\u9A5F",item:"\u7269\u54C1",position:"\u4F4D\u7F6E",orientation:"\u65B9\u5411",size:"\u5C3A\u5BF8",notes:"\u6CE8\u610F\u4E8B\u9805",warnings:"\u8B66\u544A",unpackedWarning:"\u500B\u7269\u54C1\u7121\u6CD5\u88DD\u5165",noItems:"\u6C92\u6709\u7269\u54C1\u9700\u8981\u88DD\u7BB1",actions:{place:"\u653E\u7F6E",stack:"\u5806\u758A",rotate:"\u65CB\u8F49\u653E\u7F6E"}}};function Le(t,e,i){let n=[],s=e.actions[t.action],o=`${t.step}. **${s}**\u3010${t.itemName}\u3011\u2192 ${t.position.description}`;if(n.push(o),i.detailLevel==="detailed"){let r=[],{width:a,height:u,depth:h}=t.dimensions;if(r.push(`${e.size}: ${a} \xD7 ${u} \xD7 ${h}`),i.includeCoordinates){let{x:d,y:c,z:l}=t.position.coordinates;r.push(`(${d}, ${c}, ${l})`);}i.includeWeight&&t.placedItem.item.weight&&r.push(`${t.placedItem.item.weight} kg`),r.length>0&&n.push(` - ${r.join(" | ")}`),t.notes.length>0&&t.notes.forEach(d=>{n.push(` - \u26A0\uFE0F ${d}`);});}return n.join(`
8
+ `)}function Xe(t,e,i,n){let s=[],{summary:o,steps:r}=t;if(s.push(`## ${i.binInfo} #${e+1}: ${o.binId}`),s.push(""),s.push(`| ${i.binType} | ${i.dimensions} | ${i.itemCount} | ${i.totalWeight} | ${i.layerCount} | ${i.utilization} |`),s.push("|------|------|------|------|------|------|"),s.push(`| ${o.binType} | ${o.binDimensions} | ${o.itemCount} | ${o.totalWeight} kg | ${o.layerCount} | ${o.utilization}% |`),s.push(""),s.push(`### ${i.packingSteps}`),s.push(""),r.length===0)return s.push(`*${i.noItems}*`),s.push(""),s.join(`
9
+ `);let a=new Map;r.forEach(h=>{let d=a.get(h.layer)||[];d.push(h),a.set(h.layer,d);});let u=[...a.keys()].sort((h,d)=>h-d);for(let h of u){let d=a.get(h),c=n.language==="zh-TW"?`${i.layer} ${h} \u5C64`:`${i.layer} ${h}`;s.push(`#### ${c}`),s.push(""),d.forEach(l=>{s.push(Le(l,i,n));}),s.push("");}return t.notes.length>0&&(s.push(`### ${i.notes}`),s.push(""),t.notes.forEach(h=>{s.push(`- ${h}`);}),s.push("")),s.join(`
10
+ `)}function nt(t,e){let i=Oe[e.language],n=[];n.push(`# ${i.title}`),n.push("");let o=new Date(t.generatedAt).toLocaleString(e.language==="zh-TW"?"zh-TW":"en-US");return n.push(`> ${i.generatedAt}: ${o}`),n.push(""),t.globalNotes.length>0&&(n.push(`## \u26A0\uFE0F ${i.warnings}`),n.push(""),t.globalNotes.forEach(r=>{n.push(`- ${r}`);}),n.push("")),n.push(`## ${i.summary}`),n.push(""),n.push(e.language==="zh-TW"?`- \u7E3D\u5BB9\u5668\u6578: ${t.totalBins}`:`- Total Bins: ${t.totalBins}`),n.push(e.language==="zh-TW"?`- \u7E3D\u7269\u54C1\u6578: ${t.totalItems}`:`- Total Items: ${t.totalItems}`),n.push(""),n.push("---"),n.push(""),t.bins.forEach((r,a)=>{n.push(Xe(r,a,i,e)),a<t.bins.length-1&&(n.push("---"),n.push(""));}),n.join(`
11
+ `)}var Ne={en:{title:"Packing Instructions",generatedAt:"Generated at",summary:"Summary",binInfo:"Bin",binId:"ID",binType:"Type",dimensions:"Dimensions",itemCount:"Items",totalWeight:"Weight",layerCount:"Layers",utilization:"Utilization",packingSteps:"Packing Steps",layer:"Layer",step:"Step",item:"Item",position:"Position",size:"Size",notes:"Notes",warnings:"Warnings",printButton:"Print",actions:{place:"Place",stack:"Stack on",rotate:"Place (rotated)"}},"zh-TW":{title:"\u88DD\u7BB1\u6307\u793A",generatedAt:"\u7522\u751F\u6642\u9593",summary:"\u6458\u8981",binInfo:"\u5BB9\u5668",binId:"ID",binType:"\u985E\u578B",dimensions:"\u5C3A\u5BF8",itemCount:"\u7269\u54C1\u6578",totalWeight:"\u91CD\u91CF",layerCount:"\u5C64\u6578",utilization:"\u4F7F\u7528\u7387",packingSteps:"\u88DD\u7BB1\u6B65\u9A5F",layer:"\u7B2C",step:"\u6B65\u9A5F",item:"\u7269\u54C1",position:"\u4F4D\u7F6E",size:"\u5C3A\u5BF8",notes:"\u6CE8\u610F\u4E8B\u9805",warnings:"\u8B66\u544A",printButton:"\u5217\u5370",actions:{place:"\u653E\u7F6E",stack:"\u5806\u758A\u65BC",rotate:"\u65CB\u8F49\u653E\u7F6E"}}},Ye=`
12
+ * {
13
+ box-sizing: border-box;
14
+ margin: 0;
15
+ padding: 0;
16
+ }
17
+
18
+ body {
19
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
20
+ line-height: 1.6;
21
+ color: #1a1a1a;
22
+ background: #f5f5f5;
23
+ padding: 20px;
24
+ }
25
+
26
+ .container {
27
+ max-width: 800px;
28
+ margin: 0 auto;
29
+ background: white;
30
+ padding: 40px;
31
+ border-radius: 8px;
32
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
33
+ }
34
+
35
+ h1 {
36
+ font-size: 28px;
37
+ color: #111;
38
+ margin-bottom: 8px;
39
+ padding-bottom: 16px;
40
+ border-bottom: 3px solid #3b82f6;
41
+ }
42
+
43
+ h2 {
44
+ font-size: 20px;
45
+ color: #333;
46
+ margin: 24px 0 12px;
47
+ padding-bottom: 8px;
48
+ border-bottom: 1px solid #e5e7eb;
49
+ }
50
+
51
+ h3 {
52
+ font-size: 16px;
53
+ color: #4b5563;
54
+ margin: 16px 0 8px;
55
+ }
56
+
57
+ .meta {
58
+ color: #6b7280;
59
+ font-size: 14px;
60
+ margin-bottom: 24px;
61
+ }
62
+
63
+ .warning-box {
64
+ background: #fef3c7;
65
+ border: 1px solid #f59e0b;
66
+ border-left: 4px solid #f59e0b;
67
+ padding: 12px 16px;
68
+ margin: 16px 0;
69
+ border-radius: 4px;
70
+ }
71
+
72
+ .warning-box ul {
73
+ margin: 8px 0 0 20px;
74
+ }
75
+
76
+ .summary-grid {
77
+ display: grid;
78
+ grid-template-columns: repeat(2, 1fr);
79
+ gap: 12px;
80
+ margin: 16px 0;
81
+ }
82
+
83
+ .summary-item {
84
+ background: #f9fafb;
85
+ padding: 12px;
86
+ border-radius: 6px;
87
+ border: 1px solid #e5e7eb;
88
+ }
89
+
90
+ .summary-item .label {
91
+ font-size: 12px;
92
+ color: #6b7280;
93
+ text-transform: uppercase;
94
+ letter-spacing: 0.5px;
95
+ }
96
+
97
+ .summary-item .value {
98
+ font-size: 24px;
99
+ font-weight: 600;
100
+ color: #111;
101
+ }
102
+
103
+ .bin-card {
104
+ border: 1px solid #e5e7eb;
105
+ border-radius: 8px;
106
+ margin: 24px 0;
107
+ overflow: hidden;
108
+ }
109
+
110
+ .bin-header {
111
+ background: #3b82f6;
112
+ color: white;
113
+ padding: 12px 16px;
114
+ font-weight: 600;
115
+ }
116
+
117
+ .bin-info {
118
+ display: grid;
119
+ grid-template-columns: repeat(3, 1fr);
120
+ gap: 1px;
121
+ background: #e5e7eb;
122
+ }
123
+
124
+ .bin-info-item {
125
+ background: #f9fafb;
126
+ padding: 12px;
127
+ text-align: center;
128
+ }
129
+
130
+ .bin-info-item .label {
131
+ font-size: 11px;
132
+ color: #6b7280;
133
+ text-transform: uppercase;
134
+ }
135
+
136
+ .bin-info-item .value {
137
+ font-size: 16px;
138
+ font-weight: 600;
139
+ color: #111;
140
+ }
141
+
142
+ .layer-section {
143
+ padding: 16px;
144
+ border-top: 1px solid #e5e7eb;
145
+ }
146
+
147
+ .layer-title {
148
+ font-size: 14px;
149
+ font-weight: 600;
150
+ color: #3b82f6;
151
+ margin-bottom: 12px;
152
+ padding: 4px 8px;
153
+ background: #eff6ff;
154
+ border-radius: 4px;
155
+ display: inline-block;
156
+ }
157
+
158
+ .step {
159
+ display: flex;
160
+ gap: 12px;
161
+ padding: 12px;
162
+ margin: 8px 0;
163
+ background: #fafafa;
164
+ border-radius: 6px;
165
+ border-left: 3px solid #e5e7eb;
166
+ }
167
+
168
+ .step.action-place { border-left-color: #10b981; }
169
+ .step.action-stack { border-left-color: #f59e0b; }
170
+ .step.action-rotate { border-left-color: #8b5cf6; }
171
+
172
+ .step-number {
173
+ width: 28px;
174
+ height: 28px;
175
+ background: #3b82f6;
176
+ color: white;
177
+ border-radius: 50%;
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ font-size: 12px;
182
+ font-weight: 600;
183
+ flex-shrink: 0;
184
+ }
185
+
186
+ .step-content {
187
+ flex: 1;
188
+ }
189
+
190
+ .step-main {
191
+ font-weight: 500;
192
+ color: #111;
193
+ }
194
+
195
+ .step-action {
196
+ display: inline-block;
197
+ padding: 2px 6px;
198
+ border-radius: 3px;
199
+ font-size: 12px;
200
+ font-weight: 600;
201
+ margin-right: 4px;
202
+ }
203
+
204
+ .step-action.place { background: #d1fae5; color: #065f46; }
205
+ .step-action.stack { background: #fef3c7; color: #92400e; }
206
+ .step-action.rotate { background: #ede9fe; color: #5b21b6; }
207
+
208
+ .step-item-name {
209
+ font-weight: 600;
210
+ color: #1f2937;
211
+ }
212
+
213
+ .step-details {
214
+ font-size: 13px;
215
+ color: #6b7280;
216
+ margin-top: 4px;
217
+ }
218
+
219
+ .step-note {
220
+ font-size: 12px;
221
+ color: #b45309;
222
+ background: #fffbeb;
223
+ padding: 4px 8px;
224
+ border-radius: 4px;
225
+ margin-top: 6px;
226
+ display: inline-block;
227
+ }
228
+
229
+ .print-button {
230
+ position: fixed;
231
+ bottom: 20px;
232
+ right: 20px;
233
+ background: #3b82f6;
234
+ color: white;
235
+ border: none;
236
+ padding: 12px 24px;
237
+ border-radius: 8px;
238
+ font-size: 14px;
239
+ font-weight: 600;
240
+ cursor: pointer;
241
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
242
+ transition: all 0.2s;
243
+ }
244
+
245
+ .print-button:hover {
246
+ background: #2563eb;
247
+ transform: translateY(-1px);
248
+ }
249
+
250
+ @media print {
251
+ body {
252
+ background: white;
253
+ padding: 0;
254
+ }
255
+
256
+ .container {
257
+ box-shadow: none;
258
+ padding: 20px;
259
+ max-width: none;
260
+ }
261
+
262
+ .print-button {
263
+ display: none;
264
+ }
265
+
266
+ .bin-card {
267
+ break-inside: avoid;
268
+ }
269
+
270
+ .layer-section {
271
+ break-inside: avoid;
272
+ }
273
+ }
274
+ `;function R(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function Ve(t,e,i){let n=t.action,s=e.actions[t.action],{width:o,height:r,depth:a}=t.dimensions,u="";if(i.detailLevel==="detailed"){let d=[`${e.size}: ${o} \xD7 ${r} \xD7 ${a}`];if(i.includeWeight&&t.placedItem.item.weight&&d.push(`${t.placedItem.item.weight} kg`),i.includeCoordinates){let{x:c,y:l,z:p}=t.position.coordinates;d.push(`(${c}, ${l}, ${p})`);}u=`<div class="step-details">${d.join(" \xB7 ")}</div>`;}let h=t.notes.length>0?t.notes.map(d=>`<div class="step-note">\u26A0\uFE0F ${R(d)}</div>`).join(""):"";return `
275
+ <div class="step action-${n}">
276
+ <div class="step-number">${t.step}</div>
277
+ <div class="step-content">
278
+ <div class="step-main">
279
+ <span class="step-action ${n}">${s}</span>
280
+ <span class="step-item-name">\u3010${R(t.itemName)}\u3011</span>
281
+ \u2192 ${R(t.position.description)}
282
+ </div>
283
+ ${u}
284
+ ${h}
285
+ </div>
286
+ </div>
287
+ `}function He(t,e,i,n){let{summary:s,steps:o}=t,r=new Map;o.forEach(h=>{let d=r.get(h.layer)||[];d.push(h),r.set(h.layer,d);});let u=[...r.keys()].sort((h,d)=>h-d).map(h=>{let d=r.get(h),c=n.language==="zh-TW"?`${i.layer} ${h} \u5C64`:`${i.layer} ${h}`,l=d.map(p=>Ve(p,i,n)).join("");return `
288
+ <div class="layer-section">
289
+ <div class="layer-title">${c}</div>
290
+ ${l}
291
+ </div>
292
+ `}).join("");return `
293
+ <div class="bin-card">
294
+ <div class="bin-header">${i.binInfo} #${e+1}: ${R(s.binId)}</div>
295
+ <div class="bin-info">
296
+ <div class="bin-info-item">
297
+ <div class="label">${i.dimensions}</div>
298
+ <div class="value">${s.binDimensions}</div>
299
+ </div>
300
+ <div class="bin-info-item">
301
+ <div class="label">${i.itemCount}</div>
302
+ <div class="value">${s.itemCount}</div>
303
+ </div>
304
+ <div class="bin-info-item">
305
+ <div class="label">${i.totalWeight}</div>
306
+ <div class="value">${s.totalWeight} kg</div>
307
+ </div>
308
+ <div class="bin-info-item">
309
+ <div class="label">${i.layerCount}</div>
310
+ <div class="value">${s.layerCount}</div>
311
+ </div>
312
+ <div class="bin-info-item">
313
+ <div class="label">${i.utilization}</div>
314
+ <div class="value">${s.utilization}%</div>
315
+ </div>
316
+ <div class="bin-info-item">
317
+ <div class="label">${i.binType}</div>
318
+ <div class="value">${s.binType}</div>
319
+ </div>
320
+ </div>
321
+ ${u}
322
+ </div>
323
+ `}function Ue(t,e){let i=Ne[e.language],s=new Date(t.generatedAt).toLocaleString(e.language==="zh-TW"?"zh-TW":"en-US"),o=t.globalNotes.length>0?`
324
+ <div class="warning-box">
325
+ <strong>\u26A0\uFE0F ${i.warnings}</strong>
326
+ <ul>
327
+ ${t.globalNotes.map(u=>`<li>${R(u)}</li>`).join("")}
328
+ </ul>
329
+ </div>
330
+ `:"",r=`
331
+ <h2>${i.summary}</h2>
332
+ <div class="summary-grid">
333
+ <div class="summary-item">
334
+ <div class="label">${e.language==="zh-TW"?"\u7E3D\u5BB9\u5668\u6578":"Total Bins"}</div>
335
+ <div class="value">${t.totalBins}</div>
336
+ </div>
337
+ <div class="summary-item">
338
+ <div class="label">${e.language==="zh-TW"?"\u7E3D\u7269\u54C1\u6578":"Total Items"}</div>
339
+ <div class="value">${t.totalItems}</div>
340
+ </div>
341
+ </div>
342
+ `,a=t.bins.map((u,h)=>He(u,h,i,e)).join("");return `<!DOCTYPE html>
343
+ <html lang="${e.language}">
344
+ <head>
345
+ <meta charset="UTF-8">
346
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
347
+ <title>${i.title}</title>
348
+ <style>${Ye}</style>
349
+ </head>
350
+ <body>
351
+ <div class="container">
352
+ <h1>${i.title}</h1>
353
+ <div class="meta">${i.generatedAt}: ${s}</div>
354
+ ${o}
355
+ ${r}
356
+ ${a}
357
+ </div>
358
+ <button class="print-button" onclick="window.print()">\u{1F5A8}\uFE0F ${i.printButton}</button>
359
+ </body>
360
+ </html>`}var pt={en:{positions:{bottomLeft:"bottom-left corner",bottomRight:"bottom-right corner",topLeft:"top-left corner",topRight:"top-right corner",center:"center",above:"above",beside:"beside",behind:"behind",inFront:"in front of"},orientations:{upright:"upright",flat:"flat",sideways:"sideways",rotated90:"rotated 90\xB0",rotated180:"rotated 180\xB0",custom:"custom orientation"},notes:{heavyItem:"Heavy item - handle with care",fragile:"Fragile - this side up",stackable:"Stackable",floorOnly:"Must be placed on floor",groupWith:"Keep together with group",deliveryOrder:"Delivery priority"},layers:{bottom:"Bottom layer",middle:"Middle layer",top:"Top layer"}},"zh-TW":{positions:{bottomLeft:"\u5DE6\u4E0B\u89D2",bottomRight:"\u53F3\u4E0B\u89D2",topLeft:"\u5DE6\u4E0A\u89D2",topRight:"\u53F3\u4E0A\u89D2",center:"\u4E2D\u592E",above:"\u4E0A\u65B9",beside:"\u65C1\u908A",behind:"\u5F8C\u65B9",inFront:"\u524D\u65B9"},orientations:{upright:"\u76F4\u7ACB",flat:"\u5E73\u653E",sideways:"\u5074\u653E",rotated90:"\u65CB\u8F49 90\xB0",rotated180:"\u65CB\u8F49 180\xB0",custom:"\u81EA\u5B9A\u7FA9\u65B9\u5411"},notes:{heavyItem:"\u91CD\u7269 - \u5C0F\u5FC3\u642C\u904B",fragile:"\u6613\u788E - \u6B64\u9762\u671D\u4E0A",stackable:"\u53EF\u5806\u758A",floorOnly:"\u5FC5\u9808\u653E\u7F6E\u65BC\u5730\u9762",groupWith:"\u8207\u540C\u7D44\u7269\u54C1\u653E\u5728\u4E00\u8D77",deliveryOrder:"\u51FA\u8CA8\u512A\u5148\u9806\u5E8F"},layers:{bottom:"\u5E95\u5C64",middle:"\u4E2D\u5C64",top:"\u9802\u5C64"}}};function st(t,e){return Math.floor(t/e)+1}function je(t){let{rotation:e,item:i,dimensions:n}=t;return n.height===i.height?e===0?"upright":"rotated-90":n.height===i.width||n.height===i.depth?"flat":"custom"}function _e(t,e,i,n,s){let o=pt[s].positions,{position:r,dimensions:a}=t,u=r.x+a.width/2,h=r.z+a.depth/2,d=ft(t,n);if(d&&r.y>0)return {description:`${o.above} [${mt(d)}]`,coordinates:r,referenceItemId:d.item.id,relationship:"above"};let c=u<e/2,l=h<i/2,p;return c&&l?p=o.bottomLeft:!c&&l?p=o.bottomRight:c&&!l?p=o.topLeft:p=o.topRight,{description:p,coordinates:r}}function ft(t,e){for(let n of e){if(n===t)continue;let s=n.position.y+n.dimensions.height;if(Math.abs(s-t.position.y)>1)continue;let o=t.position.x<n.position.x+n.dimensions.width&&t.position.x+t.dimensions.width>n.position.x,r=t.position.z<n.position.z+n.dimensions.depth&&t.position.z+t.dimensions.depth>n.position.z;if(o&&r)return n}return null}function mt(t){let{item:e}=t;return e.metadata?.name&&typeof e.metadata.name=="string"?e.metadata.name:e.id}function Ge(t,e,i){let n=pt[e].notes,s=[],{item:o}=t;return i==="simple"||(o.weight&&o.weight>20&&s.push(n.heavyItem),o.requiresFloor&&s.push(n.floorOnly),o.groupId&&s.push(`${n.groupWith}: ${o.groupId}`),o.deliveryOrder&&s.push(`${n.deliveryOrder}: #${o.deliveryOrder}`)),s}function qe(t,e){return ft(t,e)?"stack":t.rotation!==0?"rotate":"place"}function Ke(t,e){let{bin:i,items:n,utilization:s,weight:o}=t,{language:r,detailLevel:a,layerHeightThreshold:u}=e,h=[...n].sort((f,m)=>f.position.y!==m.position.y?f.position.y-m.position.y:f.position.z!==m.position.z?f.position.z-m.position.z:f.position.x-m.position.x),d=h.reduce((f,m)=>{let g=st(m.position.y,u);return Math.max(f,g)},0),c={binId:i.id,binType:i.type,binDimensions:`${i.width} \xD7 ${i.height} \xD7 ${i.depth}`,itemCount:n.length,totalWeight:o,layerCount:d,utilization:Math.round(s*100)},l=h.map((f,m)=>{let g=st(f.position.y,u),x=je(f),w=_e(f,i.width,i.depth,n,r),z=Ge(f,r,a),b=qe(f,n);return {step:m+1,action:b,itemId:f.item.id,itemName:mt(f),position:w,dimensions:f.dimensions,orientation:x,layer:g,notes:z,placedItem:f}}),p=[];if(o>0&&i.maxWeight){let f=Math.round(o/i.maxWeight*100);p.push(r==="zh-TW"?`\u91CD\u91CF\u4F7F\u7528\u7387: ${f}%`:`Weight usage: ${f}%`);}return {summary:c,steps:l,notes:p}}function ki(t,e={}){let i={format:e.format??"markdown",language:e.language??"zh-TW",detailLevel:e.detailLevel??"detailed",includeCoordinates:e.includeCoordinates??false,includeWeight:e.includeWeight??true,layerHeightThreshold:e.layerHeightThreshold??100},n=t.packed.map(a=>Ke(a,i)),s=[];t.unpacked.length>0&&s.push(i.language==="zh-TW"?`\u8B66\u544A: ${t.unpacked.length} \u500B\u7269\u54C1\u7121\u6CD5\u88DD\u5165`:`Warning: ${t.unpacked.length} items could not be packed`);let o={generatedAt:new Date().toISOString(),totalBins:t.packed.length,totalItems:t.stats.packedItems,bins:n,globalNotes:s},r;switch(i.format){case "json":r=Ze(o,i);break;case "markdown":r=nt(o,i);break;case "html":r=Ue(o,i);break;default:r=nt(o,i);}return {instructions:o,formatted:r,format:i.format,language:i.language}}var Si=class{options;binStates=new Map;binOrder=[];stats;eventListeners=new Map;autoAddCounter=0;constructor(t={}){if(this.options={algorithm:t.algorithm??"online-extreme-point",binSelection:t.binSelection??"first-fit",autoAddBins:t.autoAddBins??false,binTemplate:t.binTemplate??{id:"auto-bin",type:"box",width:100,height:100,depth:100},maxBins:t.maxBins??100,features:t.features??{supportCheck:true},constraints:t.constraints??{}},this.stats={totalItems:0,placedItems:0,rejectedItems:0,binsInUse:0,avgUtilization:0,totalWeight:0},t.bins)for(let e of t.bins)this.addBin(e);}addBin(t){if(this.binStates.has(t.id))throw new Error(`Bin with id "${t.id}" already exists`);let e={bin:t,items:[],spatialIndex:O(),extremePoints:this.generateInitialExtremePoints(t),totalVolume:t.width*t.height*t.depth,usedVolume:0,weight:0};if(t.existingItems)for(let i of t.existingItems)e.items.push(i),e.spatialIndex.insert(i),e.usedVolume+=P(i.dimensions),e.weight+=i.item.weight??0,this.updateExtremePoints(e,i);this.binStates.set(t.id,e),this.binOrder.push(t.id),this.stats.binsInUse++,this.emit("bin-added",{bin:t});}removeBin(t){let e=this.binStates.get(t);if(!e)return null;let i={bin:e.bin,items:[...e.items],utilization:e.totalVolume>0?e.usedVolume/e.totalVolume:0,weight:e.weight,remainingVolume:e.totalVolume-e.usedVolume};return this.binStates.delete(t),this.binOrder=this.binOrder.filter(n=>n!==t),this.stats.binsInUse--,i}placeItem(t){if(this.stats.totalItems++,this.options.autoAddBins&&!this.canFitInTemplate(t)){this.stats.rejectedItems++;let n={success:false,reason:"no-fit"};return this.emit("item-rejected",{item:t,placement:n}),n}let e=this.options.maxBins+1;for(let n=0;n<e;n++){if(this.binStates.size===0)if(this.options.autoAddBins&&this.stats.binsInUse<this.options.maxBins)this.autoAddBin();else {this.stats.rejectedItems++;let o={success:false,reason:"no-bins"};return this.emit("item-rejected",{item:t,placement:o}),o}let s=this.findPlacement(t);if(s){let o=this.binStates.get(s.binId),r={item:t,position:s.position,rotation:s.rotation,dimensions:s.dimensions};o.items.push(r),o.spatialIndex.insert(r),o.usedVolume+=P(s.dimensions),o.weight+=t.weight??0,this.updateExtremePoints(o,r),this.stats.placedItems++,this.stats.totalWeight+=t.weight??0,this.updateAvgUtilization();let a={success:true,binId:s.binId,position:s.position,placedItem:r};return this.emit("item-placed",{item:t,bin:o.bin,placement:a}),a}if(this.options.autoAddBins&&this.stats.binsInUse<this.options.maxBins){this.autoAddBin();continue}break}this.stats.rejectedItems++;let i={success:false,reason:"no-fit"};return this.emit("item-rejected",{item:t,placement:i}),i}canFitInTemplate(t){let e=this.options.binTemplate,i=[t.width,t.height,t.depth].sort((s,o)=>s-o),n=[e.width,e.height,e.depth].sort((s,o)=>s-o);return i[0]<=n[0]&&i[1]<=n[1]&&i[2]<=n[2]}findPlacement(t){let e=[],i=this.getBinOrder();for(let s of i){let o=this.binStates.get(s),r=this.findPlacementInBin(t,o);if(r){if(this.options.binSelection==="first-fit")return {binId:s,...r};let a=P(r.dimensions),u=o.totalVolume-o.usedVolume-a;e.push({binId:s,...r,score:u});}}if(e.length===0)return null;this.options.binSelection==="best-fit"?e.sort((s,o)=>s.score-o.score):e.sort((s,o)=>o.score-s.score);let n=e[0];return {binId:n.binId,position:n.position,rotation:n.rotation,dimensions:n.dimensions}}findPlacementInBin(t,e){let i=t.allowedRotations||T(t.rotationType||"all"),n=[...e.extremePoints].sort((s,o)=>s.y!==o.y?s.y-o.y:s.z!==o.z?s.z-o.z:s.x-o.x);for(let s of n)for(let o of i){let r=I(t.width,t.height,t.depth,o);if(X(s,r,e.bin)&&!N(s,r,e.bin)&&!L(s,r,e.spatialIndex)&&Y(e.items,t,e.bin)){if(this.options.features?.supportCheck){let a=t.requiresSupport??.5;if(!V(s,r,e.items,a))continue}return {position:{...s},rotation:o,dimensions:r}}}return null}updateExtremePoints(t,e){let{position:i,dimensions:n}=e,s=[];s.push({x:i.x+n.width,y:i.y,z:i.z}),s.push({x:i.x,y:i.y+n.height,z:i.z}),s.push({x:i.x,y:i.y,z:i.z+n.depth}),t.extremePoints=t.extremePoints.filter(o=>!(o.x>=i.x&&o.x<i.x+n.width&&o.y>=i.y&&o.y<i.y+n.height&&o.z>=i.z&&o.z<i.z+n.depth));for(let o of s)o.x>=0&&o.x<t.bin.width&&o.y>=0&&o.y<t.bin.height&&o.z>=0&&o.z<t.bin.depth&&(t.extremePoints.some(a=>Math.abs(a.x-o.x)<.001&&Math.abs(a.y-o.y)<.001&&Math.abs(a.z-o.z)<.001)||t.extremePoints.push(o));}getBinOrder(){return this.options.binSelection==="first-fit"?this.binOrder:[...this.binOrder].sort((t,e)=>{let i=this.binStates.get(t),n=this.binStates.get(e),s=i.totalVolume>0?i.usedVolume/i.totalVolume:0,o=n.totalVolume>0?n.usedVolume/n.totalVolume:0;return this.options.binSelection==="best-fit"?o-s:s-o})}autoAddBin(){this.autoAddCounter++;let t={...this.options.binTemplate,id:`${this.options.binTemplate.id}-${this.autoAddCounter}`};this.addBin(t);}updateAvgUtilization(){if(this.binStates.size===0){this.stats.avgUtilization=0;return}let t=0;for(let e of this.binStates.values())t+=e.totalVolume>0?e.usedVolume/e.totalVolume:0;this.stats.avgUtilization=this.binStates.size>0?t/this.binStates.size:0;}getStats(){return {...this.stats}}getBinState(t){let e=this.binStates.get(t);return e?{bin:e.bin,items:[...e.items],utilization:e.totalVolume>0?e.usedVolume/e.totalVolume:0,weight:e.weight,remainingVolume:e.totalVolume-e.usedVolume}:null}getAllBinStates(){return this.binOrder.map(t=>this.getBinState(t))}getBinIds(){return [...this.binOrder]}reset(){this.binStates.clear(),this.binOrder=[],this.autoAddCounter=0,this.stats={totalItems:0,placedItems:0,rejectedItems:0,binsInUse:0,avgUtilization:0,totalWeight:0};}on(t,e){return this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e),()=>{this.eventListeners.get(t)?.delete(e);}}emit(t,e){let i={type:t,timestamp:Date.now(),...e},n=this.eventListeners.get(t);if(n)for(let s of n)s(i);}generateInitialExtremePoints(t){let e=[];if(e.push({x:0,y:0,z:0}),!t.excludeZones||t.excludeZones.length===0)return e;for(let n of t.excludeZones)n.minY>0||(n.minX===0&&n.maxX<t.width&&(e.push({x:n.maxX,y:0,z:0}),n.minZ===0&&n.maxZ<t.depth&&(e.push({x:0,y:0,z:n.maxZ}),e.push({x:n.maxX,y:0,z:n.maxZ}))),n.minZ===0&&n.maxZ<t.depth&&n.minX!==0&&e.push({x:0,y:0,z:n.maxZ}));let i=[];for(let n of e)i.some(o=>Math.abs(o.x-n.x)<.001&&Math.abs(o.y-n.y)<.001&&Math.abs(o.z-n.z)<.001)||i.push(n);return i}};var H={EUR1:{width:800,depth:1200,height:144,name:"EUR1 (Euro Pallet)"},EUR2:{width:1200,depth:1e3,height:144,name:"EUR2"},EUR3:{width:1e3,depth:1200,height:144,name:"EUR3"},EUR6:{width:600,depth:800,height:144,name:"EUR6 (Half Pallet)"},US:{width:1016,depth:1219,height:150,name:'US (40"\xD748")'},US_GROCERY:{width:1016,depth:1219,height:150,name:"US Grocery"},ASIA:{width:1100,depth:1100,height:150,name:"Asia Standard"},AUSTRALIA:{width:1165,depth:1165,height:150,name:"Australia Standard"}};function Je(t){return H[t]}var Qe=1800,ti=1e3;function ei(t,e={}){let i,n;if(typeof e.palletSize=="string"){let h=H[e.palletSize];i=h.width,n=h.depth;}else e.palletSize?(i=e.palletSize.width,n=e.palletSize.depth):(i=H.EUR1.width,n=H.EUR1.depth);let s=e.maxHeight??Qe,o=e.maxWeight??ti,r={id:"pallet-1",type:"pallet",width:i,height:s,depth:n,maxWeight:o},a={algorithm:e.algorithm??"layer-building",features:{supportCheck:true,weightBalance:true,stackingLimit:true},...e.packOptions};return {...A({bins:[r],items:t,options:a}),palletSpec:r}}var j={"20ft":{width:2352,height:2393,depth:5898,maxWeight:21770,name:"20ft Standard"},"40ft":{width:2352,height:2393,depth:12032,maxWeight:26680,name:"40ft Standard"},"40ftHC":{width:2352,height:2698,depth:12032,maxWeight:26460,name:"40ft High Cube"},"45ftHC":{width:2352,height:2698,depth:13556,maxWeight:25600,name:"45ft High Cube"}};function ii(t){return j[t]}function ni(t,e={}){let i,n,s,o;if(typeof e.containerSize=="string"){let h=j[e.containerSize];i=h.width,n=h.height,s=h.depth,o=e.maxWeight??h.maxWeight;}else if(e.containerSize)i=e.containerSize.width,n=e.containerSize.height,s=e.containerSize.depth,o=e.maxWeight??26e3;else {let h=j["40ft"];i=h.width,n=h.height,s=h.depth,o=e.maxWeight??h.maxWeight;}let r={id:"container-1",type:"container",width:i,height:n,depth:s,maxWeight:o,constraints:{loadingDirection:e.loadingDirection??"rear"}},a={algorithm:e.algorithm??"wall-building",features:{supportCheck:true,weightBalance:true,stackingLimit:true},constraints:{respectDeliveryOrder:e.respectDeliveryOrder??false},...e.packOptions};return {...A({bins:[r],items:t,options:a}),containerSpec:r}}function gt(t,e,i,n){let s=i??e*.6,o=n??e*.2,r=0,a=0;for(let u of t){let h=u.item.weight??0;if(h===0)continue;let c=u.position.z+u.dimensions.depth/2-o,l=Math.max(0,Math.min(1,c/s));a+=h*l,r+=h*(1-l);}return {front:r,rear:a,isValid:true}}function si(t,e){let{truckSize:i,maxWeight:n,axleWeights:s}=e,o={id:"truck-1",type:"truck",width:i.width,height:i.height,depth:i.depth,maxWeight:n,constraints:{axleWeights:s,loadingDirection:"rear"}},r={algorithm:e.algorithm??"wall-building",features:{supportCheck:true,weightBalance:true,stackingLimit:true},constraints:{respectDeliveryOrder:true},...e.packOptions},a=A({bins:[o],items:t,options:r}),u=a.packed.length>0?a.packed[0].items:[],h=gt(u,i.depth,e.wheelbase,e.frontAxleOffset);return s&&(h.isValid=h.front<=s.front&&h.rear<=s.rear),{...a,truckSpec:o,axleWeights:h}}export{j as CONTAINER_STANDARDS,yt as NaiveSpatialIndex,Ce as OctreeIndex,Si as OnlinePacker,H as PALLET_STANDARDS,ke as Packer,y as RotationType,gi as buildBlocks,gt as calcAxleWeights,ot as calcCenterOfGravity,_ as calcOverlapAreaXZ,rt as calcSupportedArea,zt as calcTotalWeight,Y as canAddWeight,pi as canMixInBin,ui as canStackOn,oi as containsAABB,D as createAABB,O as createNaiveIndex,wi as createOctreeIndex,mi as createPacker,Jt as enhanceWithGenetic,xi as expandBlocks,di as extractLayers,li as extractWalls,X as fitsInBin,Ue as formatAsHtml,Ze as formatAsJson,nt as formatAsMarkdown,ki as generateInstructions,T as getAllowedRotations,ii as getContainerStandard,v as getItemAABB,Je as getPalletStandard,I as getRotatedDimensions,ci as getRotationVariants,zi as getScale,fi as groupItems,L as hasCollision,V as hasSufficientSupport,B as intersectsAABB,ai as isDirectlyAbove,N as isInExcludeZone,Bi as isValidPacking,hi as isWeightBalanced,A as pack,ni as packContainer,ei as packPallet,si as packTruck,Yt as packWithEBAFIT,G as packWithExtremePoint,$t as packWithLayerBuilding,Ft as packWithWallBuilding,yi as setScale,me as sortByDeliveryOrder,ge as sortByVolume,xe as sortByWeight,vi as toExternal,bi as toInternal,Te as validatePackingResult,P as volume,ri as volumeAABB};
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@cratefit/pack",
3
+ "version": "0.1.0",
4
+ "description": "3D Bin Packing Library - Optimize container, pallet, and truck loading",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "LICENSE",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup && pnpm run build:types",
23
+ "build:types": "dts-bundle-generator -o dist/index.d.ts src/index.ts --no-check && cp dist/index.d.ts dist/index.d.cts",
24
+ "dev": "tsup --watch",
25
+ "clean": "rm -rf dist *.tsbuildinfo",
26
+ "typecheck": "tsc --noEmit",
27
+ "prepublishOnly": "pnpm run build"
28
+ },
29
+ "keywords": [
30
+ "bin-packing",
31
+ "3d-packing",
32
+ "3d-bin-packing",
33
+ "container-loading",
34
+ "pallet-packing",
35
+ "pallet-loading",
36
+ "truck-loading",
37
+ "box-packing",
38
+ "logistics",
39
+ "optimization",
40
+ "warehouse",
41
+ "shipping",
42
+ "cargo"
43
+ ],
44
+ "author": "supra126 (https://github.com/supra126)",
45
+ "license": "SEE LICENSE IN LICENSE",
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "registry": "https://registry.npmjs.org/"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ },
53
+ "dependencies": {
54
+ "@cratefit/core": "workspace:*",
55
+ "@cratefit/pallet": "workspace:*",
56
+ "@cratefit/container": "workspace:*",
57
+ "@cratefit/truck": "workspace:*"
58
+ }
59
+ }