markuno_lib 1.2.64 → 1.2.66

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/bin/markcad.js CHANGED
@@ -49,7 +49,7 @@ constructor(p1,p2,x2=null,y2=null){"number"==typeof p1&&"number"==typeof p2&&nul
49
49
  /**
50
50
  * Calcola la differenza delle coordinate x dei punti
51
51
  * @returns {number} Differenza x
52
- */get dx(){return this.p2.x-this.p1.x}
52
+ */get angle(){return new Punto2(this.dx,this.dy).angle}get dx(){return this.p2.x-this.p1.x}
53
53
  /**
54
54
  * Calcola la differenza delle coordinate y dei punti
55
55
  * @returns {number} Differenza y
@@ -137,7 +137,7 @@ constructor(p1,p2,x2=null,y2=null){"number"==typeof p1&&"number"==typeof p2&&nul
137
137
  * @param {Linea2} line2 - Seconda linea
138
138
  * @param {boolean} [checkpunticomune=false] - Se true verifica anche la sovrapposizione
139
139
  * @returns {boolean} True se collineari
140
- */isCollineare(line2,checkpunticomune=!1){if(!this.isparallela(line2))return!1;const distanza=this.distanzaSegmentiParalleli(line2);if(Math.abs(distanza)>.001)return!1;if(checkpunticomune){const isPointBetween=(p,a,b)=>Math.min(a.x,b.x)<=p.x&&p.x<=Math.max(a.x,b.x)&&Math.min(a.y,b.y)<=p.y&&p.y<=Math.max(a.y,b.y),{p1:p1,p2:p2}=this,{p1:p1_2,p2:p2_2}=line2;return isPointBetween(p1_2,p1,p2)||isPointBetween(p2_2,p1,p2)||isPointBetween(p1,p1_2,p2_2)||isPointBetween(p2,p1_2,p2_2)}return!0}clone(){return new Linea2(this.p1.x,this.p1.y,this.p2.x,this.p2.y)}rotate(deg){if(!deg)return this;const r=deg*Math.PI/180,cosTheta=Math.cos(r),sinTheta=Math.sin(r);function rotate(p){return new Punto2(p.x*cosTheta-p.y*sinTheta,p.x*sinTheta+p.y*cosTheta)}return this.p1=rotate(this.p1),this.p2=rotate(this.p2),this}move(x=0,y=0){return"object"==typeof x&&x.x&&(y=x.y||0,x=x.x),this.p1.x+=x,this.p1.y+=y,this.p2.x+=x,this.p2.y+=y,this}}
140
+ */isCollineare(line2,checkpunticomune=!1){if(!this.isparallela(line2))return!1;const distanza=this.distanzaSegmentiParalleli(line2);if(Math.abs(distanza)>.001)return!1;if(checkpunticomune){function isPointBetween(p,a,b,toll=.001){const cross=(b.x-a.x)*(p.y-a.y)-(b.y-a.y)*(p.x-a.x);return!(Math.abs(cross)>toll)&&(Math.min(a.x,b.x)-toll<=p.x&&p.x<=Math.max(a.x,b.x)+toll&&Math.min(a.y,b.y)-toll<=p.y&&p.y<=Math.max(a.y,b.y)+toll)}const{p1:p1,p2:p2}=this,{p1:p1_2,p2:p2_2}=line2;return isPointBetween(p1_2,p1,p2)||isPointBetween(p2_2,p1,p2)||isPointBetween(p1,p1_2,p2_2)||isPointBetween(p2,p1_2,p2_2)}return!0}clone(){return new Linea2(this.p1.x,this.p1.y,this.p2.x,this.p2.y)}rotate(deg){if(!deg)return this;const r=deg*Math.PI/180,cosTheta=Math.cos(r),sinTheta=Math.sin(r);function rotate(p){return new Punto2(p.x*cosTheta-p.y*sinTheta,p.x*sinTheta+p.y*cosTheta)}return this.p1=rotate(this.p1),this.p2=rotate(this.p2),this}move(x=0,y=0){return"object"==typeof x&&x.x&&(y=x.y||0,x=x.x),this.p1.x+=x,this.p1.y+=y,this.p2.x+=x,this.p2.y+=y,this}}
141
141
  /**
142
142
  * Calcola i punti di offset tra due percorsi
143
143
  * Trova i punti del secondo percorso che corrispondono all'offset del primo
@@ -286,7 +286,7 @@ function sharpCorners(path,thresholdDeg=45){const result=[],n=path.length;if(n<3
286
286
  * @param {number} thresholdDeg - Angolo in gradi.
287
287
  * @returns {Array<{ index: number, point: {x:number,y:number}, angle: number }>}
288
288
  */
289
- segment(i,inverse=!1){let n=pt.length;return i<0&&(i+=n),new Linea2(pt[i%n],pt[(i+(inverse?-1:1))%n])},lineoffset(i1,i2,offset){if((i1=(i1||0)%pt.length)!=(i2=(i2||0)%pt.length)){let l2=new Linea2(pt[i1],pt[i2]);if(l2){return l2=l2.offsetline(-offset),this.intersectline(l2)}}},orientasplitter(){-1!=orientation()&&pt.reverse();let np=pt.length;for(let i=0;i<np;i++){let lt=new Linea2(pt[(np+i-1)%np],pt[i]);if(Math.abs(Math.abs(lt.angle)-Math.PI)<.001){i&&selezionaprimo(i);break}}return this},mirrorx(value=0){for(let p of pt)p.x=2*value-p.x;return this},mirrory(value=0){for(let p of pt)p.y=2*value-p.y;return this},simplify(tolerance,hq){return pt=simplify(pt,tolerance,hq),this},fromclip(vv){pt=[];for(let p of vv)pt.push({x:p.x/1e3,y:p.y/1e3});return this},infosegmento(i,open=!1){const n=pt.length;function clampIndex(idx){return(idx+n)%n}function angle(p1,p2){return Math.atan2(p2.y-p1.y,p2.x-p1.x)}function angleDiff(a,b){let diff=a-b;for(;diff>Math.PI;)diff-=2*Math.PI;for(;diff<-Math.PI;)diff+=2*Math.PI;return diff}const p1=pt[i];let p0,p2,p3;if(open)if(0===i){const dx=pt[1].x-pt[0].x,dy=pt[1].y-pt[0].y;p0={x:pt[0].x-dx,y:pt[0].y-dy},p2=pt[1],p3=2==n?{x:pt[1].x+dx,y:pt[1].y+dy}:pt[2]}else if(i===n-1){const dx=pt[n-1].x-pt[n-2].x,dy=pt[n-1].y-pt[n-2].y;p0=pt[n-2],p2={x:pt[n-1].x+dx,y:pt[n-1].y+dy},p3={x:p2.x+dx,y:p2.y+dy}}else p0=pt[i-1],p2=pt[i+1],p3=i+2<n?pt[i+2]:{x:pt[i+1].x+(pt[i+1].x-pt[i].x),y:pt[i+1].y+(pt[i+1].y-pt[i].y)};else{const i0=clampIndex(i-1),i2=clampIndex(i+1),i3=clampIndex(i+2);p0=pt[i0],p2=pt[i2],p3=pt[i3]}const ang12=angle(p1,p2),ang01=angle(p0,p1),ang23=angle(p2,p3);return{x:p1.x,y:p1.y,l:function length(p1,p2){const dx=p2.x-p1.x,dy=p2.y-p1.y;return Math.sqrt(dx*dx+dy*dy)}(p1,p2),ang:ang12/PIF,a1:angleDiff(ang12,ang01)/PIF,a2:angleDiff(ang23,ang12)/PIF}},swapxy(){for(let i=0;i<pt.length;i++){let q=pt[i].x;pt[i].x=-pt[i].y,pt[i].y=-q}return this},fromvec(aa){return pt=[],_addvec(aa),this},addvec(vec){return _addvec(vec),this},frompt(pts){return pt=[...pts],pt=removeduplicate(pt),this},fromdxfvec(verts){let points=[];if(verts&&verts.length)for(let i=0;i<verts.length;i++){let{x:x,y:y,bulge:bulge}=verts[i];if(points.push({x:x,y:y}),bulge){const step=1;let p1={x:x,y:y},p2=verts[(i+1)%verts.length],dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>step&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-step)/step)+1))}}return pt=points.map((e=>({x:Math.round(10*e.x)/10,y:Math.round(10*e.y)/10}))),pt=removeduplicate(pt),this},monotona(){let dxd=dims(pt),pp=pt.map((e=>({x:e.x-dxd.p2.x,y:e.y}))),xp=[];xp.push(pp[0]);let lastv=pp[0].y;for(let i=1;i<pp.length;i++)if(pp[i].y>lastv+1e-4||i==pp.length-1)xp.push(pp[i]),lastv=pp[i].y;else{const newv=lastv+1e-4;xp.push({x:pp[i].x,y:newv}),lastv=newv}return{sh:getshape().frompt(xp),...dxd}},sliceony(stag){let yvalues=stag.pt.map((e=>e.y)).slice(1,-1);const res=[],n=pt.length;let imin=0,yMin=pt[0].y;for(let i=1;i<n;i++)pt[i].y<yMin&&(yMin=pt[i].y,imin=i);const pts=[...pt.slice(imin),...pt.slice(0,imin)],m=pts.length,ymap=new Map;for(let i=0;i<m;i++)for(let y of yvalues)Math.abs(pts[i].y-y)<1e-5&&(ymap.has(y)?ymap.get(y).i2=i:ymap.set(y,{i1:i,i2:i}));const pairs=yvalues.map((y=>ymap.get(y))).filter((p=>p&&p.i1>=0&&p.i2>=0));pairs.length>0&&pairs[0].i1>0&&res.push([...pts.slice(0,pairs[0].i1+1),...pts.slice(pairs[0].i2,pairs[0].length)]);for(let i=0;i<pairs.length-1;i++){const a=pairs[i],b=pairs[i+1];res.push([...pts.slice(a.i1,b.i1+1),...pts.slice(b.i2,a.i2+1)])}const last=pairs[pairs.length-1];last.i2>last.i1&&res.push(pts.slice(last.i1,last.i2+1));return res.filter((arr=>arr.length>0))},splitshape(p,verticale=!0){const p1=verticale?{x:p.x,y:p.y-100}:{x:p.x-100,y:p.y},p2=verticale?{x:p.x,y:p.y+100}:{x:p.x+100,y:p.y},linea=this.intersectline(new Linea2(p1,p2));if(!linea)return null;const pstart=linea.p1,pend=linea.p2,findIndex=pt=>this.pt.findIndex(((v,i)=>new Linea2(v,this.pt[(i+1)%this.pt.length]).onsegment(pt))),i1=findIndex(pstart),i2=findIndex(pend);if(i1<0||i2<0)return null;const n=this.pt.length,loop=(a,b,p0,p1)=>{const res=[];for(let i=a;i!==b;i=(i+1)%n)res.push(this.pt[(i+1)%n]);return res},dx=getshape().frompt(loop(i1,i2));return{sx:getshape().frompt(loop(i2,i1)),dx:dx,linea:linea}},xfromy(y,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.y<=y&&p2.y>=y||p2.y<=y&&p1.y>=y){const dy=p2.y-p1.y,t=dy?(y-p1.y)/dy:0,x=p1.x+t*(p2.x-p1.x);res.push(x)}else p1.y===y&&p2.y===y&&res.push(maggiore?Math.max(p1.x,p2.x):Math.min(p1.x,p2.x))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},yfromx(x,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.x<=x&&p2.x>=x||p2.x<=x&&p1.x>=x){const dx=p2.x-p1.x,t=dx?(x-p1.x)/dx:0,y=p1.y+t*(p2.y-p1.y);res.push(y)}else p1.x===x&&p2.x===x&&res.push(maggiore?Math.max(p1.y,p2.y):Math.min(p1.y,p2.y))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},forcevalues(shape,verticale=!0,delta=1e-6){const sorted=[...new Set(shape.pt.map((e=>verticale?e.y:e.x)))].sort(((a,b)=>a-b)),newpt=[],n=pt.length;for(let i=0;i<n;i++){const p1=pt[i],p2=pt[(i+1)%n];newpt.push({...p1});let v1=verticale?p1.y:p1.x,v2=verticale?p2.y:p2.x;if(v1===v2)continue;const range=v2>v1?sorted.filter((v=>v>v1+delta&&v<v2-delta)):sorted.filter((v=>v<v1-delta&&v>v2+delta)).reverse();for(const v of range){const t=(v-v1)/(v2-v1),q={x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};newpt.push(q)}}return pt=newpt,this},fromrrect(w,h,r=10,sx=0,sy=0){return(r>=w/2||r>=h/2&&r<=0)&&(r=Math.round(Math.min(w/3,h/3))),fromstr(`0,0,r${r},${w},0,r${r},${w},${h},r${r},0,${h},r${r}`),(sx||sy)&&move(sx,sy),this},fromrect(w,h,sx,sy,bordo){w||(w=10),h||(h=10),bordo||(bordo=0),bordo=Math.min(Math.abs(bordo),Math.abs(.4*w),Math.abs(.4*h));let b1=w>0?bordo:-bordo,b2=h>0?bordo:-bordo;return pt=bordo?[{x:b1,y:0},{x:w-b1,y:0},{x:w,y:b2},{x:w,y:h-b2},{x:w-b1,y:h},{x:b1,y:h},{x:0,y:h-b2},{x:0,y:b2}]:[{x:0,y:0},{x:w,y:0},{x:w,y:h},{x:0,y:h}],this},intersectline:l=>function _intersectline(shape,p3,p4){let n=shape.length,l=new Linea2(p3,p4);const intersezioni=[];for(let i=0;i<shape.length;i++){let l2=new Linea2(shape[i],shape[(i+1)%n]),p=l2.interseca(l);p&&l2.onsegment(p)&&intersezioni.push(p)}if(intersezioni.length<2)return null;const{dx:dx,dy:dy}=l;intersezioni.sort(((a,b)=>(a.x-p3.x)*dx+(a.y-p3.y)*dy-((b.x-p3.x)*dx+(b.y-p3.y)*dy)));let pstart=new Punto2(intersezioni[0].x,intersezioni[0].y),pend=new Punto2(intersezioni[intersezioni.length-1].x,intersezioni[intersezioni.length-1].y);const vx1=pend.x-pstart.x,vy1=pend.y-pstart.y;return vx1*dx+vy1*dy<0&&([pstart,pend]=[pend,pstart]),new Linea2(pstart,pend)}(pt,l.p1,l.p2),tostr(dec=2){let dd=10**dec,pstr=x=>String(Math.round(x*dd)/dd),cl=pt.map((e=>`${pstr(e.x)};${pstr(e.y)};`)).join("");return cl&&cl.length?cl.slice(0,-1).match(/.{1,80}(;|$)/g).map((s=>s.trim())).join("\n"):""},addpt(pts){return pts?(Array.isArray(pts)||(pts=[pts]),pt=removeduplicate([...pt,...pts]),this):this},addracc(v1,v2,suddivisioni=2,addv1v2=!0){if(Array.isArray(v1)&&(v2={x:v1[2]||0,y:v1[3]||0},v1={x:v1[0]||0,y:v1[1]||0}),pt.length>=2){let tm=raccordabezier(pt[pt.length-2],pt[pt.length-1],v1,v2,suddivisioni);pt=[...pt,...tm],addv1v2&&(pt.push(v1),pt.push(v2))}return pt=removeduplicate(pt),this},setorient(mode){let p=orientation();return(1==p&&-1==mode||-1==p&&1==mode)&&pt.reverse(),this},reverse(){return pt.reverse(),this},pointinshape:p=>function isPointInPolygon(P){let x=P.x,y=P.y,inside=!1;for(let i=0,j=pt.length-1;i<pt.length;j=i++){let xi=pt[i].x,yi=pt[i].y,xj=pt[j].x,yj=pt[j].y;yi>y!=yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}(p),azzera(){return pt=[],this},truncatebefore:function truncatebefore(linea){let s=new Linea2(pt[0],pt[1]),p=linea.interseca(s);if(p){let a=pt[0],b=pt[1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den<=1)return pt[0]=p,this}}for(let i=1;i<pt.length-1;i++){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(i),pt[0]=p,this}return this},truncateafter:function truncateafter(linea){let np=pt.length,s=new Linea2(pt[np-2],pt[np-1]),p=linea.interseca(s);if(p){let a=pt[np-2],b=pt[np-1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den>=0)return pt[np-1]=p,this}}for(let i=np-3;i>=0;i--){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(0,i+1),pt.push(p),this}return this},removeduplicate(delta=.005){return pt=removeduplicate(pt,delta),this},to3d(u0,alt=0,coeffa=0,coeffb=0,open=!1,sh=null,invert=!1){let tm=function to3dcoor(path,options){let{currentU:currentU=0,c:c=0,a:a=0,b:b=0,anglemin:anglemin=30,open:open=!1,sh:sh=null,invert:invert=!1}=options;const pointsWithNormals=[],n=path.length;for(let i=0;i<n;i++){const prev=path[(i-1+n)%n],current=path[i],next=path[(i+1)%n],vPrev={x:current.x-prev.x,y:current.y-prev.y},vNext={x:next.x-current.x,y:next.y-current.y},normalPrev=normal2(prev,current),normalNext=normal2(current,next),angle=angle2vec(vPrev,vNext);let z=a*current.x+b*current.y+c;if(sh){let t=sh.xfromy(current.y,0,!0);invert?z+=t:z-=t}Math.abs(angle-180)<=anglemin?(normalPrev.nx,normalNext.nx,normalPrev.ny,normalNext.ny,pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z})):(pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}),pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}));const dx=next.x-current.x,dy=next.y-current.y;currentU+=Math.sqrt(dx*dx+dy*dy)}if(!open){let p=pointsWithNormals[0],pf=pointsWithNormals[pointsWithNormals.length-1];p.x==pf.x&&p.y==pf.y||pointsWithNormals.push({x:p.x,y:p.y,z:p.z,nx:p.nx,ny:p.ny,nz:p.nz,u:currentU,v:p.z})}return pointsWithNormals}(pt,{open:open,currentU:u0,c:alt,a:coeffa,b:coeffb,anglemin:30,sh:sh,invert:invert});return tm},getboundbox:()=>pt.length?pt.reduce(((box,p)=>(box.p1.x=Math.min(box.p1.x,p.x),box.p1.y=Math.min(box.p1.y,p.y),box.p2.x=Math.max(box.p2.x,p.x),box.p2.y=Math.max(box.p2.y,p.y),box)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}):{p1:new Punto2(0,0),p2:new Punto2(0,0)},fittobox(p1,p2){if(!pt.length)return this;const currentBox=this.getboundbox(),currentWidth=currentBox.p2.x-currentBox.p1.x,currentHeight=currentBox.p2.y-currentBox.p1.y,targetWidth=p2.x-p1.x,targetHeight=p2.y-p1.y,scale=Math.min(targetWidth/(currentWidth||1),targetHeight/(currentHeight||1));for(let p of pt)p.x=(p.x-currentBox.p1.x)*scale,p.y=(p.y-currentBox.p1.y)*scale,p.x+=p1.x,p.y+=p1.y;return this}}}
289
+ segment(i,inverse=!1){let n=pt.length;return i<0&&(i+=n),new Linea2(pt[i%n],pt[(i+(inverse?-1:1))%n])},lineoffset(i1,i2,offset){if((i1=(i1||0)%pt.length)!=(i2=(i2||0)%pt.length)){let l2=new Linea2(pt[i1],pt[i2]);if(l2){return l2=l2.offsetline(-offset),this.intersectline(l2)}}},orientasplitter(){-1!=orientation()&&pt.reverse();let np=pt.length;for(let i=0;i<np;i++){let lt=new Linea2(pt[(np+i-1)%np],pt[i]);if(Math.abs(Math.abs(lt.angle)-Math.PI)<.001){i&&selezionaprimo(i);break}}return this},mirrorx(value=0){for(let p of pt)p.x=2*value-p.x;return this},mirrory(value=0){for(let p of pt)p.y=2*value-p.y;return this},simplify(tolerance,hq){return pt=simplify(pt,tolerance,hq),this},fromclip(vv){pt=[];for(let p of vv)pt.push({x:p.x/1e3,y:p.y/1e3});return this},infosegmento(i,open=!1){const n=pt.length;function clampIndex(idx){return(idx+n)%n}function angle(p1,p2){return Math.atan2(p2.y-p1.y,p2.x-p1.x)}function angleDiff(a,b){let diff=a-b;for(;diff>Math.PI;)diff-=2*Math.PI;for(;diff<-Math.PI;)diff+=2*Math.PI;return diff}const p1=pt[i];let p0,p2,p3;if(open)if(0===i){const dx=pt[1].x-pt[0].x,dy=pt[1].y-pt[0].y;p0={x:pt[0].x-dx,y:pt[0].y-dy},p2=pt[1],p3=2==n?{x:pt[1].x+dx,y:pt[1].y+dy}:pt[2]}else if(i===n-1){const dx=pt[n-1].x-pt[n-2].x,dy=pt[n-1].y-pt[n-2].y;p0=pt[n-2],p2={x:pt[n-1].x+dx,y:pt[n-1].y+dy},p3={x:p2.x+dx,y:p2.y+dy}}else p0=pt[i-1],p2=pt[i+1],p3=i+2<n?pt[i+2]:{x:pt[i+1].x+(pt[i+1].x-pt[i].x),y:pt[i+1].y+(pt[i+1].y-pt[i].y)};else{const i0=clampIndex(i-1),i2=clampIndex(i+1),i3=clampIndex(i+2);p0=pt[i0],p2=pt[i2],p3=pt[i3]}const ang12=angle(p1,p2),ang01=angle(p0,p1),ang23=angle(p2,p3);return{x:p1.x,y:p1.y,l:function length(p1,p2){const dx=p2.x-p1.x,dy=p2.y-p1.y;return Math.sqrt(dx*dx+dy*dy)}(p1,p2),ang:ang12/PIF,a1:angleDiff(ang12,ang01)/PIF,a2:angleDiff(ang23,ang12)/PIF}},swapxy(){for(let i=0;i<pt.length;i++){let q=pt[i].x;pt[i].x=-pt[i].y,pt[i].y=-q}return this},fromvec(aa){return pt=[],_addvec(aa),this},addvec(vec){return _addvec(vec),this},frompt(pts){return pt=[...pts],pt=removeduplicate(pt),this},fromdxfvec(verts){let points=[];if(verts&&verts.length)for(let i=0;i<verts.length;i++){let{x:x,y:y,bulge:bulge}=verts[i];if(points.push({x:x,y:y}),bulge){const step=1;let p1={x:x,y:y},p2=verts[(i+1)%verts.length],dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>step&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-step)/step)+1))}}return pt=points.map((e=>({x:Math.round(10*e.x)/10,y:Math.round(10*e.y)/10}))),pt=removeduplicate(pt),this},monotona(){let dxd=dims(pt),pp=pt.map((e=>({x:e.x-dxd.p2.x,y:e.y}))),xp=[];xp.push(pp[0]);let lastv=pp[0].y;for(let i=1;i<pp.length;i++)if(pp[i].y>lastv+1e-4||i==pp.length-1)xp.push(pp[i]),lastv=pp[i].y;else{const newv=lastv+1e-4;xp.push({x:pp[i].x,y:newv}),lastv=newv}return{sh:getshape().frompt(xp),...dxd}},offsetshape(delta){let sg=[],sh=this;for(let i=0;i<sh.npt-1;i++){let l=sh.segment(i).offset(delta);sg.push(l)}let l1=sh.segment(0).perpendicolare(),s2=sh.segment(sh.npt-2),l2=s2.perpendicolare(s2.p2),pts=[l1.interseca(sg[0])];for(let i=0;i<sg.length-1;i++){let p=sg[i].interseca(sg[i+1]);p&&pts.push(p)}return pts.push(sg[sg.length-1].interseca(l2)),getshape().frompt(pts)},sliceony(stag){let yvalues=stag.pt.map((e=>e.y)).slice(1,-1);const res=[],n=pt.length;let imin=0,yMin=pt[0].y;for(let i=1;i<n;i++)pt[i].y<yMin&&(yMin=pt[i].y,imin=i);const pts=[...pt.slice(imin),...pt.slice(0,imin)],m=pts.length,ymap=new Map;for(let i=0;i<m;i++)for(let y of yvalues)Math.abs(pts[i].y-y)<1e-5&&(ymap.has(y)?ymap.get(y).i2=i:ymap.set(y,{i1:i,i2:i}));const pairs=yvalues.map((y=>ymap.get(y))).filter((p=>p&&p.i1>=0&&p.i2>=0));pairs.length>0&&pairs[0].i1>0&&res.push([...pts.slice(0,pairs[0].i1+1),...pts.slice(pairs[0].i2,pairs[0].length)]);for(let i=0;i<pairs.length-1;i++){const a=pairs[i],b=pairs[i+1];res.push([...pts.slice(a.i1,b.i1+1),...pts.slice(b.i2,a.i2+1)])}const last=pairs[pairs.length-1];last.i2>last.i1&&res.push(pts.slice(last.i1,last.i2+1));return res.filter((arr=>arr.length>0))},splitshape(p,verticale=!0){const p1=verticale?{x:p.x,y:p.y-100}:{x:p.x-100,y:p.y},p2=verticale?{x:p.x,y:p.y+100}:{x:p.x+100,y:p.y},linea=this.intersectline(new Linea2(p1,p2));if(!linea)return null;const pstart=linea.p1,pend=linea.p2,findIndex=pt=>this.pt.findIndex(((v,i)=>new Linea2(v,this.pt[(i+1)%this.pt.length]).onsegment(pt))),i1=findIndex(pstart),i2=findIndex(pend);if(i1<0||i2<0)return null;const n=this.pt.length,loop=(a,b,p0,p1)=>{const res=[];for(let i=a;i!==b;i=(i+1)%n)res.push(this.pt[(i+1)%n]);return res},dx=getshape().frompt(loop(i1,i2));return{sx:getshape().frompt(loop(i2,i1)),dx:dx,linea:linea}},xfromy(y,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.y<=y&&p2.y>=y||p2.y<=y&&p1.y>=y){const dy=p2.y-p1.y,t=dy?(y-p1.y)/dy:0,x=p1.x+t*(p2.x-p1.x);res.push(x)}else p1.y===y&&p2.y===y&&res.push(maggiore?Math.max(p1.x,p2.x):Math.min(p1.x,p2.x))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},yfromx(x,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.x<=x&&p2.x>=x||p2.x<=x&&p1.x>=x){const dx=p2.x-p1.x,t=dx?(x-p1.x)/dx:0,y=p1.y+t*(p2.y-p1.y);res.push(y)}else p1.x===x&&p2.x===x&&res.push(maggiore?Math.max(p1.y,p2.y):Math.min(p1.y,p2.y))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},forcevalues(shape,verticale=!0,delta=1e-6){const sorted=[...new Set(shape.pt.map((e=>verticale?e.y:e.x)))].sort(((a,b)=>a-b)),newpt=[],n=pt.length;for(let i=0;i<n;i++){const p1=pt[i],p2=pt[(i+1)%n];newpt.push({...p1});let v1=verticale?p1.y:p1.x,v2=verticale?p2.y:p2.x;if(v1===v2)continue;const range=v2>v1?sorted.filter((v=>v>v1+delta&&v<v2-delta)):sorted.filter((v=>v<v1-delta&&v>v2+delta)).reverse();for(const v of range){const t=(v-v1)/(v2-v1),q={x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};newpt.push(q)}}return pt=newpt,this},fromrrect(w,h,r=10,sx=0,sy=0){return(r>=w/2||r>=h/2&&r<=0)&&(r=Math.round(Math.min(w/3,h/3))),fromstr(`0,0,r${r},${w},0,r${r},${w},${h},r${r},0,${h},r${r}`),(sx||sy)&&move(sx,sy),this},fromrect(w,h,sx,sy,bordo){w||(w=10),h||(h=10),bordo||(bordo=0),bordo=Math.min(Math.abs(bordo),Math.abs(.4*w),Math.abs(.4*h));let b1=w>0?bordo:-bordo,b2=h>0?bordo:-bordo;return pt=bordo?[{x:b1,y:0},{x:w-b1,y:0},{x:w,y:b2},{x:w,y:h-b2},{x:w-b1,y:h},{x:b1,y:h},{x:0,y:h-b2},{x:0,y:b2}]:[{x:0,y:0},{x:w,y:0},{x:w,y:h},{x:0,y:h}],this},intersectline:l=>function _intersectline(shape,p3,p4){let n=shape.length,l=new Linea2(p3,p4);const intersezioni=[];for(let i=0;i<shape.length;i++){let l2=new Linea2(shape[i],shape[(i+1)%n]),p=l2.interseca(l);p&&l2.onsegment(p)&&intersezioni.push(p)}if(intersezioni.length<2)return null;const{dx:dx,dy:dy}=l;intersezioni.sort(((a,b)=>(a.x-p3.x)*dx+(a.y-p3.y)*dy-((b.x-p3.x)*dx+(b.y-p3.y)*dy)));let pstart=new Punto2(intersezioni[0].x,intersezioni[0].y),pend=new Punto2(intersezioni[intersezioni.length-1].x,intersezioni[intersezioni.length-1].y);const vx1=pend.x-pstart.x,vy1=pend.y-pstart.y;return vx1*dx+vy1*dy<0&&([pstart,pend]=[pend,pstart]),new Linea2(pstart,pend)}(pt,l.p1,l.p2),tostr(dec=2){let dd=10**dec,pstr=x=>String(Math.round(x*dd)/dd),cl=pt.map((e=>`${pstr(e.x)};${pstr(e.y)};`)).join("");return cl&&cl.length?cl.slice(0,-1).match(/.{1,80}(;|$)/g).map((s=>s.trim())).join("\n"):""},addpt(pts){return pts?(Array.isArray(pts)||(pts=[pts]),pt=removeduplicate([...pt,...pts]),this):this},addracc(v1,v2,suddivisioni=2,addv1v2=!0){if(Array.isArray(v1)&&(v2={x:v1[2]||0,y:v1[3]||0},v1={x:v1[0]||0,y:v1[1]||0}),pt.length>=2){let tm=raccordabezier(pt[pt.length-2],pt[pt.length-1],v1,v2,suddivisioni);pt=[...pt,...tm],addv1v2&&(pt.push(v1),pt.push(v2))}return pt=removeduplicate(pt),this},setorient(mode){let p=orientation();return(1==p&&-1==mode||-1==p&&1==mode)&&pt.reverse(),this},reverse(){return pt.reverse(),this},pointinshape:p=>function isPointInPolygon(P){let x=P.x,y=P.y,inside=!1;for(let i=0,j=pt.length-1;i<pt.length;j=i++){let xi=pt[i].x,yi=pt[i].y,xj=pt[j].x,yj=pt[j].y;yi>y!=yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}(p),azzera(){return pt=[],this},truncatebefore:function truncatebefore(linea){let s=new Linea2(pt[0],pt[1]),p=linea.interseca(s);if(p){let a=pt[0],b=pt[1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den<=1)return pt[0]=p,this}}for(let i=1;i<pt.length-1;i++){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(i),pt[0]=p,this}return this},truncateafter:function truncateafter(linea){let np=pt.length,s=new Linea2(pt[np-2],pt[np-1]),p=linea.interseca(s);if(p){let a=pt[np-2],b=pt[np-1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den>=0)return pt[np-1]=p,this}}for(let i=np-3;i>=0;i--){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(0,i+1),pt.push(p),this}return this},removeduplicate(delta=.005){return pt=removeduplicate(pt,delta),this},to3d(u0,alt=0,coeffa=0,coeffb=0,open=!1,sh=null,invert=!1){let tm=function to3dcoor(path,options){let{currentU:currentU=0,c:c=0,a:a=0,b:b=0,anglemin:anglemin=30,open:open=!1,sh:sh=null,invert:invert=!1}=options;const pointsWithNormals=[],n=path.length;for(let i=0;i<n;i++){const prev=path[(i-1+n)%n],current=path[i],next=path[(i+1)%n],vPrev={x:current.x-prev.x,y:current.y-prev.y},vNext={x:next.x-current.x,y:next.y-current.y},normalPrev=normal2(prev,current),normalNext=normal2(current,next),angle=angle2vec(vPrev,vNext);let z=a*current.x+b*current.y+c;if(sh){let t=sh.xfromy(current.y,0,!0);invert?z+=t:z-=t}Math.abs(angle-180)<=anglemin?(normalPrev.nx,normalNext.nx,normalPrev.ny,normalNext.ny,pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z})):(pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}),pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}));const dx=next.x-current.x,dy=next.y-current.y;currentU+=Math.sqrt(dx*dx+dy*dy)}if(!open){let p=pointsWithNormals[0],pf=pointsWithNormals[pointsWithNormals.length-1];p.x==pf.x&&p.y==pf.y||pointsWithNormals.push({x:p.x,y:p.y,z:p.z,nx:p.nx,ny:p.ny,nz:p.nz,u:currentU,v:p.z})}return pointsWithNormals}(pt,{open:open,currentU:u0,c:alt,a:coeffa,b:coeffb,anglemin:30,sh:sh,invert:invert});return tm},getboundbox:()=>pt.length?pt.reduce(((box,p)=>(box.p1.x=Math.min(box.p1.x,p.x),box.p1.y=Math.min(box.p1.y,p.y),box.p2.x=Math.max(box.p2.x,p.x),box.p2.y=Math.max(box.p2.y,p.y),box)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}):{p1:new Punto2(0,0),p2:new Punto2(0,0)},fittobox(p1,p2){if(!pt.length)return this;const currentBox=this.getboundbox(),currentWidth=currentBox.p2.x-currentBox.p1.x,currentHeight=currentBox.p2.y-currentBox.p1.y,targetWidth=p2.x-p1.x,targetHeight=p2.y-p1.y,scale=Math.min(targetWidth/(currentWidth||1),targetHeight/(currentHeight||1));for(let p of pt)p.x=(p.x-currentBox.p1.x)*scale,p.y=(p.y-currentBox.p1.y)*scale,p.x+=p1.x,p.y+=p1.y;return this}}}
290
290
  /**
291
291
  * Calcola i punti di un arco passante per tre punti
292
292
  * @param {number} segments - Numero di segmenti (punti-1)
@@ -504,7 +504,7 @@ ClipperLib.ExPolygon=function(){this.outer=null,this.holes=null},ClipperLib.JS.A
504
504
  * @property {Function} inflate - Espande o contrae una forma
505
505
  * @property {Function} unisci - Unisce più forme con gestione di fori e tagli
506
506
  */
507
- function alignByMinDist(sag1,sag2,isopen){const n1=sag1.length,n2=sag2.length;if(n1<1||n2<1)return sag2.slice();let bestOffset=0,minSum=1/0;for(let k=0;k<n2;k++){const p0=sag1[0],q0=sag2[k%n2],dx0=p0.x-q0.x,dy0=p0.y-q0.y,p1=sag1[n1-1],q1=sag2[isopen?Math.min(k+n1-1,n2-1):(k+n1-1)%n2],dx1=p1.x-q1.x,dy1=p1.y-q1.y,sum=dx0*dx0+dy0*dy0+dx1*dx1+dy1*dy1;sum<minSum&&(minSum=sum,bestOffset=k)}return[...sag2.slice(bestOffset),...sag2.slice(0,bestOffset)]}function shapeclip(){function toclipformat(pts){let tm=pts.map((e=>({X:Math.round(1e4*e.x),Y:Math.round(1e4*e.y)})));return ensureOrientation(tm)}function fromclipformat(pts){return pts.map((e=>({x:e.X/1e4,y:e.Y/1e4})))}const ensureOrientation=poly=>ClipperLib.Clipper.Orientation(poly)?poly:poly.slice().reverse();function orientation(pt){if(!pt.length)return 0;let area=0;const n=pt.length;for(let i=0;i<n;i++){const current=pt[i],next=pt[(i+1)%n];area+=current.X*next.Y-next.X*current.Y}return area>0?1:area<0?-1:0}const _inflate=(pt,delta,cut=!1)=>{const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.AddPath(pt,ClipperLib.JoinType.jtMiter,cut||2==pt.length?ClipperLib.EndType.etOpenButt:ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;return co.Execute(solution,delta),solution};function _inflateopen(pts,delta){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*delta,pshape=toclipformat(pts);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return getshape().frompt(tm)}return{offset(shape,delta,full=!1){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*Math.abs(delta),pshape=toclipformat(shape.pt);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etOpenButt);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return full?getshape().frompt(tm):getshape().frompt(getptsoffset(shape.pt,tm,delta))},inflate:function inflate(shape,delta=2,mantainorder=!1,isopen=0){let pshape=toclipformat(shape.pt),tm=_inflate(pshape,1e4*delta);if(!tm||!tm.length)return getshape().frompt([]);let p2=getshape().frompt(fromclipformat(tm[0]));if(mantainorder){p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,isopen);if(p2.frompt(p3),isopen>0&&shape.pt.length>=3){function estendi1(sh1,sh2){let l1=sh1.segment(0).ruotata(-Math.PI/2,200,!0),l2=sh1.segment(-2).ruotata(-Math.PI/2,200),q2=sh2.segment(-2).interseca(l2),q1=sh2.segment(0).interseca(l1);q1&&(sh2.pt[0]=q1),q2&&(sh2.pt[sh2.pt.length-1]=q2)}function estendi2(sh1,sh2){let lfin=sh1.segment(-1),l2=sh2.segment(0),q1=lfin.interseca(l2);q1&&(sh2.pt[0]=q1),l2=sh2.segment(-2);let q2=lfin.interseca(l2);q2&&(sh2.pt[sh2.pt.length-1]=q2)}1==isopen?estendi1(shape,p2):estendi2(shape,p2)}}return p2},inflateopen:_inflateopen,inflateclose(shape,delta){let p2=_inflateopen(shape.pt,delta);p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,0);return p2.frompt(p3),p2},inflatecornici(shape,delta=2,linetruncateini,linetruncateend){let p2,n=shape.npt;if(2==n){let l2=shape.segment(0).offset(delta);p2=getshape().frompt([l2.p1,l2.p2])}else if(3==n){let l1=shape.segment(0).offset(delta),l2=shape.segment(1).offset(delta);if(l1.isparallela(l2))p2=getshape().frompt([l1.p1,l2.p2]);else{let p=l1.interseca(l2);p2=getshape().frompt([l1.p1,p,l2.p2])}}else{let l1=new Linea2(shape.pt[0],shape.pt[shape.npt-1]),len1=l1.len,l2=l1.perpendicolare(l1.p1,len1),l3=l1.perpendicolare(l1.p2,len1);l2.isparallela(shape.segment(0))&&(l2=l1.perpendicolare(l1.puntot(.1),len1)),l3.isparallela(shape.segment(shape.npt-2))&&(l3=l1.perpendicolare(l1.puntot(.9),len1));let n2=Math.floor(shape.npt/2),{t:t}=l2.proiezionet(shape.pt[n2]),t2=2*(t>0?-1:1),px2=l2.puntot(t2),px3=l3.puntot(t2);p2=_inflateopen([...shape.pt,px3,px2],delta);let idx=p2.pt.reduce(((imin,p,i)=>(p.x-px2.x)**2+(p.y-px2.y)**2<(p2.pt[imin].x-px2.x)**2+(p2.pt[imin].y-px2.y)**2?i:imin),0);p2.pt=p2.pt.slice(idx+2).concat(p2.pt.slice(0,idx)),p2.orient!=shape.orient&&p2.reverse(),linetruncateini&&(shape.truncatebefore(linetruncateini),p2.truncatebefore(linetruncateini)),linetruncateend&&(p2.truncateafter(linetruncateend),shape.truncateafter(linetruncateend))}return p2},intersecasplitter(areabase,forma1){const clipper=new ClipperLib.Clipper,pt1=[toclipformat(forma1.pt)],pt2=[toclipformat(areabase.pt)];clipper.AddPaths(pt1,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(pt2,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;let res;if(clipper.Execute(ClipperLib.ClipType.ctIntersection,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)&&solution.length>0){const path=solution[0];if(1===orientation(path)){res=getshape().frompt(fromclipformat(path)),res.orient!=forma1.orient&&res.reverse();for(let iu=0;iu<forma1.pt.length;iu++){let p2=forma1.pt[iu],id=res.pt.findIndex((p=>Math.abs(p.x-p2.x)<.01&&Math.abs(p.y-p2.y)<.01));if(id>0){id-=iu,0!=id&&res.selezionaprimo(id);break}}}}return res},offsetpts(pts,delta=.01){const DELTA=1e4*delta;let tm=_inflate(toclipformat(pts),DELTA);if(tm&&tm.length)return fromclipformat(tm[0])},areesplitter(shapept,clipspt,useInflatedClipping=!0){if(!Array.isArray(shapept)||shapept.length<3)return;if(!clipspt||0==clipspt.length)return[shapept];const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;let shape_in=useInflatedClipping?_inflate(toclipformat(shapept),-100):[toclipformat(shapept)],clips_in=useInflatedClipping?clipspt.flatMap((c=>_inflate(toclipformat(c),100))):clipspt.map((c=>toclipformat(c)));for(let s of shape_in)subj.push(s);for(let c of clips_in)clip.push(c);const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(!clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero))return;let res=[];for(let x of solution)if(useInflatedClipping){const restored=_inflate(x,100);for(const r of restored)1===orientation(r)&&res.push(fromclipformat(r))}else if(x.length>4&&1==orientation(x)){const cleaned=_inflate(x,-100);if(cleaned.length>0)for(let cc of cleaned){const restored=_inflate(cc,100);for(const rr of restored)1===orientation(rr)&&res.push(fromclipformat(rr))}}else 1==orientation(x)&&res.push(fromclipformat(x));return res},unisci(shapes,holes,cuts){const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;for(let hh of shapes){let h2=[toclipformat(hh.pt)];for(let h of h2)subj.push(h)}if(holes&&holes.length)for(let hh of holes){let h1=toclipformat(hh.pt);clip.push(h1)}if(cuts&&cuts.length)for(let hh of cuts){let h1=toclipformat(hh.pt),h2=_inflate(h1,1,!0);for(let h of h2)clip.push(h)}const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)){let res=[],holes=[];for(let x of solution)if(1==orientation(x)){let yy=[x];for(let y of yy)res.push({shape:getshape().frompt(fromclipformat(y)),holes:[]})}else holes.push(getshape().frompt(fromclipformat(x)));for(let h of holes)for(let s of res)if(s.shape.pointinshape(h.pt[0])){s.holes.push(h);break}return res}return[]}}}class Vscene{constructor(x,y,info={}){this.x=x,this.y=y,this.info=info,this.clear()}addrow(o){o||(o={}),o.id=function newid(rows){let max=0;for(let x of rows)+x.id>max&&(max=+x.id);return max+1}(this.rows);let tm=new Vobject(o);return this.rows.push(tm),tm}clear(){this.curlayer=0,this.rows=[],this.clines=[]}fromjson(o){o||(o={info:{}}),this.clear(),this.x=o.x||4e3,this.y=o.y||3e3,this.info=o.info||{},this.curlayer=o.curlayer,o.clines&&(this.clines=o.clines.map((e=>new Linea2(e.p1,e.p2)))),o.rows&&(this.rows=o.rows.map((e=>new Vobject(e))))}tojson(){let{x:x,y:y,info:info,curlayer:curlayer,rows:rows,clines:clines}=this;return rows=rows.map((e=>e.tojson())),clines=clines.map((e=>({p1:e.p1,p2:e.p2}))),{x:x,y:y,curlayer:curlayer,rows:rows,clines:clines}}}class Vobject{constructor(o){o||(o={}),this.fromjson(o)}fromjson(o){this.id=o.id??1,this.layer=o.layer||0,this.hidden=!!o.hidden,this.x=o.x||100,this.y=o.y||100,this.pc=o.pc||{x:0,y:0},o.shape?this.shape=getshape().frompt(o.shape):this.shape=void 0,this.lines=(o.lines||[]).map((e=>new Linea2(e.p1,e.p2))),this.draw=new Vis2d(`d:${o.id}`),o.draw&&this.draw.fromjson(o.draw),this.info=o.info||{},this.pos=o.pos||{x:0,y:0,rot:0}}tojson(){let{id:id,layer:layer,x:x,y:y,pc:pc,shape:shape,hidden:hidden,lines:lines,info:info,pos:pos}=this;return lines=lines.map((e=>({p1:e.p1,p2:e.p2}))),shape=shape?shape.pt:void 0,{id:id,layer:layer,x:x,y:y,pc:pc,shape:shape,lines:lines,hidden:hidden,info:info,pos:pos,draw:this.draw.tojson()}}}class Vis2d{constructor(name){this.name=name,this.clear()}clear(){return this.vec=[],this.gr={},this}tojson(){let tm={};for(let x in this.gr)tm[x]=this.gr[x].tojson();return{name:this.name,rows:this.vec,groups:tm}}fromjson(n){if(!(n&&n.name&&n.rows&&n.groups))throw new Error("wrong data JSON");this.clear(),this.name=n.name,this.vec=n.rows;for(let x in n.groups)this.gr[x]=new Vis2d(x).fromjson(n.groups[x])}creategr(name="grp"){return this.gr[name]||(this.gr[name]=new Vis2d(name)),this.gr[name]}push(x=0,y=0,op={}){"number"==typeof op&&(op={rot:op}),op||(op={}),this.vec.push({type:"push",x:x,y:y,op:op})}pop(){this.vec.push({type:"pop"})}randomcolor(transp="100%"){return`hsl(${Math.floor(360*Math.random())}, 50%, 40%,${transp})`}addgr(gr){let name=gr;gr?.name&&(name=gr.name),this.gr[name]?this.vec.push({type:"group",name:name}):this.vec.push({type:"err",err:`addgroup: ${name} => missing`})}addquota(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"quota",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addqpunto(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"qpunto",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addpoint(p,id=-1,color="red",spessore=8){return p&&this.vec.push({type:"point",p:p,id:id,color:color,spessore:1*spessore}),this}addline(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"line",l:l,id:id,color:color,spessore:1*spessore}),this}addrect(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"rect",l:l,id:id,color:color,spessore:1*spessore}),this}addimg(l,img){return l&&this.vec.push({type:"img",l:l,img:img}),this}addrecta(l,id=-1,color=void 0){return l&&this.vec.push({type:"recta",l:l,id:id,color:color,spessore:0}),this}addshape(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shape",s:s,color:color||this.randomcolor(),spessore:1*spessore}),this}addshapelin(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shapelin",s:s,color:color||this.randomcolor(),spessore:1*spessore}),this}addarea(s,color=void 0){return s&&this.vec.push({type:"area",s:s,color:color||this.randomcolor()}),this}addoffset(x,y){return this.vec.push({type:"offset",x:x||0,y:y||0}),this}}function checkoggetto(oggetti,tipo,cod,isrect){if("h"==tipo&&(tipo="o"),oggetti||(oggetti=[]),"number"==typeof cod&&!["a","as"].includes(tipo))return{cod:"__",macro:"",sps:cod};let bb=oggetti.find((e=>e.tipo.includes(tipo)&&e.cod==cod&&(e.isshape||isrect||"a"!=tipo)));return bb||(bb=oggetti.find((e=>e.tipo.includes(tipo)&&(e.isshape||isrect||"a"!=tipo)))),bb||(bb={cod:"__",macro:"",sps:0}),"a"!=tipo&&"as"!=tipo||"__"==bb.cod||bb.color||(bb.color=`hsl(${function stringToHue(str){let hash=0;for(let i=0;i<str.length;i++)hash=31*hash+str.charCodeAt(i)>>>0;return Math.floor(.6180339887*hash%1*360)}(bb.cod)}, 95%, 97%`),bb}function getbordi(oggetti,bordo){let bordi,uguali=!1;if(Array.isArray(bordo)){bordo.length=4;let b0=bordo[0]||"";bordi=bordo.map((b=>checkoggetto(oggetti,"b",b||b0))),uguali=bordi.every((b=>b.sps===bordi[0].sps))}else{let tm=checkoggetto(oggetti,"b",bordo);bordi=[tm,tm,tm,tm],uguali=!0}return{bordi:bordi,uguali:uguali,senza:!(bordi[0].sps||bordi[1].sps||bordi[2].sps||bordi[3].sps),bl:bordi[0].sps,bt:bordi[1].sps,br:bordi[2].sps,bb:bordi[3].sps}}function elaborapercorso(sh1,bordo,taglio,oggetti,countid=0){let sh2,sh3,p1h,p2h,p3h,p4h,p1v,p2v,p3v,p4v,p1s,p2s,line1,line2,i1,i2,dati=[],draws=[];function eseguipezzo(l1,l2,bordo,shape){let info=l1.infoquad(l2);if(info&&info.distanza){let s0=getshape().frompt(shape||[l1.p1,l1.p2,l2.p2,l2.p1]),s1=s0.clone();(info.sx||info.sy)&&s1.move(-info.sx||0,-info.sy||0),info.angle&&s1.rotate(-info.angle||0);let tm={id:++countid,type:`b${bordo}`,info:info};shape&&(tm.shape=s1.pt),draws.push({type:`b${bordo}`,pt:s0.pt}),dati.push(tm)}}countid=countid||0;let np=sh1.pt.length,idr=np-1;oggetti||(oggetti=[]);let{bordi:bordi,uguali:uguali,senza:senza}=getbordi(oggetti,bordo);if(uguali)if(senza||!bordi[0].sps)sh2=sh1.clone();else{let b=bordi[0].sps;sh2=shapeclip().inflate(sh1,-b,!0)}else{let b,ll=[],pp=[];for(let i=0;i<np;i++){b=0==i?bordi[0].sps:i==idr-1?bordi[2].sps:i==idr?bordi[3].sps:bordi[1].sps,"number"!=typeof b&&(b=0);let l=sh1.segment(i).offset(-b);ll.push(l)}for(let i=0;i<np;i++){let p=ll[i].interseca(ll[(i-1+np)%np]);pp.push(p)}sh2=getshape().frompt(pp)}if(!senza){p1h=sh2.segment(idr).interseca(sh1.segment(0)),p2h=sh2.segment(1).interseca(sh1.segment(0)),p3h=sh1.segment(idr-1).interseca(sh2.segment(idr-2)),p4h=sh1.segment(idr-1).interseca(sh2.segment(idr)),p1v=sh1.segment(idr).interseca(sh2.segment(0)),p2v=sh1.segment(1).interseca(sh2.segment(0)),p3v=sh1.segment(idr-2).interseca(sh2.segment(idr-1)),p4v=sh1.segment(idr).interseca(sh2.segment(idr-1)),i1=1,i2=idr-2,line1=sh2.segment(0),line2=sh2.segment(idr-1);for(let i=1;i<idr-1;i++){let l=sh1.segment(i),p=l.interseca(line1);p&&l.onsegment(p)&&(i1=i,p2v=p),p=l.interseca(line2),p&&l.onsegment(p)&&(i2=i,p3v=p)}i1-=1,i2=idr-2-i2;let p1=sh1.pt[0],p2=sh2.pt[0],p3=sh2.pt[idr],p4=sh1.pt[idr];switch(taglio[0]){case"v":eseguipezzo(new Linea2(p4v,p1v),sh2.segment(idr),3),p2=p1v,p3=p4v;break;case"o":eseguipezzo(sh1.segment(idr),new Linea2(p4h,p1h),3),p1=p1h,p4=p4h;break;default:eseguipezzo(sh1.segment(idr),sh2.segment(idr),3)}switch(p1s=sh1.pt.slice(1,idr),p2s=sh2.pt.slice(1,idr),taglio[1]){case"v":eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,p2v),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(p3v,p3),2),i1&&(p1s=p1s.slice(i1)),i2&&(p1s=p1s.slice(0,-i2)),p1s[0]=p2v,p1s[p1s.length-1]=p3v;break;case"o":eseguipezzo(new Linea2(p1,p2h),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(p3h,p4),new Linea2(sh2.pt[idr-1],p3),2),p2s[0]=p2h,p2s[p2s.length-1]=p3h;break;default:eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(sh2.pt[idr-1],p3),2)}if(sh3=getshape().frompt(p2s),p1s.length<8&&p1s.length==p2s.length)for(let i=0;i<p1s.length-1;i++)eseguipezzo(new Linea2(p1s[i],p1s[i+1]),new Linea2(p2s[i],p2s[i+1]),1);else{let sh3=getshape().frompt([...p1s,...p2s.reverse()]),l3=new Linea2(p1s[0],p1s[p1s.length-1]),l4=l3.offset(-bordo[1]);eseguipezzo(l3,l4,1,sh3.pt)}}return{countid:countid,shape2:sh2,shapetop:sh3,bordi:bordi,dati:dati,draws:draws}}function creaprofiloesterno(ff,oggetti){let sh1,{x:x,y:y,tipo:tipo,bordo:bordo,taglio:taglio,h1:h1,h2:h2,l1:l1,l2:l2,forma:forma}=ff;x=x<50?50:x,y=y<50?50:y,l1=l1||0,l2=l2||0,h1=h1||0,h2=h2||0;let pts=[0,0];switch(tipo){case"i":case"d":pts.push(l1>0&&l1<x?l1:0,h1>0&&h1<y?y-h1:y),pts.push(l2>0&&l2<x-l1?x-l2:x,h2>0&&h2<y&&h2!=h1?y-h2:y);break;case"a":if(forma){let tm=getshape().fromstr(forma);tm.alignline({x:l1,y:y-h1},{x:x-l2,y:y-h2}),pts.push(...tm.vec)}else if((h1||h2)&&h1>=0&&h1<Math.min(y,x/2)&&h2>=0&&h2<Math.min(y,x/2)){let tm=getshape().fromstr(`a30;${l1||0};${y-h1};${x/2};${y};${x-l2};${y-h2}`);pts.push(...tm.vec)}else pts.push(0,y,x,y);break;case"s":l1>0&&h1>0?pts.push(0,y-h1,l1,y):pts.push(0,y),l2&&l2<x-l1&&h2>0&&h2<y?pts.push(x-l2,y,x,y-h2):pts.push(x,y);break;default:pts.push(0,y,x,y)}pts.push(x,0),ff.countid=0,sh1=getshape().fromvec(pts);let{countid:countid,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}=elaborapercorso(sh1,bordo,taglio,oggetti,ff.countid);return ff.countid=countid,{shape:sh1,internalshape:shape2,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}}
507
+ function alignByMinDist(sag1,sag2,isopen){const n1=sag1.length,n2=sag2.length;if(n1<1||n2<1)return sag2.slice();let bestOffset=0,minSum=1/0;for(let k=0;k<n2;k++){const p0=sag1[0],q0=sag2[k%n2],dx0=p0.x-q0.x,dy0=p0.y-q0.y,p1=sag1[n1-1],q1=sag2[isopen?Math.min(k+n1-1,n2-1):(k+n1-1)%n2],dx1=p1.x-q1.x,dy1=p1.y-q1.y,sum=dx0*dx0+dy0*dy0+dx1*dx1+dy1*dy1;sum<minSum&&(minSum=sum,bestOffset=k)}return[...sag2.slice(bestOffset),...sag2.slice(0,bestOffset)]}function shapeclip(){function toclipformat(pts){let tm=pts.map((e=>({X:Math.round(1e4*e.x),Y:Math.round(1e4*e.y)})));return ensureOrientation(tm)}function fromclipformat(pts){return pts.map((e=>({x:e.X/1e4,y:e.Y/1e4})))}const ensureOrientation=poly=>ClipperLib.Clipper.Orientation(poly)?poly:poly.slice().reverse();function orientation(pt){if(!pt.length)return 0;let area=0;const n=pt.length;for(let i=0;i<n;i++){const current=pt[i],next=pt[(i+1)%n];area+=current.X*next.Y-next.X*current.Y}return area>0?1:area<0?-1:0}const _inflate=(pt,delta,cut=!1)=>{const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.AddPath(pt,ClipperLib.JoinType.jtMiter,cut||2==pt.length?ClipperLib.EndType.etOpenButt:ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;return co.Execute(solution,delta),solution};function _inflateopen(pts,delta){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*delta,pshape=toclipformat(pts);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return getshape().frompt(tm)}return{offset(shape,delta){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*Math.abs(delta),pshape=toclipformat(shape.pt);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etOpenButt);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return getshape().frompt(tm)},inflate:function inflate(shape,delta=2,mantainorder=!1,isopen=0){let pshape=toclipformat(shape.pt),tm=_inflate(pshape,1e4*delta);if(!tm||!tm.length)return getshape().frompt([]);let p2=getshape().frompt(fromclipformat(tm[0]));if(mantainorder){p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,isopen);if(p2.frompt(p3),isopen>0&&shape.pt.length>=3){function estendi1(sh1,sh2){let l1=sh1.segment(0).ruotata(-Math.PI/2,200,!0),l2=sh1.segment(-2).ruotata(-Math.PI/2,200),q2=sh2.segment(-2).interseca(l2),q1=sh2.segment(0).interseca(l1);q1&&(sh2.pt[0]=q1),q2&&(sh2.pt[sh2.pt.length-1]=q2)}function estendi2(sh1,sh2){let lfin=sh1.segment(-1),l2=sh2.segment(0),q1=lfin.interseca(l2);q1&&(sh2.pt[0]=q1),l2=sh2.segment(-2);let q2=lfin.interseca(l2);q2&&(sh2.pt[sh2.pt.length-1]=q2)}1==isopen?estendi1(shape,p2):estendi2(shape,p2)}}return p2},inflateopen:_inflateopen,inflateclose(shape,delta){let p2=_inflateopen(shape.pt,delta);p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,0);return p2.frompt(p3),p2},inflatecornici(shape,delta=2,linetruncateini,linetruncateend){let p2,n=shape.npt;if(2==n){let l2=shape.segment(0).offset(delta);p2=getshape().frompt([l2.p1,l2.p2])}else if(3==n){let l1=shape.segment(0).offset(delta),l2=shape.segment(1).offset(delta);if(l1.isparallela(l2))p2=getshape().frompt([l1.p1,l2.p2]);else{let p=l1.interseca(l2);p2=getshape().frompt([l1.p1,p,l2.p2])}}else{let l1=new Linea2(shape.pt[0],shape.pt[shape.npt-1]),len1=l1.len,l2=l1.perpendicolare(l1.p1,len1),l3=l1.perpendicolare(l1.p2,len1);l2.isparallela(shape.segment(0))&&(l2=l1.perpendicolare(l1.puntot(.1),len1)),l3.isparallela(shape.segment(shape.npt-2))&&(l3=l1.perpendicolare(l1.puntot(.9),len1));let n2=Math.floor(shape.npt/2),{t:t}=l2.proiezionet(shape.pt[n2]),t2=2*(t>0?-1:1),px2=l2.puntot(t2),px3=l3.puntot(t2);p2=_inflateopen([...shape.pt,px3,px2],delta);let idx=p2.pt.reduce(((imin,p,i)=>(p.x-px2.x)**2+(p.y-px2.y)**2<(p2.pt[imin].x-px2.x)**2+(p2.pt[imin].y-px2.y)**2?i:imin),0);p2.pt=p2.pt.slice(idx+2).concat(p2.pt.slice(0,idx)),p2.orient!=shape.orient&&p2.reverse(),linetruncateini&&(shape.truncatebefore(linetruncateini),p2.truncatebefore(linetruncateini)),linetruncateend&&(p2.truncateafter(linetruncateend),shape.truncateafter(linetruncateend))}return p2},intersecasplitter(areabase,forma1){const clipper=new ClipperLib.Clipper,pt1=[toclipformat(forma1.pt)],pt2=[toclipformat(areabase.pt)];clipper.AddPaths(pt1,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(pt2,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;let res;if(clipper.Execute(ClipperLib.ClipType.ctIntersection,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)&&solution.length>0){const path=solution[0];if(1===orientation(path)){res=getshape().frompt(fromclipformat(path)),res.orient!=forma1.orient&&res.reverse();for(let iu=0;iu<forma1.pt.length;iu++){let p2=forma1.pt[iu],id=res.pt.findIndex((p=>Math.abs(p.x-p2.x)<.01&&Math.abs(p.y-p2.y)<.01));if(id>0){id-=iu,0!=id&&res.selezionaprimo(id);break}}}}return res},offsetpts(pts,delta=.01){const DELTA=1e4*delta;let tm=_inflate(toclipformat(pts),DELTA);if(tm&&tm.length)return fromclipformat(tm[0])},areesplitter(shapept,clipspt,useInflatedClipping=!0){if(!Array.isArray(shapept)||shapept.length<3)return;if(!clipspt||0==clipspt.length)return[shapept];const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;let shape_in=useInflatedClipping?_inflate(toclipformat(shapept),-100):[toclipformat(shapept)],clips_in=useInflatedClipping?clipspt.flatMap((c=>_inflate(toclipformat(c),100))):clipspt.map((c=>toclipformat(c)));for(let s of shape_in)subj.push(s);for(let c of clips_in)clip.push(c);const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(!clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero))return;let res=[];for(let x of solution)if(useInflatedClipping){const restored=_inflate(x,100);for(const r of restored)1===orientation(r)&&res.push(fromclipformat(r))}else if(x.length>4&&1==orientation(x)){const cleaned=_inflate(x,-100);if(cleaned.length>0)for(let cc of cleaned){const restored=_inflate(cc,100);for(const rr of restored)1===orientation(rr)&&res.push(fromclipformat(rr))}}else 1==orientation(x)&&res.push(fromclipformat(x));return res},unisci(shapes,holes,cuts){const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;for(let hh of shapes){let h2=[toclipformat(hh.pt)];for(let h of h2)subj.push(h)}if(holes&&holes.length)for(let hh of holes){let h1=toclipformat(hh.pt);clip.push(h1)}if(cuts&&cuts.length)for(let hh of cuts){let h1=toclipformat(hh.pt),h2=_inflate(h1,1,!0);for(let h of h2)clip.push(h)}const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)){let res=[],holes=[];for(let x of solution)if(1==orientation(x)){let yy=[x];for(let y of yy)res.push({shape:getshape().frompt(fromclipformat(y)),holes:[]})}else holes.push(getshape().frompt(fromclipformat(x)));for(let h of holes)for(let s of res)if(s.shape.pointinshape(h.pt[0])){s.holes.push(h);break}return res}return[]}}}class Vscene{constructor(x,y,info={}){this.x=x,this.y=y,this.info=info,this.clear()}addrow(o){o||(o={}),o.id=function newid(rows){let max=0;for(let x of rows)+x.id>max&&(max=+x.id);return max+1}(this.rows);let tm=new Vobject(o);return this.rows.push(tm),tm}clear(){this.curlayer=0,this.rows=[],this.clines=[]}fromjson(o){let ll,l2;o||(o={info:{}}),this.clear(),this.x=o.x||4e3,this.y=o.y||3e3,this.info=o.info||{},this.curlayer=o.curlayer,o.clines&&(ll=o.clines.map((e=>new Linea2(e.p1,e.p2))));let x=this.x,y=this.y;l2=[new Linea2(0,0,100,0),new Linea2(x,0,x,100),new Linea2(x,y,x-100,y),new Linea2(0,y,0,y-100)],this.clines=[...l2,...ll],o.rows&&(this.rows=o.rows.map((e=>new Vobject(e))))}tojson(){let{x:x,y:y,info:info,curlayer:curlayer,xrows:xrows,xclines:xclines}=this,rows=xrows.map((e=>e.tojson())),clines=xclines.map((e=>({p1:e.p1,p2:e.p2})));return clines=clines.slice(4),{x:x,y:y,curlayer:curlayer,rows:rows,clines:clines}}}class Vobject{constructor(o){o||(o={}),this.fromjson(o)}get lines(){if(this._lines&&this._lines.length)return this._lines;{let{x:x,y:y}=this;return x||(x=100),y||(y=100),[new Linea2(0,0,0,y),new Linea2(x,0,x,y)]}}fromjson(o){let ll;this.id=o.id??1,this.layer=o.layer||0,this.hidden=!!o.hidden,this.x=o.x||100,this.y=o.y||100,this.pc=o.pc||{x:0,y:0},o.shape?this.shape=getshape().frompt(o.shape):this.shape=void 0,o.lines&&o.lines.length&&(ll=o.lines.map((e=>new Linea2(e.p1,e.p2)))),this._lines=ll,this.draw=new Vis2d(`d:${o.id}`),o.draw&&this.draw.fromjson(o.draw),this.info=o.info||{},this.pos=o.pos||{x:0,y:0,rot:0}}tojson(){let{id:id,layer:layer,x:x,y:y,pc:pc,shape:shape,hidden:hidden,_lines:lines,info:info,pos:pos}=this;return lines=lines&&lines.length?lines.map((e=>({p1:e.p1,p2:e.p2}))):void 0,shape=shape?shape.pt:void 0,{id:id,layer:layer,x:x,y:y,pc:pc,shape:shape,lines:lines,hidden:hidden,info:info,pos:pos,draw:this.draw.tojson()}}}class Vis2d{constructor(name){this.name=name,this.clear()}clear(){return this.vec=[],this.gr={},this}tojson(){let tm={};for(let x in this.gr)tm[x]=this.gr[x].tojson();return{name:this.name,rows:this.vec,groups:tm}}fromjson(n){if(!(n&&n.name&&n.rows&&n.groups))throw new Error("wrong data JSON");this.clear(),this.name=n.name,this.vec=n.rows;for(let x in n.groups)this.gr[x]=new Vis2d(x).fromjson(n.groups[x])}creategr(name="grp"){return this.gr[name]||(this.gr[name]=new Vis2d(name)),this.gr[name]}push(x=0,y=0,op={}){"number"==typeof op&&(op={rot:op}),op||(op={}),this.vec.push({type:"push",x:x,y:y,op:op})}pop(){this.vec.push({type:"pop"})}randomcolor(transp="100%"){return`hsl(${Math.floor(360*Math.random())}, 50%, 40%,${transp})`}addgr(gr){let name=gr;gr?.name&&(name=gr.name),this.gr[name]?this.vec.push({type:"group",name:name}):this.vec.push({type:"err",err:`addgroup: ${name} => missing`})}addquota(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"quota",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addqpunto(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"qpunto",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addpoint(p,id=-1,color="red",spessore=8){return p&&this.vec.push({type:"point",p:p,id:id,color:color,spessore:1*spessore}),this}addline(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"line",l:l,id:id,color:color,spessore:1*spessore}),this}addrect(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"rect",l:l,id:id,color:color,spessore:1*spessore}),this}addimg(l,img){return l&&this.vec.push({type:"img",l:l,img:img}),this}addrecta(l,id=-1,color=void 0){return l&&this.vec.push({type:"recta",l:l,id:id,color:color,spessore:0}),this}addshape(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shape",s:s,color:color||this.randomcolor(),spessore:1*spessore}),this}addshapelin(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shapelin",s:s,color:color||this.randomcolor(),spessore:1*spessore}),this}addarea(s,color=void 0){return s&&this.vec.push({type:"area",s:s,color:color||this.randomcolor()}),this}addoffset(x,y){return this.vec.push({type:"offset",x:x||0,y:y||0}),this}}function checkoggetto(oggetti,tipo,cod,isrect){if("h"==tipo&&(tipo="o"),oggetti||(oggetti=[]),"number"==typeof cod&&!["a","as"].includes(tipo))return{cod:"__",macro:"",sps:cod};let bb=oggetti.find((e=>e.tipo.includes(tipo)&&e.cod==cod&&(e.isshape||isrect||"a"!=tipo)));return bb||(bb=oggetti.find((e=>e.tipo.includes(tipo)&&(e.isshape||isrect||"a"!=tipo)))),bb||(bb={cod:"__",macro:"",sps:0}),"a"!=tipo&&"as"!=tipo||"__"==bb.cod||bb.color||(bb.color=`hsl(${function stringToHue(str){let hash=0;for(let i=0;i<str.length;i++)hash=31*hash+str.charCodeAt(i)>>>0;return Math.floor(.6180339887*hash%1*360)}(bb.cod)}, 95%, 97%`),bb}function getbordi(oggetti,bordo){let bordi,uguali=!1;if(Array.isArray(bordo)){bordo.length=4;let b0=bordo[0]||"";bordi=bordo.map((b=>checkoggetto(oggetti,"b",b||b0))),uguali=bordi.every((b=>b.sps===bordi[0].sps))}else{let tm=checkoggetto(oggetti,"b",bordo);bordi=[tm,tm,tm,tm],uguali=!0}return{bordi:bordi,uguali:uguali,senza:!(bordi[0].sps||bordi[1].sps||bordi[2].sps||bordi[3].sps),bl:bordi[0].sps,bt:bordi[1].sps,br:bordi[2].sps,bb:bordi[3].sps}}function elaborapercorso(sh1,bordo,taglio,oggetti,countid=0){let sh2,sh3,p1h,p2h,p3h,p4h,p1v,p2v,p3v,p4v,p1s,p2s,line1,line2,i1,i2,dati=[],draws=[];function eseguipezzo(l1,l2,bordo,shape){let info=l1.infoquad(l2);if(info&&info.distanza){let s0=getshape().frompt(shape||[l1.p1,l1.p2,l2.p2,l2.p1]),s1=s0.clone();(info.sx||info.sy)&&s1.move(-info.sx||0,-info.sy||0),info.angle&&s1.rotate(-info.angle||0);let tm={id:++countid,type:`b${bordo}`,info:info};shape&&(tm.shape=s1.pt),draws.push({type:`b${bordo}`,pt:s0.pt}),dati.push(tm)}}countid=countid||0;let np=sh1.pt.length,idr=np-1;oggetti||(oggetti=[]);let{bordi:bordi,uguali:uguali,senza:senza}=getbordi(oggetti,bordo);if(uguali)if(senza||!bordi[0].sps)sh2=sh1.clone();else{let b=bordi[0].sps;sh2=shapeclip().inflate(sh1,-b,!0)}else{let b,ll=[],pp=[];for(let i=0;i<np;i++){b=0==i?bordi[0].sps:i==idr-1?bordi[2].sps:i==idr?bordi[3].sps:bordi[1].sps,"number"!=typeof b&&(b=0);let l=sh1.segment(i).offset(-b);ll.push(l)}for(let i=0;i<np;i++){let p=ll[i].interseca(ll[(i-1+np)%np]);pp.push(p)}sh2=getshape().frompt(pp)}if(!senza){p1h=sh2.segment(idr).interseca(sh1.segment(0)),p2h=sh2.segment(1).interseca(sh1.segment(0)),p3h=sh1.segment(idr-1).interseca(sh2.segment(idr-2)),p4h=sh1.segment(idr-1).interseca(sh2.segment(idr)),p1v=sh1.segment(idr).interseca(sh2.segment(0)),p2v=sh1.segment(1).interseca(sh2.segment(0)),p3v=sh1.segment(idr-2).interseca(sh2.segment(idr-1)),p4v=sh1.segment(idr).interseca(sh2.segment(idr-1)),i1=1,i2=idr-2,line1=sh2.segment(0),line2=sh2.segment(idr-1);for(let i=1;i<idr-1;i++){let l=sh1.segment(i),p=l.interseca(line1);p&&l.onsegment(p)&&(i1=i,p2v=p),p=l.interseca(line2),p&&l.onsegment(p)&&(i2=i,p3v=p)}i1-=1,i2=idr-2-i2;let p1=sh1.pt[0],p2=sh2.pt[0],p3=sh2.pt[idr],p4=sh1.pt[idr];switch(taglio[0]){case"v":eseguipezzo(new Linea2(p4v,p1v),sh2.segment(idr),3),p2=p1v,p3=p4v;break;case"o":eseguipezzo(sh1.segment(idr),new Linea2(p4h,p1h),3),p1=p1h,p4=p4h;break;default:eseguipezzo(sh1.segment(idr),sh2.segment(idr),3)}switch(p1s=sh1.pt.slice(1,idr),p2s=sh2.pt.slice(1,idr),taglio[1]){case"v":eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,p2v),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(p3v,p3),2),i1&&(p1s=p1s.slice(i1)),i2&&(p1s=p1s.slice(0,-i2)),p1s[0]=p2v,p1s[p1s.length-1]=p3v;break;case"o":eseguipezzo(new Linea2(p1,p2h),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(p3h,p4),new Linea2(sh2.pt[idr-1],p3),2),p2s[0]=p2h,p2s[p2s.length-1]=p3h;break;default:eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(sh2.pt[idr-1],p3),2)}if(sh3=getshape().frompt(p2s),p1s.length<8&&p1s.length==p2s.length)for(let i=0;i<p1s.length-1;i++)eseguipezzo(new Linea2(p1s[i],p1s[i+1]),new Linea2(p2s[i],p2s[i+1]),1);else{let sh3=getshape().frompt([...p1s,...p2s.reverse()]),l3=new Linea2(p1s[0],p1s[p1s.length-1]),l4=l3.offset(-bordo[1]);eseguipezzo(l3,l4,1,sh3.pt)}}return{countid:countid,shape2:sh2,shapetop:sh3,bordi:bordi,dati:dati,draws:draws}}function creaprofiloesterno(ff,oggetti){let sh1,{x:x,y:y,tipo:tipo,bordo:bordo,taglio:taglio,h1:h1,h2:h2,l1:l1,l2:l2,forma:forma}=ff;x=x<50?50:x,y=y<50?50:y,l1=l1||0,l2=l2||0,h1=h1||0,h2=h2||0;let pts=[0,0];switch(tipo){case"i":case"d":pts.push(l1>0&&l1<x?l1:0,h1>0&&h1<y?y-h1:y),pts.push(l2>0&&l2<x-l1?x-l2:x,h2>0&&h2<y&&h2!=h1?y-h2:y);break;case"a":if(forma){let tm=getshape().fromstr(forma);tm.alignline({x:l1,y:y-h1},{x:x-l2,y:y-h2}),pts.push(...tm.vec)}else if((h1||h2)&&h1>=0&&h1<Math.min(y,x/2)&&h2>=0&&h2<Math.min(y,x/2)){let tm=getshape().fromstr(`a30;${l1||0};${y-h1};${x/2};${y};${x-l2};${y-h2}`);pts.push(...tm.vec)}else pts.push(0,y,x,y);break;case"s":l1>0&&h1>0?pts.push(0,y-h1,l1,y):pts.push(0,y),l2&&l2<x-l1&&h2>0&&h2<y?pts.push(x-l2,y,x,y-h2):pts.push(x,y);break;default:pts.push(0,y,x,y)}pts.push(x,0),ff.countid=0,sh1=getshape().fromvec(pts);let{countid:countid,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}=elaborapercorso(sh1,bordo,taglio,oggetti,ff.countid);return ff.countid=countid,{shape:sh1,internalshape:shape2,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}}
508
508
  /**
509
509
  * Genera segmenti basati su intervalli e punti di interruzione
510
510
  * @param {Array<{a: number, b: number}>} t1 - Array di oggetti che rappresentano intervalli con coordinate a e b
package/bin/markuno.js CHANGED
@@ -8,7 +8,7 @@ function testsync(a,b){return a+b}
8
8
  /**
9
9
  * Restituisce il timestamp corrente in millisecondi
10
10
  * @returns {number} Timestamp corrente
11
- */const tk=()=>(new Date).valueOf();function isJsonStr(str){if("string"!=typeof str)return!1;const trimmed=str.trim();return trimmed.startsWith("{")&&trimmed.endsWith("}")||trimmed.startsWith("[")&&trimmed.endsWith("]")}const isObject=value=>!(!value||!Array.isArray(value)&&"object"!=typeof value);function quote(v){if((v=(v||"").trim()).length>1){if(v.startsWith('"')&&v.endsWith('"'))return v;if(v.startsWith("(")&&v.endsWith(")"))return v}return`"${v}"`}function noquote(e){return(e=e.trim()).startsWith('"')&&e.endsWith('"')||e.startsWith("(")&&e.endsWith(")")?e.slice(1,-1):e}function hash(obj){let str="";if("string"==typeof obj||"number"==typeof obj)str=obj+"";else if("object"==typeof obj&&obj){const chiaviOrdinati=Object.keys(obj).sort(),separatore="\0";str=chiaviOrdinati.map((key=>`${key}${separatore}${String(obj[key])}`)).join(separatore)}let h1=2166136261,h2=2218511855;for(let i=0;i<str.length;i++){const char=str.charCodeAt(i);h1^=char,h1+=h1<<5^2779096485,h2^=h1,h2=((h2<<3)+char^2134516169)>>>0}return h1>>>=0,h1.toString(16)+h2.toString(16)}
11
+ */const tk=()=>(new Date).valueOf();function seeder(n,seed="seed42"){const rand=function mulberry32(a){return function(){a=(a|=0)+1831565813|0;let t=Math.imul(a^a>>>15,1|a);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296}}(function xmur3(str){let h=1779033703^str.length;for(let i=0;i<str.length;i++)h=Math.imul(h^str.charCodeAt(i),3432918353),h=h<<13|h>>>19;return function(){return h=Math.imul(h^h>>>16,2246822507),h=Math.imul(h^h>>>13,3266489909),(h^=h>>>16)>>>0}}(String(seed))());return Math.floor(rand()*n)}function isJsonStr(str){if("string"!=typeof str)return!1;const trimmed=str.trim();return trimmed.startsWith("{")&&trimmed.endsWith("}")||trimmed.startsWith("[")&&trimmed.endsWith("]")}const isObject=value=>!(!value||!Array.isArray(value)&&"object"!=typeof value);function quote(v){if((v=(v||"").trim()).length>1){if(v.startsWith('"')&&v.endsWith('"'))return v;if(v.startsWith("(")&&v.endsWith(")"))return v}return`"${v}"`}function noquote(e){return(e=e.trim()).startsWith('"')&&e.endsWith('"')||e.startsWith("(")&&e.endsWith(")")?e.slice(1,-1):e}function hash(obj){let str="";if("string"==typeof obj||"number"==typeof obj)str=obj+"";else if("object"==typeof obj&&obj){const chiaviOrdinati=Object.keys(obj).sort(),separatore="\0";str=chiaviOrdinati.map((key=>`${key}${separatore}${String(obj[key])}`)).join(separatore)}let h1=2166136261,h2=2218511855;for(let i=0;i<str.length;i++){const char=str.charCodeAt(i);h1^=char,h1+=h1<<5^2779096485,h2^=h1,h2=((h2<<3)+char^2134516169)>>>0}return h1>>>=0,h1.toString(16)+h2.toString(16)}
12
12
  /**
13
13
  * Formatta un messaggio di errore rimuovendo informazioni non necessarie
14
14
  * @param {Error|string} err - L'errore da formattare
@@ -115,7 +115,7 @@ function setOggetto(objDestinazione,objSorgente){"object"==typeof objDestinazion
115
115
  /**
116
116
  * Converte la lista degli errori in stringa
117
117
  * @returns {string} Rappresentazione testuale degli errori
118
- */toString(){const cl=[];for(const e of this.err){const m="object"==typeof e.msg?JSON.stringify(e.msg):e.msg||"";cl.push(`${e.row?e.row+":":""}${m}`)}return cl.join("\n")}},toNum=(n,dec=-1)=>{const num="string"==typeof n?parseFloat(n)||0:n;if(dec<0)return num||0;const factor=Math.pow(10,dec);return Math.round(num*factor)/factor||0};function getheaddims(dims){let res;try{res="object"==typeof dims&&dims?dims:JSON.parse(dims||"{}")}catch(error){res={}}return res||(res={}),res.l||(res.l={visible:1,val:1e3,min:0,max:1e4}),res.a||(res.a={visible:1,val:1e3,min:0,max:1e4}),res.p||(res.p={visible:1,val:1e3,min:0,max:1e4}),res}function sortrows(rows){const k2=Object.keys(rows).sort(),out={};for(let i=0;i<k2.length;i++){const k=k2[i],kk=rows[k];i+1<k2.length&&k2[i+1].startsWith(k+".")?kk.hasliv=1:delete kk.hasliv,out[k]=kk}return out}const REGEX_PARENTESI=/(?<!\w)\(/g,REGEX_NUMERO=/^-?[0-9.]+$/,REGEX_FUNZIONE=/^(\w+)(!)?\[(.*)?\]$/,REGEX_DIGIT=/[0-9.]/,REGEX_OPERATOR=/[+\-*/^%]/,REGEX_ALPHA=/[a-zA-Z]/i;function valutaparentesi(expression){for(expression=(expression+"").trim();;){const tm=REGEX_PARENTESI.exec(expression);if(!tm)break;{const{i:i,res:res}=parsevar(expression,tm.index+1,"(",")");if(i<=0)break;expression=expression.substring(0,tm.index)+valutaparentesi(res[0])+(i>=0?expression.substring(i+1):"")}}return function operatoricomparazione(expression){let left,right;const operators={"||":()=>valutaparentesi(left)||valutaparentesi(right)?1:0,"|":()=>valutaparentesi(left)||valutaparentesi(right)?1:0,"&&":()=>valutaparentesi(left)&&valutaparentesi(right)?1:0,"&":()=>valutaparentesi(left)&&valutaparentesi(right)?1:0,"<<=":()=>clean(left)<=clean(right),">>=":()=>clean(left)>=clean(right),"===":()=>clean(left)==clean(right),"==":()=>clean(left)==clean(right),"!!":()=>clean(left)!=clean(right),"<<":()=>clean(left)<clean(right),">>":()=>clean(left)>clean(right),"<=":()=>muCalcbase(left)<=muCalcbase(right),">=":()=>muCalcbase(left)>=muCalcbase(right),"<":()=>muCalcbase(left)<muCalcbase(right),">":()=>muCalcbase(left)>muCalcbase(right),"=":()=>muCalcbase(left)==muCalcbase(right),"!":()=>muCalcbase(left)!=muCalcbase(right)};let operatorIndex=-1,op="";for(const operator in operators)if(operatorIndex=expression.indexOf(operator),operatorIndex>=0){op=operator;break}return-1!==operatorIndex?(left=expression.slice(0,operatorIndex),right=expression.slice(operatorIndex+op.length),operators[op]&&operators[op]()?1:0):muCalcbase(expression)}(expression=function valutainsiemi(expression){if(expression.includes("[")){function resinisiemi(rr){const v1=rr[1],fl=!!rr[2],vv=getcolonne(rr[3]);for(const v of vv)if(v==v1)return fl?"0":"1";return fl?"1":"0"}for(;;){const rr=REGEX_FUNZIONE.exec(expression);if(!rr)break;{const tm=resinisiemi(rr);expression=expression.substring(0,rr.index)+tm+expression.substring(rr.index+rr[0].length)}}}return expression}(expression))}const mathFunctions={sqrt:x=>Math.sqrt(x),sqr:x=>Math.sqrt(x),pow:(x,y)=>Math.pow(x,y),int:x=>Math.floor(x),floor:(x,d=0)=>Math.floor((Number.parseFloat(x)||0)*10**d)/10**d,round:(x,d=0)=>Math.round((Number.parseFloat(x)||0)*10**d)/10**d,dec:(x,d=0)=>Math.floor((Number.parseFloat(x)||0)*10**d)/10**d,abs:x=>Math.abs(x),sin:x=>Math.sin(x*Math.PI/180),cos:x=>Math.cos(x*Math.PI/180),tan:x=>Math.tan(x*Math.PI/180),asin:x=>180*Math.asin(x)/Math.PI,acos:x=>180*Math.acos(x)/Math.PI,atan:x=>180*Math.atan(x)/Math.PI,atan2:(y,x)=>180*Math.atan2(y,x)/Math.PI,log:x=>Math.log(x),log10:x=>Math.log10(x),min:(...args)=>Math.min(...args),max:(...args)=>Math.max(...args),clamp:(x,x1,x2)=>Math.max(x1,Math.min(x2,x)),rnd:(a,b)=>a?b?Math.floor(Math.random()*(b-a+1))+a:Math.floor(Math.random()*a):Math.random(),cas:(a,b)=>Math.floor(Math.random()*(b-a+1))+a};function muCalcbase(expression){let index=0;function parseOperator(){const op=expression[index];return REGEX_OPERATOR.test(op)?(index++,op):null}function parsePrimary(){if("+"===expression[index]||"-"===expression[index]){return("-"===expression[index++]?-1:1)*parsePrimary()}if(REGEX_DIGIT.test(expression[index]))return function parseNumber(){const start=index;for(;index<expression.length&&REGEX_DIGIT.test(expression[index]);)index++;return Number(expression.slice(start,index))}();if("("===expression[index]){index++;const result=parseExpr();return")"===expression[index]&&index++,result}return REGEX_ALPHA.test(expression[index])?function parseFunctions(){const ex=expression.slice(index);if(!ex)return 0;for(const[name,func]of Object.entries(mathFunctions)){const match=new RegExp(`^(${name})\\(`,"i").exec(ex);if(match){index+=match[0].length;let pars=[];for(;;){let tm=parseExpr();if(pars.push(tm),")"===expression[index]){index++;break}if(","!=expression[index])break;index++}return func(...pars)}}return index++,parseExpr()}():0}function parseFactor(){let left=parsePrimary();for(;index<expression.length&&/[/*^%]/.test(expression[index]);){const op=parseOperator(),right=parsePrimary();"*"===op?left*=right:"/"===op?left=right?left/right:0:"%"===op?left=right?left%right:0:"^"===op&&(left=Math.pow(left,right))}return left}function parseExpr(){let left=parseFactor();for(;index<expression.length&&/[+-]/.test(expression[index]);){const op=parseOperator(),right=parseFactor();"+"===op?left+=right:"-"===op&&(left-=right)}return left}return expression=expression.replace(/\s/g,""),parseExpr()}
118
+ */toString(){const cl=[];for(const e of this.err){const m="object"==typeof e.msg?JSON.stringify(e.msg):e.msg||"";cl.push(`${e.row?e.row+":":""}${m}`)}return cl.join("\n")}},toNum=(n,dec=-1)=>{const num="string"==typeof n?parseFloat(n)||0:n;if(dec<0)return num||0;const factor=Math.pow(10,dec);return Math.round(num*factor)/factor||0};function getheaddims(dims){let res;try{res="object"==typeof dims&&dims?dims:JSON.parse(dims||"{}")}catch(error){res={}}return res||(res={}),res.l||(res.l={visible:1,val:1e3,min:0,max:1e4}),res.a||(res.a={visible:1,val:1e3,min:0,max:1e4}),res.p||(res.p={visible:1,val:1e3,min:0,max:1e4}),res}function sortrows(rows){const k2=Object.keys(rows).sort(),out={};for(let i=0;i<k2.length;i++){const k=k2[i],kk=rows[k];i+1<k2.length&&k2[i+1].startsWith(k+".")?kk.hasliv=1:delete kk.hasliv,out[k]=kk}return out}const REGEX_PARENTESI=/(?<!\w)\(/g,REGEX_NUMERO=/^-?[0-9.]+$/,REGEX_FUNZIONE=/^(\w+)(!)?\[(.*)?\]$/,REGEX_DIGIT=/[0-9.]/,REGEX_OPERATOR=/[+\-*/^%]/,REGEX_ALPHA=/[a-zA-Z]/i;function valutaparentesi(expression){for(expression=(expression+"").trim();;){const tm=REGEX_PARENTESI.exec(expression);if(!tm)break;{const{i:i,res:res}=parsevar(expression,tm.index+1,"(",")");if(i<=0)break;expression=expression.substring(0,tm.index)+valutaparentesi(res[0])+(i>=0?expression.substring(i+1):"")}}return function operatoricomparazione(expression){let left,right;const operators={"||":()=>valutaparentesi(left)||valutaparentesi(right)?1:0,"|":()=>valutaparentesi(left)||valutaparentesi(right)?1:0,"&&":()=>valutaparentesi(left)&&valutaparentesi(right)?1:0,"&":()=>valutaparentesi(left)&&valutaparentesi(right)?1:0,"<<=":()=>clean(left)<=clean(right),">>=":()=>clean(left)>=clean(right),"===":()=>clean(left)==clean(right),"==":()=>clean(left)==clean(right),"!!":()=>clean(left)!=clean(right),"<<":()=>clean(left)<clean(right),">>":()=>clean(left)>clean(right),"<=":()=>muCalcbase(left)<=muCalcbase(right),">=":()=>muCalcbase(left)>=muCalcbase(right),"<":()=>muCalcbase(left)<muCalcbase(right),">":()=>muCalcbase(left)>muCalcbase(right),"=":()=>muCalcbase(left)==muCalcbase(right),"!":()=>muCalcbase(left)!=muCalcbase(right)};let operatorIndex=-1,op="";for(const operator in operators)if(operatorIndex=expression.indexOf(operator),operatorIndex>=0){op=operator;break}return-1!==operatorIndex?(left=expression.slice(0,operatorIndex),right=expression.slice(operatorIndex+op.length),operators[op]&&operators[op]()?1:0):muCalcbase(expression)}(expression=function valutainsiemi(expression){if(expression.includes("[")){function resinisiemi(rr){const v1=rr[1],fl=!!rr[2],vv=getcolonne(rr[3]);for(const v of vv)if(v==v1)return fl?"0":"1";return fl?"1":"0"}for(;;){const rr=REGEX_FUNZIONE.exec(expression);if(!rr)break;{const tm=resinisiemi(rr);expression=expression.substring(0,rr.index)+tm+expression.substring(rr.index+rr[0].length)}}}return expression}(expression))}const mathFunctions={sqrt:x=>Math.sqrt(x),sqr:x=>Math.sqrt(x),pow:(x,y)=>Math.pow(x,y),int:x=>Math.floor(x),floor:(x,d=0)=>Math.floor((Number.parseFloat(x)||0)*10**d)/10**d,round:(x,d=0)=>Math.round((Number.parseFloat(x)||0)*10**d)/10**d,dec:(x,d=0)=>Math.floor((Number.parseFloat(x)||0)*10**d)/10**d,abs:x=>Math.abs(x),sin:x=>Math.sin(x*Math.PI/180),cos:x=>Math.cos(x*Math.PI/180),tan:x=>Math.tan(x*Math.PI/180),asin:x=>180*Math.asin(x)/Math.PI,acos:x=>180*Math.acos(x)/Math.PI,atan:x=>180*Math.atan(x)/Math.PI,atan2:(y,x)=>180*Math.atan2(y,x)/Math.PI,seeder:(x,seed)=>seeder(x,seed),log:x=>Math.log(x),log10:x=>Math.log10(x),min:(...args)=>Math.min(...args),max:(...args)=>Math.max(...args),clamp:(x,x1,x2)=>Math.max(x1,Math.min(x2,x)),rnd:(a,b)=>a?b?Math.floor(Math.random()*(b-a+1))+a:Math.floor(Math.random()*a):Math.random(),cas:(a,b)=>Math.floor(Math.random()*(b-a+1))+a};function muCalcbase(expression){let index=0;function parseOperator(){const op=expression[index];return REGEX_OPERATOR.test(op)?(index++,op):null}function parsePrimary(){if("+"===expression[index]||"-"===expression[index]){return("-"===expression[index++]?-1:1)*parsePrimary()}if(REGEX_DIGIT.test(expression[index]))return function parseNumber(){const start=index;for(;index<expression.length&&REGEX_DIGIT.test(expression[index]);)index++;return Number(expression.slice(start,index))}();if("("===expression[index]){index++;const result=parseExpr();return")"===expression[index]&&index++,result}return REGEX_ALPHA.test(expression[index])?function parseFunctions(){const ex=expression.slice(index);if(!ex)return 0;for(const[name,func]of Object.entries(mathFunctions)){const match=new RegExp(`^(${name})\\(`,"i").exec(ex);if(match){index+=match[0].length;let pars=[];for(;;){let tm=parseExpr();if(pars.push(tm),")"===expression[index]){index++;break}if(","!=expression[index])break;index++}return func(...pars)}}return index++,parseExpr()}():0}function parseFactor(){let left=parsePrimary();for(;index<expression.length&&/[/*^%]/.test(expression[index]);){const op=parseOperator(),right=parsePrimary();"*"===op?left*=right:"/"===op?left=right?left/right:0:"%"===op?left=right?left%right:0:"^"===op&&(left=Math.pow(left,right))}return left}function parseExpr(){let left=parseFactor();for(;index<expression.length&&/[+-]/.test(expression[index]);){const op=parseOperator(),right=parseFactor();"+"===op?left+=right:"-"===op&&(left-=right)}return left}return expression=expression.replace(/\s/g,""),parseExpr()}
119
119
  /**
120
120
  * Valuta un'espressione matematica o logica e restituisce il risultato
121
121
  * @param {string|number} expression - L'espressione da valutare
@@ -250,7 +250,7 @@ this.amb=amb}
250
250
  * Carica il contenuto esteso della variante
251
251
  * @param {Object|string} content - Contenuto da caricare, può essere un oggetto o una stringa
252
252
  * @returns {Promise<void>} Promise che si risolve al completamento del caricamento
253
- */async loadContentExtended(content){if("object"==typeof content){for(const x in content)["rows","des","h","alias","obbligo"].includes(x)&&(this[x]=content[x]);"string"==typeof content.def&&content.def.length&&(this.vdef=getcolonne(content.def.trim().toLowerCase())),content.filter&&content.filter.length&&(this.limits=parselimitifromdb(content.filter))}else await this._loadContent(muClComments(content,!1))}todata(){return{name:this.name,des:this.des,alias:this.alias,obbligo:this.obbligo,h:this.h,rows:this.rows,limits:this.limits,key:this.key}}}const _nofunc={};async function getcbfunc(tm,cmd,pars,vari,amb,output){if(cbFunc){if(_nofunc[cmd])return"";let a=await cbFunc(cmd,pars,vari,amb,output);return isObject(a)||(a=(a||"").trim(),"!"==a&&(_nofunc[cmd]=!0,a="")),a}return tm}async function intvaluta(amb,mac,str){return await amb.vari.valuta(str,(async(fun,pars)=>{if("dim"===fun){let dm=muCalc(pars[1]),vv=await dammivariante(amb,mac,pars[2]),col=parseInt(pars[3])||2;return vv&&vv.fromdim?vv.fromdim(dm,col):dm}return await getcbfunc(`**fun:${fun}**`,fun,pars,amb.vari,amb)}))}async function dammivariante(amb,macro,ky){let tm;return tm=macro&&macro?.localvar&&macro.localvar[ky]?macro.localvar[ky]:await amb.getvariante(ky),tm}async function impostavariante(amb,macro,a,b,head){let tm,ky=a;if((b=b||"")&&"string"==typeof b){const k=b.indexOf(":");k>=0&&(k>0&&(ky=clean(b.slice(0,k))),b=b.slice(k+1))}
253
+ */async loadContentExtended(content){if("object"==typeof content){for(const x in content)["rows","des","h","alias","obbligo"].includes(x)&&(this[x]=content[x]);"string"==typeof content.def&&content.def.length&&(this.vdef=getcolonne(content.def.trim().toLowerCase())),content.filter&&content.filter.length&&(this.limits=parselimitifromdb(content.filter))}else await this._loadContent(muClComments(content,!1))}todata(){return{name:this.name,des:this.des,alias:this.alias,obbligo:this.obbligo,h:this.h,rows:this.rows,limits:this.limits,key:this.key}}}const _nofunc={};async function getcbfunc(tm,cmd,pars,vari,amb,output){if(cbFunc){if(_nofunc[cmd])return"";let a=await cbFunc(cmd,pars,vari,amb,output);return isObject(a)||(a=(a||"").trim(),"!"==a&&(_nofunc[cmd]=!0,a="")),a}return tm}async function intvaluta(amb,mac,str){return await amb.vari.valuta(str,(async(fun,pars)=>{switch(fun){case"dim":{let dm=muCalc(pars[1]),vv=await dammivariante(amb,mac,pars[2]),col=parseInt(pars[3])||2;return vv&&vv.fromdim?vv.fromdim(dm,col):dm}case"seed":{let n1=pars[1],cl=getcolonne(pars[2]);return cl[seeder(cl.length,n1)]||""}case"seedvar":{let vv=await dammivariante(amb,mac,pars[2]),n1=pars[1],cl=vv.validkeys();if(pars[4]&&pars[5]){let idcol=muCalc(pars[4])-1;if(idcol>=0){let pcol=getcolonne(pars[5]);cl=cl.filter((e=>{let t=vv.rows[e];if(t&&t.v&&t.v[idcol]){let v=getcolonne(t.v[idcol]);if(v)for(var p of pcol)if(v.includes(p))return!0}return!1}))}}let id=seeder(cl.length,n1);return id>=0&&vv.tovar(cl[id])||""}default:return await getcbfunc(`**fun:${fun}**`,fun,pars,amb.vari,amb)}}))}async function dammivariante(amb,macro,ky){let tm;return tm=macro&&macro?.localvar&&macro.localvar[ky]?macro.localvar[ky]:await amb.getvariante(ky),tm}async function impostavariante(amb,macro,a,b,head){let tm,ky=a;if((b=b||"")&&"string"==typeof b){const k=b.indexOf(":");k>=0&&(k>0&&(ky=clean(b.slice(0,k))),b=b.slice(k+1))}
254
254
  /** @type {Variante} */if(head&&head.alias&&(ky=head.alias),macro&&macro.paralias&&macro.paralias[a]&&(ky=macro.paralias[a]),tm=await dammivariante(amb,macro,ky),tm)if(head&&head.t){head.des||(head.des=tm.des);let x8=head?.filtra||"";if(x8.includes("$")&&(x8=await amb.vari.valuta(x8)),"m"===head.t){let col=2;if(b.includes(":")){const xx=b.split(":");col=parseInt(xx[1]),b=xx[0]}tm.limita(x8),b=tm.fromdim(parseFloat(b),col)}else{tm.limita(x8);const b1=tm.firstvalid(b,getcolonne(head.def));b=tm.tovar(b1)}}else tm.resetfilter(),b=tm.firstvalid(b),b=tm.tovar(b);else head&&head.t&&head.t;return amb.vari.add(a,b),b}async function pushpars(amb,macro,parsfunzione,parsinit){const fatti={},vals=[];if(parsfunzione)for(const x of parsfunzione){const{v:v,o:o,fl:fl}=getcouple(x);fatti[v]||(fatti[v]=!0,vals.push({v:v,o:amb.vari.var[v]}),fl&&await impostavariante(amb,macro,v,o))}if(parsinit)for(const x of parsinit){const{v:v,o:o,fl:fl}=getcouple(x);fatti[v]||(fatti[v]=!0,vals.push({v:v,o:amb.vari.var[v]}),fl&&await impostavariante(amb,macro,v,o))}return vals}function poppars(amb,tm){if(tm)for(const x of tm)amb.vari.add(x.v,x.o)}const outpush=(output,a)=>{null!=a&&null!=a&&("object"==typeof a?output.push(JSON.stringify(a,null,2)):"string"==typeof a&&a.startsWith("_ ")&&output.length>0&&"string"==typeof output[output.length-1]?output[output.length-1]+=a.slice(2):output.push(...a.split("\n")))};async function muEval(amb,mac,codice,options){if(!Array.isArray(codice))return errori.add("codice is not a valid parsed array"),[];options||(options={}),options.id||(options.id="_"),options._stackmacro||(options._stackmacro=0),options.limited||(options.limited=!1),amb||errori.add("amb deve essere definito");const vari=amb.vari;amb.maxdelays,amb.cat;const output=[];let macro,pars,xid;tk();for(let ii=0;ii<codice.length;){let riga=codice[ii];switch(riga.tipo){case"IFDEF":case"IFNDEF":case"IF":{const tm="IF"==riga.tipo?muCalc(await intvaluta(amb,mac,riga.contenuto)):"IFDEF"==riga.tipo?""!=await intvaluta(amb,mac,riga.contenuto):""==await intvaluta(amb,mac,riga.contenuto);riga.next?(codice[riga.next].jlast=tm?1:0,tm||(ii=riga.next-1)):errori.add("Troppo tempo",riga)}break;case"SELECT":riga.next?(codice[riga.next].t1=await intvaluta(amb,mac,riga.contenuto),ii=riga.next-1):errori.add("manca endselect",riga);break;case"CASE":case"CASES":case"DEFAULT":if(riga.next)if(riga.jlast)riga.jlast=0,ii=riga.last-1;else{let vv,tm=1;const _getvv=async()=>{let vv=await intvaluta(amb,mac,riga.contenuto);return vv=vv.includes(":")&&!vv.includes(",")?vv.split(":").map((e=>(e||"").trim())):getcolonne(vv),vv};if("CASE"==riga.tipo){tm=0,vv=await _getvv();const tmx=muCalc(riga.t1||"");vv.find((v=>muCalc(v)==tmx))&&(tm=1)}else if("CASES"==riga.tipo){tm=0,vv=await _getvv();const tmx=riga.t1||"";vv.find((v=>v==tmx))&&(tm=1)}codice[riga.next].jlast=tm?1:0,codice[riga.next].t1=riga.t1,tm||(ii=riga.next-1)}else errori.add("manca select",riga);break;case"ELSEIF":case"ELSEIFDEF":case"ELSEIFNDEF":case"ELSE":if(riga.next)if(riga.jlast)riga.jlast=0,ii=riga.last-1;else{const tm="ELSE"==riga.tipo?1:"ELSEIF"==riga.tipo?muCalc(await intvaluta(amb,mac,riga.contenuto)):"ELSEIFDEF"==riga.tipo?""!=await intvaluta(amb,mac,riga.contenuto):""==await intvaluta(amb,mac,riga.contenuto);codice[riga.next].jlast=tm?1:0,tm||(ii=riga.next-1)}else errori.add("manca endif",riga);break;case"ENDIF":case"ENDSELECT":case"CACHE":case"CVAR":break;case"PUSH":vari.push();break;case"POP":vari.pop();break;case"INC":case"I":if(options._stackmacro>500)errori.add("stack chiamate macro troppo profondo!",riga);else if(({macro:macro,pars:pars,xid:xid}=await amb.getmacro(riga)||{}),macro){options._inc=!0,options._stackmacro++;const saved={},parametri=macro.parametri?._;if(parametri&&parametri.length)for(const x of parametri){const x1=clean(x.split("=")[0]||"",!0);x1&&(saved[x1]=vari.dictionary[x1])}await macro.impostaparametri(parametri,pars);const rs1=await muEval(amb,macro,macro.codice,options);for(const v in saved)saved[v]?vari.dictionary[v]=saved[v]:delete vari.dictionary[v];output.push(...rs1),options._stackmacro--,options._inc=!1}break;case"RET":{const a=await intvaluta(amb,mac,riga.contenuto);amb.vari.savevars(a)}break;case"MACRO":case"M":case"FUNC":case"F":if(options._stackmacro>500)errori.add("stack chiamate macro troppo profondo!",riga);else{let{macro:macro,pars:pars,xid:xid}=await amb.getmacro(riga)||{};if(macro){const ismacro=!!options.grafica||["F","FUNC"].includes(riga.tipo),optid=options.id||"",parametri=macro.parametri?._,saved={};if(ismacro)vari.push();else{if(macro.head)for(const x of macro.head)saved[x.cod]=amb.vari.var(x.cod);if(parametri&&parametri.length)for(const x of parametri){const x1=(x.split("=")[0]||"").trim().toLowerCase();x1&&(saved[x1]=vari.dictionary[x1])}}if(macro.codice.length){if(options._stackmacro++,options.grafica&&"function"==typeof options.grafica){let f="",xid="";pars&&pars.length?(f=pars.find((e=>e.startsWith("#id"))),f?(f=await vari.valuta(f.slice(4)),f.startsWith("#")?options.id=f:options.id=hash(`${ii}${macro.name}${optid}${f}`),pars=pars.filter((e=>!e.startsWith("#id"))),xid=options.id):options.id=hash(`z${optid}${ii}`)):options.id=hash(`z${optid}${ii}`);let tm=amb.pick.key;amb.pick.key=options.id;const out=await options.grafica({tipo:riga.tipo,id:xid,pars:pars,parametri:parametri,macro:macro,options:options,vari:amb.vari,amb:amb});amb.pick.key=tm,output.push(out)}else{await macro.impostaparametri(parametri,pars);let tm=amb.vari.var("_rootnode");amb.vari.add("_rootnode","0");const rs1=await muEval(amb,macro,macro.codice,options);amb.vari.add("_rootnode",tm),output.push(...rs1)}options._stackmacro--}if(ismacro)vari.pop();else for(const v in saved)saved[v]?vari.dictionary[v]=saved[v]:delete vari.dictionary[v];options.id=optid}else errori.add("Macro non trovata!",riga)}break;case"SETDEF":{let cl=getcolonne(riga.contenuto.toLowerCase()),tm=await dammivariante(amb,macro,cl[0]),prf=cl[1]||"def_",filtra=cl[2];if(prf.endsWith("_")||(prf+="_"),tm&&tm.rows){cl=Object.keys(tm.rows),filtra&&(cl=cl.filter((e=>e.startsWith(filtra))));for(let c of cl){let ky=`${prf}${c}`;if(!vari.dictionary[ky]){function torow(tm){const cl=[];if(tm)for(const t of tm.v.slice(1))"string"==typeof t&&(t.includes(",")||t.includes(";"))?cl.push(quote(t)):cl.push(t||"");return cl.join(",")}vari.add(ky,await intvaluta(amb,mac,torow(tm.rows[c])))}}}}break;case"LET":case"LETS":{let i=riga.contenuto.indexOf("="),j=-1;if(i>=0&&(j=riga.contenuto.indexOf("=",i+1)),j<0){const v=riga.contenuto;if(i=v.indexOf("="),i>0){const a=await intvaluta(amb,mac,v.slice(0,i).trim());let b=v.slice(i+1).trim();b="LET"==riga.tipo?muCalc(await intvaluta(amb,mac,b))||"":await intvaluta(amb,mac,b),vari.add(a,b)}}else{const vv=getcolonne(riga.contenuto);for(const v of vv)if(i=v.indexOf("="),i>0){const a=await intvaluta(amb,mac,v.slice(0,i));let b=v.slice(i+1).trim();b="LET"==riga.tipo?muCalc(await intvaluta(amb,mac,b))||"":await intvaluta(amb,mac,b),vari.add(a,b)}}}break;case"LETT":{const i=riga.contenuto.indexOf("=");if(i>0){const a=await intvaluta(amb,mac,riga.contenuto.slice(0,i).trim()),b=await intvaluta(amb,mac,riga.contenuto.slice(i+1).trim());vari.add(a,b)}}break;case"LOOK":case"LOOKB":{const cc=getcolonne(await intvaluta(amb,mac,riga.contenuto)),base=muCalc(cc[1]),col=muCalc(cc[3]),ww=await dammivariante(amb,macro,cc[2]);if(ww&&ww.rows){const rr=Object.values(ww.rows).reduce(((t,e)=>{const val=parseInt(e.v[col?col-1:0]);return val&&("LOOKB"==riga.tipo?val<=base&&val>t.v&&(t.v=val,t.c=e.v[0]):val>=base&&val<t.v&&(t.v=val,t.c=e.v[0])),t}),{v:"LOOKB"==riga.tipo?0:1/0,c:""});rr&&rr.c&&(amb.vari.add(cc[0],ww.tovar(rr.c)),options.checkheader&&"function"==typeof options.checkheader&&await options.checkheader({variante:cc[0],valore:ww.tovar(rr.c),riga:riga}))}else amb.vari.add(cc[0],`${base},no,no`)}break;case"LETV":case"LETM":case"DEF":{const tm=getcolonne(riga.contenuto);if(tm)for(const x of tm){let{v:v,o:o,fl:fl}=getcouple(x);if(fl){v=await vari.valuta(v),o=await intvaluta(amb,mac,o);const valore=await impostavariante(amb,mac,v.trim().toLowerCase(),o.trim().toLowerCase(),"LETM"==riga.tipo?{t:"m"}:{t:"v"});options._stackmacro<=0&&options.checkheader&&"function"==typeof options.checkheader&&await options.checkheader({variante:v,valore:valore,riga:riga})}}}break;case"DO":{const valido=(riga.contenuto||"").trim();let fl=!0;valido&&!muCalc(await intvaluta(amb,mac,valido))&&(fl=!1),riga.next&&(fl||(ii=riga.next+1))}break;case"VARIANTE":case"FORVAR":case"FOR":{let vv,valido,elenco,v;if(options.oldstyle?(vv=riga.contenuto.split(","),v=vv[2]||"i",elenco=vv[0],valido=vv[1]):(vv=getcolonne(riga.contenuto||""),v=vv[0]||"",elenco=clean(vv[1],!0),valido=vv[2]||""),v=v.includes("$")?await intvaluta(amb,mac,v):v||"","FORVAR"==riga.tipo||"VARIANTE"==riga.tipo){const tm=await intvaluta(amb,mac,elenco),xx=tm?await dammivariante(amb,mac,tm):void 0;xx?elenco=xx.tovec():(elenco=[],errori.add("getvariante not found!",riga))}else{const txx=await intvaluta(amb,mac,elenco||"");elenco=elenco?getcolonne(txx):void 0}elenco=elenco||[];const nc=0;if(riga.next){codice[riga.next].for={v:v,elenco:elenco,nc:nc,valido:valido};let voce,fl=!0;v&&elenco.length>0?nc>=elenco.length?fl=!1:(voce=elenco[nc],vari.add(v,voce),valido&&(fl=!muCalc(await intvaluta(amb,mac,valido)))):fl=!1,fl||(ii=riga.next-1)}else errori.add("manca endfor/loop",riga)}break;case"LOOP":{let fl=!0;riga.contenuto&&!muCalc(await intvaluta(amb,mac,riga.contenuto))&&(fl=!1),fl&&(ii=riga.prev-1);break}case"ENDFOR":if(!riga.contenuto||muCalc(await intvaluta(amb,mac,riga.contenuto)))if(riga.for){const{v:v,elenco:elenco,valido:valido}=riga.for;if(v&&elenco.length>0&&riga.for.nc<500)for(;;){if(riga.for.nc++,riga.for.nc<elenco.length){if(vari.add(v,elenco[riga.for.nc]),valido&&muCalc(await intvaluta(amb,mac,valido)))continue;ii=riga.prev;break}break}}else errori.add("manca istruzione for",riga);break;case"BREAK":case"EXIT":case"EXITFOR":riga.next?riga.contenuto.trim()?muCalc(await intvaluta(amb,mac,riga.contenuto))&&(ii=riga.next):ii=riga.next:errori.add("break outside loop",riga);break;case"CONTINUE":riga.next?riga.contenuto&&!muCalc(await intvaluta(amb,mac,riga.contenuto))||(ii=riga.next-1):errori.add("continue outside loop",riga);break;case"MSG":case"LOG":{const tm99=await intvaluta(amb,mac,riga.contenuto);logga(tm99),errori.add(tm99)}break;default:{let tm;if(riga.contenuto.startsWith("!")){tm=await intvaluta(amb,mac,riga.contenuto);let a="";const rr=/^!(.\w+)[\s;,]\s*(.+)?$/gim.exec(tm);if(rr)if(rr[1].startsWith("."))await getcbfunc(tm,tm.slice(1),[],vari,amb),a="";else{const cmd=rr[1].toLowerCase(),pars=getcolonne(rr[2]||"");a=await getcbfunc(tm,cmd,pars,vari,amb)}a&&outpush(output,a)}else options.parsefnpunto&&"function"==typeof options.parsefnpunto&&riga.contenuto.startsWith(".")?await options.parsefnpunto({dati:riga.contenuto,output:output,id:options.id,vari:amb.vari,amb:amb}):(tm=await intvaluta(amb,mac,riga.contenuto),outpush(output,tm))}}ii++}return output}async function muGenerate(macro,amb,genera,callback,isTestmode=0){if(macro.isgenera&&callback){const output={counter:0,keys:{},isTestmode:isTestmode};if(genera){if(!macro.genera[genera])return!1;await muGenerate_0(macro,amb,genera,callback,output)}else for(const gg in macro.genera)await muGenerate_0(macro,amb,gg,callback,output);return!0}}async function muGenerate_0(mac,amb,genera,callback,output){const xgen=mac.genera[genera];if(xgen){output.counter2=0;const working_variant={};async function processavariante(liv){if(output.isTestmode&&output.counter>output.isTestmode)return;if(liv<xgen.vars.length){const xx=xgen.vars[liv];if(!working_variant[xx]){const xvar=await dammivariante(amb,mac,xx),keys=xvar?Object.keys(xvar.rows):void 0;if(keys&&keys.length>0){for(const k of keys)amb.vari.add(xvar.name,xvar.tovar(k)),working_variant[xx]=!0,await processavariante(liv+1),working_variant[xx]=!1;return}logga("manca la variante",xx)}}for(const x of xgen.calcola)mac.formula[x]&&await muEval(amb,mac,mac.formula[x],{limited:!0});for(const x of xgen.exclude)if(mac.formula[x]){const vvv=await muEval(amb,mac,mac.formula[x],{limited:!0});if(vvv)for(const v of vvv){if(muCalc(v))return}}const out1=await muEval(amb,mac,xgen.codice,{limited:!0,localvar:mac.localvar}),bb={};for(const x of xgen.bom)if(mac.formula[x]){let vvv=await muEval(amb,mac,mac.formula[x],{limited:!0});vvv=vvv.join("\n").split("\n");for(const v of vvv)if(v){const tm=getcolonne(v);bb[x]||(bb[x]=[]);const t={};for(let i=0;i<tm.length;i++)t[`c${i}`]=tm[i];bb[x].push(t)}}await async function docallback(callback,out1,bom,xgen,genera,output){let fl=!0;for(const x of out1){const tm=getcolonne(x);if(tm[0]&&!output[tm[0]]){output[tm[0]]=1,output.counter++,output.counter2++;const o={__id:output.counter};for(let i=0;i<tm.length;i++){let key=xgen.head[i]?xgen.head[i]:`c${i}`;"#"==key[0]?(key=key.substr(1),o[key]=Math.round(1e3*muCalc(tm[i]))/1e3):o[key]=tm[i]}await callback(genera,o,fl?bom:void 0,output.counter,output.counter2),fl=!1}}}(callback,out1,bb,xgen,genera,output)}await processavariante(0)}}const DIMS=["l","a","p"],rx1=/^\{(:?(var|valid|formula|genera|header|v|f|g|h))[\s|}]/im,tipifree=["s","g","h","p","q"],tipiheader=[{cod:"t",des:"Variante"},{cod:"q",des:"V.Query"},{cod:"f",des:"Valore Fisso"},{cod:"g",des:"Gruppo"},{cod:"s",des:"Libero"},{cod:"m",des:"Misura"},{cod:"c",des:"Check (no/si)"},{cod:"z",des:"Check (si/no)"},{cod:"h",des:"Hidden"},{cod:"p",des:"Programmato"}],tipicolonna=[{cod:"",des:"Libero"},{cod:"a",des:"Area"},{cod:"t",des:"Thumb",folder:"thumbs"},{cod:"i",des:"Image",folder:"textures"},{cod:"x",des:"3D file",folder:"3d"},{cod:"f",des:"Funzione",folder:"script"}];function valutaCondizioniTestata(vari,str){const vv=str.split("\n");for(const v of vv)if(v.trim()){if(muCalc(vari.valutasync(v)))return!0}return!1}class Macro{constructor(amb,_name){const{name:name,cat:cat}=checkmu(_name,amb.cat||"");this.name=name,this.cat=cat,
255
255
  /** @type {Ambiente} */
256
256
  this.amb=amb,this.azzera()}azzera(){this.key=`${this.cat}/${this.name}`,this.localvar={},this.head=[],this.frontend=!1,this.valid=[],this.parametri={},this.paralias={},this.formula={},this.settings={},this.errori=[],this.codice=[],this.genera={}}get isgenera(){return Object.keys(this.genera).length||0}get iscodice(){return this.codice.length||0}get isheader(){return this.head?.length||0}geterrori(){const cl=[];return this.errori.forEach((e=>cl.push({e:e}))),cl}getparametri(op={}){const{noderiva:noderiva}=op,s={};if(this.dims&&DIMS.forEach((k=>{const t=muCalc(this.amb.vari.var(k));t&&(s[k]=String(t))})),this.head){for(const x of this.head)if(!x._h){if(noderiva&&x._d&&x._d.cod)continue;let tm=this.amb.vari.var(x.cod);tipifree.includes(x.t)||"string"==typeof tm&&(tm=tm.split(",")[0]),s[x.cod]=tm}}else if(this.parametri?._)for(const x of this.parametri._){const x1=(x.split("=")[0]||"").trim().toLowerCase();let tm=this.amb.vari.var[x1];tm=(tm||"").split(",")[0],s[x1]=tm}return s}async setparametri(pars){const ff={},ruleset=this.amb.ruleset||{};pars||(pars={}),this.dims&&DIMS.forEach((e=>{let t=pars[e]||this.dims[e].val;t=parseFloat(t)||0,this.dims[e].visible&&(t<this.dims[e].min&&(t=this.dims[e].min),t>this.dims[e].max&&(t=this.dims[e].max)),pars[e]=String(t)}));for(const x of this.head){const tm=ruleset[x.cod];tm&&(tm.islock?(x.visible="0",pars[x.cod]=tm.opz,x._islock=!0):pars[x.cod]||(pars[x.cod]=tm.opz)),"g"!=x.t&&("z"!=x.t||pars[x.cod]||(pars[x.cod]="1"),x._v=pars[x.cod]||"",ff[x.cod]=!0)}for(const x in pars)ff[x]||(ff[x]=!0,await impostavariante(this.amb,this,x,pars[x]));return this.head?.length>0&&await this.setparametro(this.head[0].cod,pars[this.head[0].cod]||void 0,!0,pars),this.getparametri()}async setparametro(name,value,propaga=!1,pars={}){if(value&&"string"==typeof value&&value.includes("$")&&(value=await intvaluta(this.amb,this,value)),pars||(pars={}),this.head){const _imposta=async(riga,vv,id,propaga)=>{const nn=riga?.cod;if(riga.valid&&!riga._h1){const t0=!valutaCondizioniTestata(this.amb.vari,riga.valid);if(riga._h!=t0&&(riga._h=t0,["g","g1","g2"].includes(riga.t)))for(let i=id+1;i<this.head.length;i++){const tm1=this.head[i];if(tm1){if(["g","g1","g2"].includes(tm1.t))break;tm1._h1=riga._h}}}if(riga._h||riga._h1)return this.amb.vari.add(nn,""),riga._v=void 0,"";{if(delete riga._h2,riga.visible){const t0=!valutaCondizioniTestata(this.amb.vari,riga.visible);if(t0&&(riga._h2=t0),["g","g1","g2"].includes(riga.t))for(let i=id+1;i<this.head.length;i++){const tm1=this.head[i];if(tm1){if(["g","g1","g2"].includes(tm1.t))break;riga._h2?tm1._h3=riga._h2:delete tm1._h3}}}let tx=this.amb.vari.var(nn)||"";"thlm".includes(riga.t)&&"string"==typeof tx&&(tx=tx.split(",")[0]);let txold=tx;if("z"!=riga.t||tx||(this.amb.vari.add(nn,"1"),tx="1"),"m"==riga.t&&riga.spars){const vspars=getcolonne(riga.spars);tx=parseFloat(tx||vspars[0])||0,vspars[1]&&parseFloat(tx)<vspars[1]&&(tx=parseFloat(vspars[1])||0),vspars[2]&&parseFloat(tx)>vspars[2]&&(tx=parseFloat(vspars[2])||0),tx=String(tx),this.amb.vari.add(nn,tx)}const tmimposta=await impostavariante(this.amb,this,nn,vv||riga._v||tx,riga);if(riga._v=void 0,tx=this.amb.vari.var(nn)||"","thl".includes(riga.t)&&"string"==typeof tx&&(tx=tx.split(",")[0],this.amb&&this.amb.deriva&&this.amb.deriva.length>0)){const t2=this.amb.deriva.filter((e=>e.cod==nn&&((!e.item||e.item==this.amb.item)&&((!e.model||e.model==this.amb.model)&&((!e.rule||e.rule==this.amb.rule)&&(!e.opz||e.opz==tx))))));t2.length&&t2.forEach((e=>{let t=this.head.find((h=>h.cod==e.tocod));if(t){let t1=this.amb.vari.var(t.cod);pars&&pars[t.cod]&&(t1=pars[t.cod]),"string"==typeof t1&&(t1=t1.split(",")[0],t1&&t1!=txold&&t1!=tx?delete t._d:(t._v=e.toopz||tx,t._d={cod:riga.cod,opz:e.toopz}))}}))}return tmimposta}};let tm,i0=-1;if("#dim"==name)propaga=1;else{if(i0=this.head.findIndex((e=>e.cod===name)),i0<0)return;const hh=this.head[i0];tm=await _imposta(hh,value,i0),propaga&&delete hh._d}if(propaga)for(let i=i0+1;i<this.head.length;i++)await _imposta(this.head[i],void 0,i);return tm}return await impostavariante(this.amb,this,name,value)}isderivato(hd){return"string"==typeof hd&&(hd=this.head.find((e=>e.cod==hd))),!!(hd&&hd._d&&hd._d.cod)}async impostaparametri(parimposta,parcall,ismacro=!1,progettokeys){if(this.head){this.paralias||(this.paralias={}),Array.isArray(this.head)||(this.head=[]);for(const i of this.head)i._v="",delete i._h,delete i._h1,delete i._h2,i.alias&&(this.paralias[i.cod]=i.alias)}progettokeys||(progettokeys={}),parimposta||(parimposta=[]),parcall||(parcall=[]);for(const x of[...parimposta,...parcall]){const i=x.indexOf("=");if(i>0){let a=clean(x.substr(0,i));a.includes("$")&&(a=await intvaluta(this.amb,this,a));let t,b=x.substr(i+1);b.includes("$")&&(b=await intvaluta(this.amb,this,b)),this.head&&(t=this.head.find((e=>e.cod==a)))?t._v=b:await impostavariante(this.amb,this,a,b)}}if(this.head){let fl=!0;for(const h of this.head){let fl2=await this.checkvalid(h.valid);ismacro&&(fl2=!0),["g","g1","g2"].includes(h.t)?fl=fl2:fl&&fl2&&await this.setparametro(h.cod,progettokeys[h.cod]||h._v)}}}async checkvalid(formula){if(!formula)return!0;return!!muCalc(await intvaluta(this.amb,this,formula))}getmacrostr(){return JSON.stringify(this.getmacro())}getmacro(){return getOggetto(this,["amb"])}setmacro(vv){if(setOggetto(this,fromjson(vv,{})),this.localvar)for(const x in this.localvar){const vv=new Variante;setOggetto(vv,this.localvar[x]),this.localvar[x]=vv}}async load(xname,xcat){let name,cat;try{let tm;if(({name:name,cat:cat}=checkmu(xname||this.name,xcat||this.cat||"")),this.name||(this.name=name),this.cat||(this.cat=cat),this.azzera(),cbGetMacro&&(tm=await cbGetMacro(cat,name),"string"==typeof tm&&(tm.startsWith("{")||tm.startsWith("["))&&(tm=fromjson(tm)),tm&&tm.head&&!Array.isArray(tm.head)&&(tm.head=[]),this.amb.checkscript(tm.linkscript),delete tm.linkscript,tm.head&&(tm.dims=getheaddims(tm.dims))),tm){if("string"==typeof tm)await this.parsedata(tm);else for(const x in tm)this[x]=tm[x];return!0}errori.add(`missing cbGetFile: ${cat}/${name}`)}catch(error){errori.add(geterrdes(error),`macro.load: ${name}/${cat}`)}}async loadAndCompile(file,_cat,acapo=!1){let res;const{name:name,cat:cat}=checkmu(file,this.cat||_cat);return this.azzera(),cbGetFile&&(res=await cbGetFile(cat,name)),res?(await this.parsedata(res,acapo),this.getmacro()):void errori.add(`missing cbGetFile: ${name}/${cat}`)}async#loadinclude(file,flin,stak,pp){let res;const{name:name,cat:cat}=checkmu(file,this.cat);if(cbGetFile&&(res=await cbGetFile(cat,name)),!res)return[];if(res.includes("$1")&&pp&&pp.length>0)for(let i=1;i<pp.length;i++)res=res.replaceAll(`$${i}`,pp[i]);let tm=muClComments(res);const t2=[];flin&&(tm=tm.filter((t=>!/^\{(:?(var|valid|formula|header|genera|v|f|h))[\s|}]/im.test(t))));for(const t of tm){const rr=rx1.exec(t);if(rr)flin=!rr[1].startsWith(":"),t2.push(t);else{const r1=/^\s*\{i\s(.+)?\}/im.exec(t);if(r1){const pp=getcolonne(r1[1]);if(!stak.includes(pp[0])){stak.push(pp[0]);const t3=await this.loadinclude(pp[0],flin,stak,pp);Array.isArray(t3)&&t2.push(...t3),stak.pop()}}else t2.push(t)}}return t2}async parsedata(res,acapo=!1){if(this.azzera(),!res)return;const t2=[];let tm=muClComments(res),flin=!1;const lochead=[];for(const t of tm){const rr=rx1.exec(t);if(rr)flin=!rr[1].startsWith(":"),t2.push(t);else{const r1=/^\s*\{i\s(.+)?\}/im.exec(t);if(r1){const pp=getcolonne(r1[1]),t3=await this.#loadinclude(pp[0],flin,[pp[0]],pp);Array.isArray(t3)&&t2.push(...t3)}else t2.push(t)}}flin=!1;let out=this.codice;for(const t of t2){const rr=rx1.exec(t);if(rr)if(rr[1].startsWith(":"))out=this.codice;else switch(rr[1]){case"genera":case"g":{let r2=/^\s*\{(genera|g)\s+(.+)?\}/im.exec(t);if(r2){const name=checkname(getcolonne(r2[2])[0]);this.genera[name]=[],out=this.genera[name]}else out=this.errori,out.push(t)}break;case"valid":out=this.valid;break;case"var":case"v":{const r2=/^\s*\{(var|v)\s+(.+)?\}/im.exec(t);if(r2){const nn=getcolonne(r2[2]),name=checkname(nn[0]);this.localvar[name]={name:name,des:nn[1]||"",rows:[]},out=this.localvar[name].rows}else out=this.errori,out.push(t)}break;case"formula":case"f":{const r2=/^\s*\{(formula|f)\s+(.+)?\}/im.exec(t);if(r2){const name=checkname(r2[2]);this.formula[name]=[],out=this.formula[name]}else out=this.errori,out.push(t)}break;case"h":case"header":out=lochead;break;default:this.errori.push(t),out=this.errori}else t.startsWith("{")&&(out=this.codice),out.push(t)}this.parametri={},this.codice=this.cleanfiltraparametri("_",this.codice,acapo);for(const f in this.formula)this.formula[f]=this.cleanfiltraparametri(f,this.formula[f],acapo);for(const f in this.localvar){const vv=new Variante,v=this.localvar[f];vv.setheader(f,this.cat),vv.rows={};for(const x of v.rows){const c=getcolonne(x),k=c[0].trim().toLowerCase();vv.rows[k]={annulla:0,v:c}}v.des&&(vv.des=v.des),this.localvar[f]=vv}tm=this.valid,this.valid=[];for(const t of tm){let p=getcouple(t,",");p={v:p.v,msg:p.o},p.v&&(p.v.startsWith("#")?this.formula[p.v.substring(1)]&&this.valid.push(p):this.valid.push(p))}tm=lochead;const head=[];for(const t of tm){const rr=/^\s*([\w\-_]+)+[;,\s]\s*(.*)?$/im.exec(t);if(rr){const pp=getcolonne(rr[2]),c=clean(rr[1]);let ht;if(c){ht=head.find((e=>e.cod==c)),ht||(ht={cod:c,t:"t"},head.push(ht));for(const tp of pp){const p=getcouple(tp);switch(p.v){case"t":ht.t=p.o;break;case"def":case"default":ht.def=p.o;break;case"valid":case"colonna":case"hidden":p.o.startsWith("#")?this.formula[p.o.substring(1)]&&(ht[p.v]=p.o):ht[p.v]=p.o;break;default:ht[p.v]=p.o}}}}}this.head=head,tm=this.genera;const genera={};for(const kk in tm)if(Array.isArray(tm[kk])){const gen={codice:[],head:"",calcola:[],bom:[],vars:[],exclude:[]},regx=/^\s*[!:]\s*(\w+)\s*(.*)$/i;for(const k2 of tm[kk]){const rr=regx.exec(clean(k2));if(rr)switch(rr[1]){case"calcola":case"c":gen.calcola=[...gen.calcola,...getcolonne(rr[2])];break;case"exclude":case"e":case"escludi":gen.exclude=[...gen.exclude,...getcolonne(rr[2])];break;case"bom":case"db":gen.bom=[...gen.bom,...getcolonne(rr[2])];break;case"vars":case"v":gen.vars=[...gen.vars,...getcolonne(rr[2])];break;case"head":case"h":gen.head=getcolonne(rr[2]);break;default:this.errori.push(`genera ${kk} => ${k2}`)}else gen.codice.push(k2)}gen.codice=muClean(gen.codice,!0),genera[kk]=gen}this.genera=genera}cleanfiltraparametri(key,codice,acapo){if(this.paralias||(this.paralias={}),codice&&codice.length){let fl=!1;const getparalias=dati=>{const cl=[],co=getcolonne(dati);for(const c of co)if(c.includes(":")){const v=c.split(":");this.paralias[v[0]]=v[1],cl.push(v[0])}else cl.push(c);return cl};for(let i=0;i<codice.length;i++){const rr=/^:p[;,\s]+(.*)?$/im.exec(codice[i]);if(rr)codice[i]=null,fl=!0,this.parametri[key]=getparalias(rr[1]);else{const rr=/^!(parametri|pars|p)[;,\s]+(.*)?$/im.exec(codice[i]);rr&&(codice[i]=null,fl=!0,this.parametri[key]=getparalias(rr[2]))}}fl&&(codice=codice.filter((e=>null!=e)))}return codice=muClean(codice,acapo)}}function parsevariabili(text){let fl=!1;const tk=[];for(;;){const m=/\$([{[(])/m.exec(text);if(!m){text&&fl&&tk.push({class:"",text:text});break}{fl=!0;const classe="["==m[1]?"inline":"variabile";m.index>0&&tk.push({class:"",text:text.substring(0,m.index)});const{i:i}=parsevar(text,m.index+2,m[1],null);if(!(i>m.index)){tk.push({class:classe,text:text.substring(m.index)});break}tk.push({class:classe,text:text.substring(m.index,i+1)}),text=text.substring(i+1)}}return{fl:fl,tk:tk}}function parseexp(text,exp,callback){if(!callback)throw new Error("missing callback");let fl=!1;const tk=[];for(;;){const m=exp.exec(text);if(!m){text&&fl&&tk.push({class:"",text:text});break}m.index>0&&tk.push({class:"",text:text.substring(0,m.index)}),tk.push(...callback(m)),fl=!0,text=text.substring(m.index+m[0].length)}return{fl:fl,tk:tk}}
@@ -265,4 +265,4 @@ this.imgpreview={},this.vari=new Variabile,this.ruleset={},this.fndotcallback&&t
265
265
  /** @type {Object.<string, Macro>} */
266
266
  this.macro={},
267
267
  /** @type {Object.<string, Variante>} */
268
- this.varianti={},this.varelenco={},this.macroelenco={},this.scripts={},this.#headers=void 0,this.#alias=void 0,this.#deriva=void 0,this.#typos=void 0)}setimgpreview(cod,img){img?this.imgpreview[cod]=img:delete this.imgpreview[cod]}getimgpreview(cod){return this?.imgpreview[cod||""]}setfndot(fndotcallback){this.fndotcallback=fndotcallback,this.vari.setfndot(fndotcallback)}async#checkelencovar(cat){if(cbInfo&&!this.varelenco[cat]){const tm=await cbInfo("headers",cat,"_varianti");Array.isArray(tm)?this.varelenco[cat]=tm:tm.vars&&(this.varelenco[cat]=tm.vars,tm.alias&&(this.#alias=tm.alias)),this.varelenco[cat]||(this.varelenco[cat]=[])}}parseheaderfrominfo(tm){if(tm&&tm.length>0)for(const t of tm)switch(t.tipo){case"_headers":"string"==typeof t.value&&(t.value=headerconvert(t.value)),this.#headers=t.value||{};break;case"_alias":"string"==typeof t.value&&(t.value=aliasconvert(t.value)),this.#alias=t.value||{};break;case"_typos":if("string"==typeof t.value){const tips=fromjson(t.value);for(const tp in tips){const tq=tips[tp];tq.db&&(tq.db=muClean(muClComments(tq.db))),tq.list&&(tq.list=muClean(muClComments(tq.list)))}t.value=tips}this.#typos=t.value||{}}}setitem(item,rule,model,ruleset=[],datadelgiorno=0){this.item=clean(item,!0),this.rule=clean(rule,!0),this.model=clean(model,!0),this.ruleset=toruleset(ruleset),this.data=datadelgiorno||(new Date).toInt()}async getheader(cod){let tm;return!this.#headers&&cbInfo&&(tm=await cbInfo("headers",this.cat,"_headers"),this.parseheaderfrominfo(tm)),this.#headers||(this.#headers={}),this.#headers[cod]}async getalias(){let tm;return!this.#alias&&cbInfo&&(tm=await cbInfo("headers",this.cat,"_alias"),this.parseheaderfrominfo(tm)),this.#alias||(this.#alias={}),this.#alias}get deriva(){return this.#deriva,this.#deriva||[]}async getmacro(riga){try{if("string"==typeof riga&&(riga={tipo:"M",contenuto:riga}),!riga||!riga.contenuto)return;let ct=riga.contenuto;ct.startsWith("$")&&(ct=await this.vari.valuta(ct));const rr=/^([({}):$\w.\\/]+)[\s;,]*(.*)?$/im.exec(ct);if(!rr)return void errori.add("Macro non valida:"+ct,riga);let macro=clean(rr[1],!0);macro.includes("$")&&(macro=await this.vari.valuta(macro));const pars=getcolonne(rr[2]),{name:name,cat:cat}=checkmu(macro,this.cat);this.cat=cat;const ky=`${cat}/${name}`;if(!this.macro[ky]){const tm=new Macro(this,name);await tm.load()?this.macro[ky]=tm:errori.add(`macro fail to load ${ky}`,riga)}return macro=this.macro[ky],macro?{macro:macro,pars:pars}:(errori.add(`macro non trovata ${ky}`,riga),{})}catch(error){errori.add(geterrdes(error),`ambiente.getmacro: ${riga?.contenuto}`)}}async getvariante(cod){const{name:name,cat:cat}=checkmu(cod,this.cat);let n2=name,altri={};if(cat==this.cat&&this.#alias&&this.#alias[name]&&(altri=this.#alias[name]||{},n2=altri.cod),await this.#checkelencovar(cat),this.varelenco[cat]&&!this.varelenco[cat].includes(name))return;const key=`${cat}/${n2}`;let vv;return this.varianti[key]?vv=this.varianti[key]:(vv=new Variante(this),await vv.load(key,cat),this.varianti[key]=vv),altri&&(altri.des&&(vv.des=altri.des),altri.vdef&&(vv.vdef=altri.vdef)),vv}async varcompila(v,callback){const xx=new Variante(this);if(await xx.load(v,this.cat,!0),xx.alias){(await this.getalias())[v]=xx.alias}callback("variants",{cod:v,des:xx.des||"",alias:xx.alias,info:xx.alias?"":JSON.stringify(getOggetto(xx,["amb"]))})}async macrocompila(v,callback){const mac=new Macro(this,v);await mac.loadAndCompile(`${v}.mu`);const t=mac.getmacro();callback("macros",{cod:v,info:JSON.stringify(t),isgenera:mac.isgenera,isheader:mac.isheader,iscodice:mac.iscodice})}async barrecompila(articolibarre,titolibarre,callback){const cc=new CodiceBarra;await cc.compila(articolibarre,titolibarre);for(const x in cc.barre){callback("barcodes",{cod:x,des:"",info:JSON.stringify(cc.barre[x])})}return cc}async tojson(d){let tm;return cbFunc&&(tm=await cbFunc("json",d)),tm}async compila(info,callback){if(callback){for(const v of info.var)await this.varcompila(v,callback);for(const v of info.mu)await this.macrocompila(v,callback);if(callback("infos",{cod:"info",des:info.cat,info:JSON.stringify({cat:info.cat,md:info.info})}),this.#headers=void 0,this.#alias=void 0,this.#deriva=void 0,this.#typos=void 0,cbInfo){const tm=await cbInfo("headers",this.cat,["_headers","_alias","_deriva","_typos"]);this.parseheaderfrominfo(tm)}this.#headers?callback("infos",{cod:"headers",des:"",info:JSON.stringify(this.#headers)}):logga("missing headers"),this.#alias&&callback("infos",{cod:"alias",des:"",info:JSON.stringify(this.#alias)}),this.#deriva&&callback("infos",{cod:"deriva",des:"",info:JSON.stringify(this.#deriva)}),this.#typos&&callback("infos",{cod:"typos",des:"tipologie",info:JSON.stringify(this.#typos)})}}async checkvarianti(cat,vars){if(!cat||!vars?.length)return;cat=checkname(cat),await this.#checkelencovar(cat);const t=this.varelenco[cat],vn=[];for(let v of vars){v=clean(v,!0);const nn=`${cat}/${v}`;this.varianti[nn]||t&&t.includes(v)&&vn.push(v)}if(vn.length&&cbGetVariante){const xv=await cbGetVariante(cat,vn);if(xv&&xv.length)for(const x of xv){const{name:name,content:content}=x,vv=new Variante(this);vv.setheader(name,cat),content&&await vv.loadContentExtended(content),this.varianti[vv.key]=vv}}}async getheaderfromdb(name){const totale=await cbInfo("header",this.cat,name,!this.#deriva);let{head:head,rows:rows,macros:macros,deriva:deriva,llvars:llvars}=totale;for(const r of rows)r.cod=clean(r.cod),r.alias=clean(r.alias),r.t=clean(r.t);if(!llvars){llvars=new Set;for(const r of rows)if("p"==r.tipo);else{const nn=r.alias?r.alias:r.cod;llvars.add(nn)}llvars=[...llvars]}this.#deriva||(this.#deriva=deriva),await this.#checkelencovar(this.cat),head.cod=clean(head.cod),head.rule=clean(head.rule),head.ruledef=head.ruledef||[];const vn=[],t=this.varelenco[this.cat];for(const nn of llvars)this.varianti[`${this.cat}/${nn}`]||t&&t.includes(nn)&&vn.push(nn);if(vn.length&&cbGetVariante){const vars=await cbGetVariante(this.cat,vn);if(vars&&vars.length)for(const x of vars){const{name:name,content:content}=x,vv=new Variante(this);vv.setheader(name,this.cat),content&&await vv.loadContentExtended(content),this.varianti[vv.key]=vv}}return{head:head,rows:rows,macros:macros}}async getlinkedmacros(rule,macros){const getkey=n=>n.includes("/")?n:`${this.cat}/${n}`,cl=[];let k;if(rule&&(k=getkey(rule),this.macro[k]||cl.push(rule)),macros&&"string"==typeof macros){const vv=macros.split(";");for(const v of vv)k=getkey(v),this.macro[k]||cl.push(v)}if(cl&&cl.length>0&&cbGetMacro){const tm=await cbGetMacro(this.cat,cl);if(tm&&tm.length>0)for(const x of tm){this.checkscripts(x.content?.linkscript),delete x.content?.linkscript;const m=new Macro(this,x.name);for(const t in x.content){const contenuto=x.content[t];m[t]=contenuto}this.macro[m.key]=m}}}checkscripts(vv){if(vv&&vv.length)for(let v of vv)this.scripts[v.name]||(this.scripts[v.name]=v.value)}async setruleheader(rule,pars,ruleset){const{name:name,cat:cat}=checkmu(rule,this.cat);ruleset&&ruleset.length&&(this.ruleset=toruleset(ruleset));const ky=`${cat}/${name}`;if(!this.macro[ky]){const totale=await this.getheaderfromdb(name),{head:head,rows:rows,macros:macros}=totale;await this.getlinkedmacros(head.rule,macros);const tm=new Macro(this,name);if(!head)return void errori.add("Missing rule: "+rule);if(head.rule){const k2=this.macro[`${cat}/${head.rule}`];if(k2)for(const x in k2)["cat","name","key"].includes(x)||(tm[x]=k2[x])}rows&&rows.length&&(tm.head=rows),this.macro[ky]=tm}this.ruleheader=ky;const mc=this.macro[ky];return errori.azzera(),await mc.setparametri(pars),mc}getruleheader(){return this.macro[this.ruleheader]}async setvariante(cod,opz){return await impostavariante(this,null,cod,opz)}async valuta(codice){let output;return"string"==typeof codice&&(codice=muClean(muClComments(codice,this.righevuote))),Array.isArray(codice)&&(logga("m1",codice),output=await muEval(this,null,codice)),output}setinfos(tm){tm&&(this.#headers=tm.headers,this.#alias=tm.alias,this.#deriva=void 0,this.#typos=tm.typos)}async splitteroggetti(name){let data=await this.getvariante(name),cl=[];return data?.rows&&Object.values(data.rows).forEach((v=>{cl.push({tipo:v.v[2]||"",cod:v.v[0]||"",des:v.v[1]||"",macro:v.v[4]||"",sps:parseInt(v.v[3])||0,isshape:parseInt(v.v[5])})})),cl.length||cl.push({tipo:"avob",cod:"__",des:"Vuoto",macro:"",sps:0}),cl}}function toJson(t){return JSON.stringify(t,null,2)}function clamp(n,min=-1/0,max=1/0){return(n=Number(n)||0)<min&&(n=min),n>max&&(n=max),n}function gettipocolonna(cod){return tipicolonna.find((x=>x.cod==cod))?.des||tipicolonna[0].des}function gettipofolder(cod){return tipicolonna.find((x=>x.cod==cod))?.folder||""}function newVariabile(){return new Variabile}async function newVariante(cod,cat,amb){const xx=new Variante(amb);return await xx.load(cod,cat),xx}function newAmbiente(cat,maxmillis=100){return new Ambiente(cat,maxmillis)}function newMacro(amb,name){return new Macro(amb,name)}function muValuta(mu,codice,azzera){azzera&&mu.azzera();return mu.valuta(codice)}function muInit(cat,cbGetMacro,cbGetVariante,cbFunc,cbInfo,cbGetFile,cbLogga){const mu=new Ambiente(cat);return setcallbacks(cbGetMacro,cbGetVariante,cbFunc,cbInfo,cbGetFile,cbLogga),mu}function muCompileScript(codice){return codice&&"object"==typeof codice?codice:codice.startsWith("{")&&codice.endsWith("}")||codice.startsWith("[")&&codice.endsWith("]")?JSON.stringify(codice):muClean(muClComments(codice))}async function muEvalScript(/** @type {Ambiente} */amb,codice,pars,reset=!0){if(codice=muCompileScript(codice),reset&&amb.azzera(),pars)for(const p of pars){const{v:v,o:o}=getcouple(p);amb.vari.add(v,o)}return{output:await muEval(amb,null,codice,{}),vari:amb.vari.dictionary,errori:errori}}const tonum=(s,dec=-1)=>{if(!s)return 0;let n=0;if("number"==typeof s)n=s||0;else if("string"==typeof s){const x=(s=s.replaceAll(",",".")).match(/^-?[0-9.]+$/);n=x&&x.length>0?Number(x[0])||0:muCalc(s)}if(dec>=0)switch(dec){case 0:n=Math.round(n);break;case 1:n=Math.round(10*n)/10;break;case 2:n=Math.round(100*n)/100;break;case 3:n=Math.round(1e3*n)/1e3;break;case 4:n=Math.round(1e4*n)/1e4;break;case 5:n=Math.round(1e5*n)/1e5;break;case 6:n=Math.round(1e6*n)/1e6}return n||0};Date.prototype.toInt||(Date.prototype.toInt=function(){return this.getDate()+100*(this.getMonth()+1)+1e4*this.getFullYear()}),Date.prototype.toFloat||(Date.prototype.toFloat=function(){return Math.floor(1e4*this.getDate()+1e6*(this.getMonth()+1)+1e8*this.getFullYear()+100*this.getHours()+this.getMinutes()+.5)/1e4});const mustr={mus:{variants:{cod:"s",des:"s",alias:"s",info:"s",md:"s",__pk:"cod"},extras:{tipo:"s",cod:"s",info:"s",__pk:"tipo, cod"},macros:{cod:"s",des:"s",info:"s",md:"s",def:"s",isgenera:"i",iscodice:"i",isheader:"i",__pk:"cod"},infos:{cod:"s",des:"s",info:"s",__pk:"cod"},barcodes:{cod:"s",des:"s",info:"s",__pk:"cod"}}};export{Ambiente,CodiceBarra,Macro,Variabile,Variante,checkmu,checkname,clamp,clean,dammivariante,errori,fromjson,getOggetto,getcolonne,getcouple,geterrdes,getheaddims,gettipocolonna,gettipofolder,hash,impostavariante,intvaluta,isJsonStr,isObject,muInit as jsTest,logga,muCalc,muClComments,muClean,muCompileScript,muEval,muEvalScript,muGenerate,muInit,muLimits,muParsecode,muValuta,mustr,newAmbiente,newMacro,newVariabile,newVariante,noquote,parselimitifromdb,parselimitifromrule,parsevar,poppars,pushpars,quote,setOggetto,sortrows,testsync,tipicolonna,tipifree,tipiheader,tk,toCadPars,toJson,tonum,xdt};
268
+ this.varianti={},this.varelenco={},this.macroelenco={},this.scripts={},this.#headers=void 0,this.#alias=void 0,this.#deriva=void 0,this.#typos=void 0)}setimgpreview(cod,img){img?this.imgpreview[cod]=img:delete this.imgpreview[cod]}getimgpreview(cod){return this?.imgpreview[cod||""]}setfndot(fndotcallback){this.fndotcallback=fndotcallback,this.vari.setfndot(fndotcallback)}async#checkelencovar(cat){if(cbInfo&&!this.varelenco[cat]){const tm=await cbInfo("headers",cat,"_varianti");Array.isArray(tm)?this.varelenco[cat]=tm:tm.vars&&(this.varelenco[cat]=tm.vars,tm.alias&&(this.#alias=tm.alias)),this.varelenco[cat]||(this.varelenco[cat]=[])}}parseheaderfrominfo(tm){if(tm&&tm.length>0)for(const t of tm)switch(t.tipo){case"_headers":"string"==typeof t.value&&(t.value=headerconvert(t.value)),this.#headers=t.value||{};break;case"_alias":"string"==typeof t.value&&(t.value=aliasconvert(t.value)),this.#alias=t.value||{};break;case"_typos":if("string"==typeof t.value){const tips=fromjson(t.value);for(const tp in tips){const tq=tips[tp];tq.db&&(tq.db=muClean(muClComments(tq.db))),tq.list&&(tq.list=muClean(muClComments(tq.list)))}t.value=tips}this.#typos=t.value||{}}}setitem(item,rule,model,ruleset=[],datadelgiorno=0){this.item=clean(item,!0),this.rule=clean(rule,!0),this.model=clean(model,!0),this.ruleset=toruleset(ruleset),this.data=datadelgiorno||(new Date).toInt()}async getheader(cod){let tm;return!this.#headers&&cbInfo&&(tm=await cbInfo("headers",this.cat,"_headers"),this.parseheaderfrominfo(tm)),this.#headers||(this.#headers={}),this.#headers[cod]}async getalias(){let tm;return!this.#alias&&cbInfo&&(tm=await cbInfo("headers",this.cat,"_alias"),this.parseheaderfrominfo(tm)),this.#alias||(this.#alias={}),this.#alias}get deriva(){return this.#deriva,this.#deriva||[]}async getmacro(riga){try{if("string"==typeof riga&&(riga={tipo:"M",contenuto:riga}),!riga||!riga.contenuto)return;let ct=riga.contenuto;ct.startsWith("$")&&(ct=await this.vari.valuta(ct));const rr=/^([({}):$\w.\\/]+)[\s;,]*(.*)?$/im.exec(ct);if(!rr)return void errori.add("Macro non valida:"+ct,riga);let macro=clean(rr[1],!0);macro.includes("$")&&(macro=await this.vari.valuta(macro));const pars=getcolonne(rr[2]),{name:name,cat:cat}=checkmu(macro,this.cat);this.cat=cat;const ky=`${cat}/${name}`;if(!this.macro[ky]){const tm=new Macro(this,name);await tm.load()?this.macro[ky]=tm:errori.add(`macro fail to load ${ky}`,riga)}return macro=this.macro[ky],macro?{macro:macro,pars:pars}:(errori.add(`macro non trovata ${ky}`,riga),{})}catch(error){errori.add(geterrdes(error),`ambiente.getmacro: ${riga?.contenuto}`)}}async getvariante(cod){const{name:name,cat:cat}=checkmu(cod,this.cat);let n2=name,altri={};if(cat==this.cat&&this.#alias&&this.#alias[name]&&(altri=this.#alias[name]||{},n2=altri.cod),await this.#checkelencovar(cat),this.varelenco[cat]&&!this.varelenco[cat].includes(name))return;const key=`${cat}/${n2}`;let vv;return this.varianti[key]?vv=this.varianti[key]:(vv=new Variante(this),await vv.load(key,cat),this.varianti[key]=vv),altri&&(altri.des&&(vv.des=altri.des),altri.vdef&&(vv.vdef=altri.vdef)),vv}async varcompila(v,callback){const xx=new Variante(this);if(await xx.load(v,this.cat,!0),xx.alias){(await this.getalias())[v]=xx.alias}callback("variants",{cod:v,des:xx.des||"",alias:xx.alias,info:xx.alias?"":JSON.stringify(getOggetto(xx,["amb"]))})}async macrocompila(v,callback){const mac=new Macro(this,v);await mac.loadAndCompile(`${v}.mu`);const t=mac.getmacro();callback("macros",{cod:v,info:JSON.stringify(t),isgenera:mac.isgenera,isheader:mac.isheader,iscodice:mac.iscodice})}async barrecompila(articolibarre,titolibarre,callback){const cc=new CodiceBarra;await cc.compila(articolibarre,titolibarre);for(const x in cc.barre){callback("barcodes",{cod:x,des:"",info:JSON.stringify(cc.barre[x])})}return cc}async tojson(d){let tm;return cbFunc&&(tm=await cbFunc("json",d)),tm}async compila(info,callback){if(callback){for(const v of info.var)await this.varcompila(v,callback);for(const v of info.mu)await this.macrocompila(v,callback);if(callback("infos",{cod:"info",des:info.cat,info:JSON.stringify({cat:info.cat,md:info.info})}),this.#headers=void 0,this.#alias=void 0,this.#deriva=void 0,this.#typos=void 0,cbInfo){const tm=await cbInfo("headers",this.cat,["_headers","_alias","_deriva","_typos"]);this.parseheaderfrominfo(tm)}this.#headers?callback("infos",{cod:"headers",des:"",info:JSON.stringify(this.#headers)}):logga("missing headers"),this.#alias&&callback("infos",{cod:"alias",des:"",info:JSON.stringify(this.#alias)}),this.#deriva&&callback("infos",{cod:"deriva",des:"",info:JSON.stringify(this.#deriva)}),this.#typos&&callback("infos",{cod:"typos",des:"tipologie",info:JSON.stringify(this.#typos)})}}async checkvarianti(cat,vars){if(!cat||!vars?.length)return;cat=checkname(cat),await this.#checkelencovar(cat);const t=this.varelenco[cat],vn=[];for(let v of vars){v=clean(v,!0);const nn=`${cat}/${v}`;this.varianti[nn]||t&&t.includes(v)&&vn.push(v)}if(vn.length&&cbGetVariante){const xv=await cbGetVariante(cat,vn);if(xv&&xv.length)for(const x of xv){const{name:name,content:content}=x,vv=new Variante(this);vv.setheader(name,cat),content&&await vv.loadContentExtended(content),this.varianti[vv.key]=vv}}}async getheaderfromdb(name){const totale=await cbInfo("header",this.cat,name,!this.#deriva);let{head:head,rows:rows,macros:macros,deriva:deriva,llvars:llvars}=totale;for(const r of rows)r.cod=clean(r.cod),r.alias=clean(r.alias),r.t=clean(r.t);if(!llvars){llvars=new Set;for(const r of rows)if("p"==r.tipo);else{const nn=r.alias?r.alias:r.cod;llvars.add(nn)}llvars=[...llvars]}this.#deriva||(this.#deriva=deriva),await this.#checkelencovar(this.cat),head.cod=clean(head.cod),head.rule=clean(head.rule),head.ruledef=head.ruledef||[];const vn=[],t=this.varelenco[this.cat];for(const nn of llvars)this.varianti[`${this.cat}/${nn}`]||t&&t.includes(nn)&&vn.push(nn);if(vn.length&&cbGetVariante){const vars=await cbGetVariante(this.cat,vn);if(vars&&vars.length)for(const x of vars){const{name:name,content:content}=x,vv=new Variante(this);vv.setheader(name,this.cat),content&&await vv.loadContentExtended(content),this.varianti[vv.key]=vv}}return{head:head,rows:rows,macros:macros}}async getlinkedmacros(rule,macros){const getkey=n=>n.includes("/")?n:`${this.cat}/${n}`,cl=[];let k;if(rule&&(k=getkey(rule),this.macro[k]||cl.push(rule)),macros&&"string"==typeof macros){const vv=macros.split(";");for(const v of vv)k=getkey(v),this.macro[k]||cl.push(v)}if(cl&&cl.length>0&&cbGetMacro){const tm=await cbGetMacro(this.cat,cl);if(tm&&tm.length>0)for(const x of tm){this.checkscripts(x.content?.linkscript),delete x.content?.linkscript;const m=new Macro(this,x.name);for(const t in x.content){const contenuto=x.content[t];m[t]=contenuto}this.macro[m.key]=m}}}checkscripts(vv){if(vv&&vv.length)for(let v of vv)this.scripts[v.name]||(this.scripts[v.name]=v.value)}async setruleheader(rule,pars,ruleset){const{name:name,cat:cat}=checkmu(rule,this.cat);ruleset&&ruleset.length&&(this.ruleset=toruleset(ruleset));const ky=`${cat}/${name}`;if(!this.macro[ky]){const totale=await this.getheaderfromdb(name),{head:head,rows:rows,macros:macros}=totale;await this.getlinkedmacros(head.rule,macros);const tm=new Macro(this,name);if(!head)return void errori.add("Missing rule: "+rule);if(head.rule){const k2=this.macro[`${cat}/${head.rule}`];if(k2)for(const x in k2)["cat","name","key"].includes(x)||(tm[x]=k2[x])}rows&&rows.length&&(tm.head=rows),this.macro[ky]=tm}this.ruleheader=ky;const mc=this.macro[ky];return errori.azzera(),await mc.setparametri(pars),mc}getruleheader(){return this.macro[this.ruleheader]}async setvariante(cod,opz){return await impostavariante(this,null,cod,opz)}async valuta(codice){let output;return"string"==typeof codice&&(codice=muClean(muClComments(codice,this.righevuote))),Array.isArray(codice)&&(logga("m1",codice),output=await muEval(this,null,codice)),output}setinfos(tm){tm&&(this.#headers=tm.headers,this.#alias=tm.alias,this.#deriva=void 0,this.#typos=tm.typos)}async splitteroggetti(name){let data=await this.getvariante(name),cl=[];return data?.rows&&Object.values(data.rows).forEach((v=>{cl.push({tipo:v.v[2]||"",cod:v.v[0]||"",des:v.v[1]||"",macro:v.v[4]||"",sps:parseInt(v.v[3])||0,isshape:parseInt(v.v[5])})})),cl.length||cl.push({tipo:"avob",cod:"__",des:"Vuoto",macro:"",sps:0}),cl}}function toJson(t){return JSON.stringify(t,null,2)}function clamp(n,min=-1/0,max=1/0){return(n=Number(n)||0)<min&&(n=min),n>max&&(n=max),n}function gettipocolonna(cod){return tipicolonna.find((x=>x.cod==cod))?.des||tipicolonna[0].des}function gettipofolder(cod){return tipicolonna.find((x=>x.cod==cod))?.folder||""}function newVariabile(){return new Variabile}async function newVariante(cod,cat,amb){const xx=new Variante(amb);return await xx.load(cod,cat),xx}function newAmbiente(cat,maxmillis=100){return new Ambiente(cat,maxmillis)}function newMacro(amb,name){return new Macro(amb,name)}function muValuta(mu,codice,azzera){azzera&&mu.azzera();return mu.valuta(codice)}function muInit(cat,cbGetMacro,cbGetVariante,cbFunc,cbInfo,cbGetFile,cbLogga){const mu=new Ambiente(cat);return setcallbacks(cbGetMacro,cbGetVariante,cbFunc,cbInfo,cbGetFile,cbLogga),mu}function muCompileScript(codice){return codice&&"object"==typeof codice?codice:codice.startsWith("{")&&codice.endsWith("}")||codice.startsWith("[")&&codice.endsWith("]")?JSON.stringify(codice):muClean(muClComments(codice))}async function muEvalScript(/** @type {Ambiente} */amb,codice,pars,reset=!0){if(codice=muCompileScript(codice),reset&&amb.azzera(),pars)for(const p of pars){const{v:v,o:o}=getcouple(p);amb.vari.add(v,o)}return{output:await muEval(amb,null,codice,{}),vari:amb.vari.dictionary,errori:errori}}const tonum=(s,dec=-1)=>{if(!s)return 0;let n=0;if("number"==typeof s)n=s||0;else if("string"==typeof s){const x=(s=s.replaceAll(",",".")).match(/^-?[0-9.]+$/);n=x&&x.length>0?Number(x[0])||0:muCalc(s)}if(dec>=0)switch(dec){case 0:n=Math.round(n);break;case 1:n=Math.round(10*n)/10;break;case 2:n=Math.round(100*n)/100;break;case 3:n=Math.round(1e3*n)/1e3;break;case 4:n=Math.round(1e4*n)/1e4;break;case 5:n=Math.round(1e5*n)/1e5;break;case 6:n=Math.round(1e6*n)/1e6}return n||0};Date.prototype.toInt||(Date.prototype.toInt=function(){return this.getDate()+100*(this.getMonth()+1)+1e4*this.getFullYear()}),Date.prototype.toFloat||(Date.prototype.toFloat=function(){return Math.floor(1e4*this.getDate()+1e6*(this.getMonth()+1)+1e8*this.getFullYear()+100*this.getHours()+this.getMinutes()+.5)/1e4});const mustr={mus:{variants:{cod:"s",des:"s",alias:"s",info:"s",md:"s",__pk:"cod"},extras:{tipo:"s",cod:"s",info:"s",__pk:"tipo, cod"},macros:{cod:"s",des:"s",info:"s",md:"s",def:"s",isgenera:"i",iscodice:"i",isheader:"i",__pk:"cod"},infos:{cod:"s",des:"s",info:"s",__pk:"cod"},barcodes:{cod:"s",des:"s",info:"s",__pk:"cod"}}};export{Ambiente,CodiceBarra,Macro,Variabile,Variante,checkmu,checkname,clamp,clean,dammivariante,errori,fromjson,getOggetto,getcolonne,getcouple,geterrdes,getheaddims,gettipocolonna,gettipofolder,hash,impostavariante,intvaluta,isJsonStr,isObject,muInit as jsTest,logga,muCalc,muClComments,muClean,muCompileScript,muEval,muEvalScript,muGenerate,muInit,muLimits,muParsecode,muValuta,mustr,newAmbiente,newMacro,newVariabile,newVariante,noquote,parselimitifromdb,parselimitifromrule,parsevar,poppars,pushpars,quote,seeder,setOggetto,sortrows,testsync,tipicolonna,tipifree,tipiheader,tk,toCadPars,toJson,tonum,xdt};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markuno_lib",
3
- "version": "1.2.64",
3
+ "version": "1.2.66",
4
4
  "description": "Croswil Markuno Language Lib",
5
5
  "author": "Croswil SRL",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -18,7 +18,8 @@
18
18
  /**
19
19
  * Calcola la differenza delle coordinate x dei punti
20
20
  * @returns {number} Differenza x
21
- */ get dx(): number;
21
+ */ get angle(): number;
22
+ get dx(): number;
22
23
  /**
23
24
  * Calcola la differenza delle coordinate y dei punti
24
25
  * @returns {number} Differenza y
@@ -31,7 +32,6 @@
31
32
  * Calcola la lunghezza della linea
32
33
  * @returns {number} Lunghezza
33
34
  */ get len(): number;
34
- get angle(): number;
35
35
  /**
36
36
  * Estende la linea di una certa lunghezza o fino all'intersezione con un'altra linea
37
37
  * @param {number|Linea2} l - Lunghezza di estensione o linea da intersecare
@@ -309,6 +309,7 @@ export class Vis2d {
309
309
  }
310
310
  export class Vobject {
311
311
  constructor(o: any);
312
+ get lines(): any;
312
313
  fromjson(o: any): void;
313
314
  id: any;
314
315
  layer: any;
@@ -317,7 +318,7 @@ export class Vobject {
317
318
  y: any;
318
319
  pc: any;
319
320
  shape: any;
320
- lines: any;
321
+ _lines: any;
321
322
  draw: Vis2d;
322
323
  info: any;
323
324
  pos: any;
@@ -348,7 +349,7 @@ export class Vscene {
348
349
  clear(): void;
349
350
  curlayer: any;
350
351
  rows: any;
351
- clines: any;
352
+ clines: any[];
352
353
  fromjson(o: any): void;
353
354
  tojson(): {
354
355
  x: any;
@@ -676,7 +677,7 @@ export const scaleunit: 0.001;
676
677
  export function setLineColorMode(white: any, isdark: any): void;
677
678
  export function setorigine(obj: any, x?: number, y?: number, z?: number): any;
678
679
  export function shapeclip(): {
679
- offset(shape: any, delta: any, full?: boolean): any;
680
+ offset(shape: any, delta: any): any;
680
681
  inflate: (shape: any, delta?: number, mantainorder?: boolean, isopen?: number) => any;
681
682
  inflateopen: (pts: any, delta: any) => any;
682
683
  inflateclose(shape: any, delta: any): any;
@@ -530,6 +530,7 @@ export function pushpars(amb: any, macro: any, parsfunzione: any, parsinit: any)
530
530
  o: any;
531
531
  }[]>;
532
532
  export function quote(v: any): any;
533
+ export function seeder(n: any, seed?: string): number;
533
534
  /**
534
535
  * Classe per la gestione degli errori con funzionalità di accumulo e formattazione
535
536
  */