pantograph2d 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{QuadraticBezier-B2g_Iyyl.js → QuadraticBezier-BeY2TXKH.js} +464 -433
- package/dist/QuadraticBezier-BeY2TXKH.js.map +1 -0
- package/dist/{QuadraticBezier-CuRsIP_D.cjs → QuadraticBezier-eSR75IzC.cjs} +9 -9
- package/dist/QuadraticBezier-eSR75IzC.cjs.map +1 -0
- package/dist/draw-BmJ8wIc9.cjs +2 -0
- package/dist/draw-BmJ8wIc9.cjs.map +1 -0
- package/dist/{draw-BJW5kfm9.js → draw-DzKVhurb.js} +94 -89
- package/dist/draw-DzKVhurb.js.map +1 -0
- package/dist/{models-DdZq-waE.js → models-BHeLX0dj.js} +544 -527
- package/dist/models-BHeLX0dj.js.map +1 -0
- package/dist/models-Fv9xfQBT.cjs +4 -0
- package/dist/models-Fv9xfQBT.cjs.map +1 -0
- package/dist/pantograph/drawShape.cjs +1 -1
- package/dist/pantograph/drawShape.js +2 -2
- package/dist/pantograph/models.cjs +1 -1
- package/dist/pantograph/models.js +2 -2
- package/dist/pantograph/svg.cjs +1 -1
- package/dist/pantograph/svg.js +1 -1
- package/dist/pantograph.cjs +2 -2
- package/dist/pantograph.cjs.map +1 -1
- package/dist/pantograph.js +83 -83
- package/dist/pantograph.js.map +1 -1
- package/dist/svg-BTO7h1ix.js +62 -0
- package/dist/svg-BTO7h1ix.js.map +1 -0
- package/dist/svg-b6SOnbda.cjs +8 -0
- package/dist/svg-b6SOnbda.cjs.map +1 -0
- package/dist/types/src/algorithms/offsets/offsetSegment.d.ts +1 -0
- package/dist/types/src/models/BoundingBox.d.ts +1 -0
- package/dist/types/src/models/Diagram.d.ts +1 -0
- package/dist/types/src/models/Figure.d.ts +1 -0
- package/dist/types/src/models/Loop.d.ts +1 -0
- package/dist/types/src/models/Strand.d.ts +5 -0
- package/dist/types/src/models/TransformationMatrix.d.ts +1 -0
- package/dist/types/src/models/segments/Arc.d.ts +1 -0
- package/dist/types/src/models/segments/CubicBezier.d.ts +1 -0
- package/dist/types/src/models/segments/EllipseArc.d.ts +1 -0
- package/dist/types/src/models/segments/Line.d.ts +2 -0
- package/dist/types/src/models/segments/QuadraticBezier.d.ts +1 -0
- package/dist/types/src/tesselationOperations.d.ts +4 -4
- package/package.json +2 -2
- package/dist/QuadraticBezier-B2g_Iyyl.js.map +0 -1
- package/dist/QuadraticBezier-CuRsIP_D.cjs.map +0 -1
- package/dist/draw-9Elv4xz6.cjs +0 -2
- package/dist/draw-9Elv4xz6.cjs.map +0 -1
- package/dist/draw-BJW5kfm9.js.map +0 -1
- package/dist/models-DdZq-waE.js.map +0 -1
- package/dist/models-LHGiMarC.cjs +0 -4
- package/dist/models-LHGiMarC.cjs.map +0 -1
- package/dist/svg-BzloQ9l1.cjs +0 -8
- package/dist/svg-BzloQ9l1.cjs.map +0 -1
- package/dist/svg-D8vwkQf7.js +0 -62
- package/dist/svg-D8vwkQf7.js.map +0 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";var Ut=Object.defineProperty;var $t=(t,n,e)=>n in t?Ut(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var A=(t,n,e)=>$t(t,typeof n!="symbol"?n+"":n,e);const l=require("./QuadraticBezier-eSR75IzC.cjs");function Et(t,n){const e=l.subtract(n,t.firstPoint),s=l.dotProduct(e,t.V)/t.squareLength;return t.paramPoint(s)}function D(t,n,e){const s=e||t.precision,i=Et(t,n.center),r=l.distance(i,n.center);if(r>n.radius+s)return[];if(Math.abs(r-n.radius)<s){const a=i;return t.isOnSegment(a)&&n.isOnSegment(a)?[a]:[]}const c=[],o=Math.sqrt(n.radius*n.radius-r*r),u=t.tangentAtFirstPoint,f=l.add(i,l.scalarMultiply(u,o));t.isOnSegment(f)&&n.isOnSegment(f)&&c.push(f);const h=l.add(i,l.scalarMultiply(u,-o));return t.isOnSegment(h)&&n.isOnSegment(h)&&c.push(h),c}const Ht=t=>{const{firstPoint:n,lastPoint:e,center:s,clockwise:i}=t;return new l.Arc(e,n,s,i,{ignoreChecks:!0})},Yt=(t,n)=>{if(t.isSame(n))return[t];const e=l.removeDuplicatePoints([n.isOnSegment(t.firstPoint)?t.firstPoint:null,n.isOnSegment(t.lastPoint)?t.lastPoint:null,t.isOnSegment(n.firstPoint)?n.firstPoint:null,t.isOnSegment(n.lastPoint)?n.lastPoint:null].filter(s=>s!==null)).sort((s,i)=>t.pointToParam(s)-t.pointToParam(i));if(e.length===0)return[];if(e.length===1)return[];if(e.length===2)return t.isSame(Ht(n))?[]:[new l.Arc(e[0],e[1],t.center,t.clockwise)];if(e.length===3){const s=l.sameVector(e[0],n.lastPoint)||l.sameVector(e[0],n.firstPoint)?1:0;return[new l.Arc(e[0+s],e[1+s],t.center,t.clockwise)]}else if(e.length===4)return[new l.Arc(e[0],e[1],t.center,t.clockwise),new l.Arc(e[2],e[3],t.center,t.clockwise)];throw new Error("Bug in the arc arc overlap algorithm")};function Z(t,n,e=!1,s){const i=s||t.precision,r=l.distance(t.center,n.center),c=t.radius+n.radius;if(r>c+i)return[];const o=Math.abs(t.radius-n.radius);if(r<o-i)return[];if(r<i)return o>i?[]:e?Yt(t,n):[];const u=l.normalize(l.subtract(n.center,t.center)),f=r>c-i;if(f||Math.abs(r-o)<i){const P=f||t.radius>n.radius?1:-1,I=l.add(t.center,l.scalarMultiply(u,P*t.radius));return t.isOnSegment(I)&&n.isOnSegment(I)?[I]:[]}const h=t.radius*t.radius/(2*r)-n.radius*n.radius/(2*r)+r/2,a=l.add(t.center,l.scalarMultiply(u,h)),p=Math.sqrt(t.radius*t.radius-h*h),d=l.perpendicular(u),m=l.add(a,l.scalarMultiply(d,p)),g=l.add(a,l.scalarMultiply(d,-p)),w=[];return t.isOnSegment(m)&&n.isOnSegment(m)&&w.push(m),t.isOnSegment(g)&&n.isOnSegment(g)&&w.push(g),w}function Y(t,n,e=1e-9){const s=t.transform(n.ellipseReferenceFrameTransform),i=s.slope,r=s.yIntercept,c=n.majorRadius*n.majorRadius,o=n.minorRadius*n.minorRadius,u=n.majorRadius*n.minorRadius,f=s.slope*s.slope,h=s.yIntercept*s.yIntercept,a=P=>P.map(I=>n.reverseEllipseReferenceFrameTransform.transform(I)).filter(I=>t.isOnSegment(I)&&n.isOnSegment(I));if(!Number.isFinite(i)){const P=s.firstPoint[0];if(Math.abs(P)-n.majorRadius>e)return[];if(Math.abs(Math.abs(P)-n.majorRadius)<e)return a([[P,0]]);const I=n.minorRadius*Math.sqrt(1-P*P/c),S=[P,I],x=[P,-I];return a([S,x])}const p=c*f+o-h;if(p<-e)return[];const d=c*f+o;if(Math.abs(p)<e){const P=-(c*i*r)/d,I=o*r/d;return a([[P,I]])}const m=Math.sqrt(p),g=[-(c*i*r+u*m)/d,(o*r-u*i*m)/d],w=[-(c*i*r-u*m)/d,(o*r+u*i*m)/d];return a([g,w])}function Bt(t,n){const e=Math.max(t.precision,n.precision),s=t.coefficients,i=s.x2,r=s.xy,c=s.y2,o=s.x,u=s.y,f=s.c,h=n.coefficients,a=h.x2,p=h.xy,d=h.y2,m=h.x,g=h.y,w=h.c,P={z0:f*i*m*m+i*i*w*w-o*i*m*w+a*a*f*f-2*i*w*a*f-o*m*a*f+a*o*o*w,z1:g*o*o*a-w*m*i*r-2*i*w*a*u-f*a*p*o+2*m*p*i*f+2*g*w*i*i+m*m*i*u-g*m*i*o-2*i*g*a*f-f*a*m*r+2*f*u*a*a-w*p*i*o-u*a*m*o+2*w*r*a*o,z2:g*g*i*i+2*d*w*i*i-u*a*m*r+w*a*r*r-u*a*p*o-w*p*i*r-2*i*g*a*u+2*m*p*i*u-d*m*i*o-2*i*d*a*f+p*p*i*f+2*g*r*a*o+u*u*a*a-c*a*m*o-g*p*i*o+2*f*c*a*a-f*a*p*r+d*o*o*a+m*m*i*c-g*m*i*r-2*i*w*a*c,z3:-2*i*a*c*g+g*a*r*r+2*d*r*a*o-c*a*p*o+p*p*i*u-g*p*i*r-2*i*d*a*u-u*a*p*r-d*p*i*o+2*g*d*i*i+2*u*c*a*a-c*a*m*r+2*m*p*i*c-d*m*i*r,z4:i*i*d*d-2*i*d*a*c+a*a*c*c-r*i*p*d-r*p*a*c+r*r*a*d+c*i*p*p},S=l.solveGenericPolynomial([P.z0,P.z1,P.z2,P.z3,P.z4],e).flatMap(x=>{const z=i*p*x+i*m-a*r*x-a*o;if(z)return[[-(i*w+i*d*x*x-a*c*x*x+i*g*x-a*u*x-a*f)/z,x]];const B=r*x+o,F=-B/(2*i),_=c*x*x+u*x+f,v=B*B/(4*i*i)-_/i;if(Math.abs(v)<e)return[[F,x]];if(v>0){const T=Math.sqrt(v);return[[F+T,x],[F-T,x]]}return[]});return l.removeDuplicatePoints(S,e)}function ct(t,n){return Bt(t,n).filter(s=>t.isOnSegment(s)&&n.isOnSegment(s))}const Xt=t=>{const{firstPoint:n,lastPoint:e,center:s,majorRadius:i,minorRadius:r,tiltAngle:c,clockwise:o}=t;return new l.EllipseArc(e,n,s,i,r,c,o,{ignoreChecks:!0,angleUnits:"rad"})},Gt=(t,n)=>{if(t.isSame(n))return[t];const e=(i,r)=>new l.EllipseArc(i,r,t.center,t.majorRadius,t.minorRadius,t.tiltAngle,t.clockwise,{ignoreChecks:!0,angleUnits:"rad"}),s=l.removeDuplicatePoints([n.isOnSegment(t.firstPoint)?t.firstPoint:null,n.isOnSegment(t.lastPoint)?t.lastPoint:null,t.isOnSegment(n.firstPoint)?n.firstPoint:null,t.isOnSegment(n.lastPoint)?n.lastPoint:null].filter(i=>i!==null)).sort((i,r)=>t.pointToParam(i)-t.pointToParam(r));if(s.length===0)return[];if(s.length===1)return[];if(s.length===2)return t.isSame(Xt(n))?[]:[e(s[0],s[1])];if(s.length===3){const i=l.sameVector(s[0],n.lastPoint)||l.sameVector(s[0],n.firstPoint)?1:0;return[e(s[0+i],s[1+i])]}else if(s.length===4)return[e(s[0],s[1]),e(s[2],s[3])];throw new Error("Bug in the ellipse arc ellipse arc overlap algorithm")};function Wt(t,n,e=!1){const s=Math.max(t.precision,n.precision);return l.sameVector(t.center,n.center)&&Math.abs(t.majorRadius-n.majorRadius)<s&&Math.abs(t.minorRadius-n.minorRadius)<s&&(Math.abs(t.tiltAngle-n.tiltAngle)<s||Math.abs(Math.abs(t.tiltAngle-n.tiltAngle)-Math.PI)<s)?e?Gt(t,n):[]:Bt(t,n).filter(c=>t.isOnSegment(c)&&n.isOnSegment(c))}function lt(t,n){const[e,s]=t.firstPoint,[i,r]=t.lastPoint,c=new l.TransformationMatrix().translate(-e,-s).rotate(-Math.atan2(r-s,i-e)),o=c.clone().inverse(),u=n.transform(c);return u.paramsAtY(0).map(f=>u.paramPoint(f)).map(f=>o.transform(f)).filter(f=>t.isOnSegment(f))}const Jt=(t,n=1e-9)=>{let e=t;return Math.abs(t)<n&&(e=0),e.toFixed(-Math.log10(n))};function Ft(t,n=1e-9){return Array.from(new Map(t.map(e=>[Jt(e,n),e])).values())}const Kt=(t,n)=>{const[[e,s,i,r],[c,o,u,f]]=n.polynomialCoefficients,h=t.coefficients,a=h.x2,p=h.xy,d=h.y2,m=h.x,g=h.y,w=h.c,P=e*e,I=s*s,S=i*i,x=r*r,z=c*c,B=o*o,F=u*u,_=f*f,v=w+m*e+a*P+g*c+p*e*c+d*z,T=m*s+2*a*e*s+p*s*c+g*o+p*e*o+2*d*c*o,Dt=a*I+m*i+2*a*e*i+p*i*c+p*s*o+d*B+g*u+p*e*u+2*d*c*u,Rt=2*a*s*i+m*r+2*a*e*r+p*r*c+p*i*o+p*s*u+2*d*o*u+g*f+p*e*f+2*d*c*f,Nt=a*S+2*a*s*r+p*r*o+p*i*u+d*F+p*s*f+2*d*o*f,jt=2*a*i*r+p*r*u+p*i*f+2*d*u*f,Qt=a*x+p*r*f+d*_;return[v,T,Dt,Rt,Nt,jt,Qt]};function ut(t,n){const e=Math.max(t.precision,n.precision),s=Kt(t,n),i=l.solveGenericPolynomial(s,e).filter(r=>r>=-n.precision&&r<=1+n.precision);return Ft(i,e).map(r=>n.paramPoint(r)).filter(r=>t.isOnSegment(r))}const Zt=(t,n)=>{const[[e,s,i],[r,c,o]]=n.polynomialCoefficients,u=t.coefficients,f=u.x2,h=u.xy,a=u.y2,p=u.x,d=u.y,m=u.c,g=e*e,w=s*s,P=i*i,I=r*r,S=c*c,x=o*o,z=f*g+h*e*r+a*I+p*e+d*r+m,B=2*f*e*s+h*e*c+h*s*r+2*a*r*c+p*s+d*c,F=2*f*e*i+f*w+h*e*o+h*s*c+h*i*r+2*a*r*o+a*S+p*i+d*o,_=2*f*s*i+h*s*o+h*i*c+2*a*c*o,v=f*P+h*i*o+a*x;return[z,B,F,_,v]};function at(t,n){const e=Math.max(t.precision,n.precision),s=Zt(t,n),i=l.solveQuartic(...s).filter(r=>r>=-n.precision&&r<=1+n.precision);return Ft(i,e).map(r=>n.paramPoint(r)).filter(r=>t.isOnSegment(r))}function b(t,{firstPoint:n,lastPoint:e},s=1e-9){const i=l.subtract(e,n);return Math.abs(i[0])<s?i[1]>0?n[0]-t[0]:t[0]-n[0]:Math.abs(i[1])<s?i[0]>0?t[1]-n[1]:n[1]-t[1]:l.crossProduct(i,l.subtract(t,n))/l.length(i)}class tt{constructor(n,e,s,i){this.firstPoint=n,this.lastPoint=e,this.negativeThickness=s,this.positiveThickness=i}get width(){return this.positiveThickness-this.negativeThickness}}const tn=3/4,nn=4/9;function en(t){const n=b(t.firstControlPoint,t),e=b(t.lastControlPoint,t),s=n*e>0?tn:nn;return new tt(t.firstPoint,t.lastPoint,s*Math.min(0,n,e),s*Math.max(0,n,e))}function sn(t){const n=b(t.controlPoint,t);return new tt(t.firstPoint,t.lastPoint,Math.min(0,n/2),Math.max(0,n/2))}function rn(t){if(l.CubicBezier.isInstance(t))return en(t);if(l.QuadraticBezier.isInstance(t))return sn(t);throw new Error("Not implemented")}function on(t){const n=t.paramPoint(.5),e=l.perpendicular(l.subtract(n,t.firstPoint)),s=l.add(n,e),i={firstPoint:n,lastPoint:s},r=[b(t.firstPoint,i),b(t.lastPoint,i)];return l.CubicBezier.isInstance(t)?r.push(b(t.firstControlPoint,i),b(t.lastControlPoint,i)):l.QuadraticBezier.isInstance(t)&&r.push(b(t.controlPoint,i)),new tt(n,s,Math.min(...r),Math.max(...r))}function ft(t,n){const e=[];for(let s=1;s<t.length;s++){const i=t[s];if(i[1]===n){e.push(i[0]);continue}const r=t[s-1],c=n-r[1],o=n-i[1];if(c*o<0){e.push(r[0]+(n-r[1])*(i[0]-r[0])/(i[1]-r[1]));continue}}return e}class V{constructor(n,e){this.from=n,this.to=e}get size(){return this.from==="start"?this.to==="end"?1:this.to:this.to==="end"?1-this.from:Math.abs(this.from-this.to)}clipCurve(n){return this.from==="start"?this.to==="end"?n:n.splitAtParameters([this.to])[0]:this.to==="end"?n.splitAtParameters([this.from])[1]:n.splitAtParameters([this.from,this.to])[1]}}function cn(t,n){if(l.CubicBezier.isInstance(t))return new un([b(t.firstPoint,n),b(t.firstControlPoint,n),b(t.lastControlPoint,n),b(t.lastPoint,n)]);if(l.QuadraticBezier.isInstance(t))return new ln([b(t.firstPoint,n),b(t.controlPoint,n),b(t.lastPoint,n)]);throw new Error("Not implemented")}class ln{constructor(n){A(this,"topHull",[]);A(this,"bottomHull",[]);this.distances=n;const[e,s,i]=n,r=[0,e],c=[1/2,s],o=[1,i],u=i-e,f=e;s-(u*(1/2)+f)>0?(this.topHull=[r,c,o],this.bottomHull=[r,o]):(this.topHull=[r,o],this.bottomHull=[r,c,o])}get startDistance(){return this.distances[0]}get endDistance(){return this.distances[2]}}class un{constructor(n){A(this,"topHull",[]);A(this,"bottomHull",[]);this.distances=n;const[e,s,i,r]=n,c=[0,e],o=[1/3,s],u=[2/3,i],f=[1,r],h=r-e,a=e,p=s-(h*(1/3)+a),d=i-(h*(2/3)+a);let m=null,g=null;if(p*d<0)m=[c,o,f],g=[c,u,f];else{const P=p/d;P>=2?(m=[c,o,f],g=[c,f]):P<=.5?(m=[c,u,f],g=[c,f]):(m=[c,o,u,f],g=[c,f])}p<0&&([m,g]=[g,m]),this.topHull=m,this.bottomHull=g}get startDistance(){return this.distances[0]}get endDistance(){return this.distances[3]}}function ht(t,n){const e=cn(n,t),s=ft(e.topHull,t.negativeThickness),i=ft(e.bottomHull,t.positiveThickness),r=e.endDistance>=t.negativeThickness&&e.endDistance<=t.positiveThickness;if(!s.length&&!i.length)return r?new V("start","end"):null;if(s.length===1&&i.length===1)return new V(s[0],i[0]);if(s.length===2&&i.length===2)throw new Error("Bug in the clipping algorithm, unexpected number of crossing points");const c=s.length?s:i;return c.length===2?new V(c[0],c[1]):r?new V(c[0],"end"):new V("start",c[0])}function pt(t,n){const e=rn(t),s=ht(e,n);if(!s)return null;const i=on(t),r=ht(i,n);return r?s.size>r.size?r.clipCurve(n):s.clipCurve(n):null}const N=t=>l.QuadraticBezier.isInstance(t)?l.squareLength(l.subtract(t.controlPoint,t.firstPoint))+l.squareLength(l.subtract(t.controlPoint,t.lastPoint)):l.squareLength(l.subtract(t.firstControlPoint,t.firstPoint))+l.squareLength(l.subtract(t.lastControlPoint,t.firstControlPoint))+l.squareLength(l.subtract(t.lastControlPoint,t.lastPoint));function L(t,n,e=1e-9,{maxIterations:s=100}={}){const i=Math.max(e*e,Number.EPSILON*10);let r=t,c=n,o=N(r),u=N(c);for(let f=0;f<s;f++){const h=o>i?pt(c,r):r;if(!h)return[];const a=N(h),p=u>i?pt(h,c):c;if(!p)return[];const d=N(p);if(a<=i&&d<=i)return[h.boundingBox.intersection(p.boundingBox).center];if(l.sameVector(h.firstPoint,h.lastPoint)&&p.isOnSegment(h.firstPoint))return[h.firstPoint];if(l.sameVector(p.firstPoint,p.lastPoint)&&h.isOnSegment(p.firstPoint))return[p.firstPoint];if(a>.8*o&&d>.8*u)if(a/o>d/u){const[m,g]=h.splitAtParameters([.5]);return l.removeDuplicatePoints([...L(m,p,e,{maxIterations:s-f}),...L(g,p,e,{maxIterations:s-f})],e)}else{const[m,g]=p.splitAtParameters([.5]);return l.removeDuplicatePoints([...L(h,m,e,{maxIterations:s-f}),...L(h,g,e,{maxIterations:s-f})],e)}r=h,c=p,o=a,u=d}throw new Error("Bézier clip: Maximum number of iterations reached")}function an(t,n){const e=[];if([[t.firstPoint,n],[t.lastPoint,n],[n.firstPoint,t],[n.lastPoint,t]].forEach(([i,r])=>{r.isOnSegment(i)&&e.push(i)}),e.length<2)return null;if(e.length===2)return[t.splitAt(e)[1]];if(e.length===3)return l.sameVector(e[0],t.firstPoint)&&l.sameVector(e[1],t.lastPoint)?[t]:[n];if(e.length===4)return[t]}function fn(t,n,e=!1){const s=Math.max(t.precision,n.precision);if(e){const i=an(t,n);if(i)return i}return L(t,n,s)}function hn(t,n){const e=[];if([[t.firstPoint,n],[t.lastPoint,n],[n.firstPoint,t],[n.lastPoint,t]].forEach(([i,r])=>{r.isOnSegment(i)&&e.push(i)}),e.length<2)return null;if(e.length===2)return[t.splitAt(e)[1]];if(e.length===3)return l.sameVector(e[0],t.firstPoint)&&l.sameVector(e[1],t.lastPoint)?[t]:[n];if(e.length===4)return[t]}function pn(t,n,e=!1){const s=Math.max(t.precision,n.precision);if(e){const i=hn(t,n);if(i)return i}return L(t,n,s)}function dn(t,n,e){if(l.Line.isInstance(t)&&l.Line.isInstance(n)){const s=l.lineLineIntersection(t,n,!1,e);return s===null?[]:[s]}if(l.Line.isInstance(t)&&l.Arc.isInstance(n))return D(t,n,e);if(l.Arc.isInstance(t)&&l.Line.isInstance(n))return D(n,t,e);if(l.Arc.isInstance(t)&&l.Arc.isInstance(n))return Z(t,n,!1,e);throw new Error("Not implemented")}function R(t,n,e){if(l.Line.isInstance(t)&&l.Line.isInstance(n)){const s=l.lineLineIntersection(t,n,!0,e);return s===null?{intersections:[],overlaps:[],count:0}:l.Line.isInstance(s)?{intersections:[],overlaps:[s],count:1}:{intersections:[s],overlaps:[],count:1}}if(!t.boundingBox.overlaps(n.boundingBox))return{intersections:[],overlaps:[],count:0};if(l.Line.isInstance(t)&&l.Arc.isInstance(n)){const s=D(t,n,e);return{intersections:s,overlaps:[],count:s.length}}if(l.Arc.isInstance(t)&&l.Line.isInstance(n)){const s=D(n,t,e);return{intersections:s,overlaps:[],count:s.length}}if(l.Arc.isInstance(t)&&l.Arc.isInstance(n)){const s=Z(t,n,!0,e);return s.length?l.Arc.isInstance(s[0])?{intersections:[],overlaps:s,count:s.length}:{intersections:s,overlaps:[],count:s.length}:{intersections:[],overlaps:[],count:0}}if(l.Line.isInstance(t)&&l.EllipseArc.isInstance(n)){const s=Y(t,n,e);return{intersections:s,overlaps:[],count:s.length}}if(l.Line.isInstance(n)&&l.EllipseArc.isInstance(t)){const s=Y(n,t,e);return{intersections:s,overlaps:[],count:s.length}}if(l.Arc.isInstance(t)&&l.EllipseArc.isInstance(n)){const s=ct(t,n);return{intersections:s,overlaps:[],count:s.length}}if(l.Arc.isInstance(n)&&l.EllipseArc.isInstance(t)){const s=ct(n,t);return{intersections:s,overlaps:[],count:s.length}}if(l.EllipseArc.isInstance(t)&&l.EllipseArc.isInstance(n)){const s=Wt(t,n,!0);return s.length?l.EllipseArc.isInstance(s[0])?{intersections:[],overlaps:s,count:s.length}:{intersections:s,overlaps:[],count:s.length}:{intersections:[],overlaps:[],count:0}}if(l.Line.isInstance(t)&&(l.CubicBezier.isInstance(n)||l.QuadraticBezier.isInstance(n))){const s=lt(t,n);return{intersections:s,overlaps:[],count:s.length}}if(l.Line.isInstance(n)&&(l.CubicBezier.isInstance(t)||l.QuadraticBezier.isInstance(t))){const s=lt(n,t);return{intersections:s,overlaps:[],count:s.length}}if((l.Arc.isInstance(t)||l.EllipseArc.isInstance(t))&&l.QuadraticBezier.isInstance(n)){const s=at(t,n);return{intersections:s,overlaps:[],count:s.length}}if((l.Arc.isInstance(n)||l.EllipseArc.isInstance(n))&&l.QuadraticBezier.isInstance(t)){const s=at(n,t);return{intersections:s,overlaps:[],count:s.length}}if((l.Arc.isInstance(t)||l.EllipseArc.isInstance(t))&&l.CubicBezier.isInstance(n)){const s=ut(t,n);return{intersections:s,overlaps:[],count:s.length}}if((l.Arc.isInstance(n)||l.EllipseArc.isInstance(n))&&l.CubicBezier.isInstance(t)){const s=ut(n,t);return{intersections:s,overlaps:[],count:s.length}}if(l.QuadraticBezier.isInstance(t)&&l.QuadraticBezier.isInstance(n)){const s=pn(t,n);return s.length?l.QuadraticBezier.isInstance(s[0])?{intersections:[],overlaps:s,count:s.length}:{intersections:s,overlaps:[],count:s.length}:{intersections:[],overlaps:[],count:0}}if(l.QuadraticBezier.isInstance(t)&&l.CubicBezier.isInstance(n)||l.QuadraticBezier.isInstance(n)&&l.CubicBezier.isInstance(t)){const s=L(t,n);return{intersections:s,overlaps:[],count:s.length}}if(l.CubicBezier.isInstance(t)&&l.CubicBezier.isInstance(n)){const s=fn(t,n);return s.length?l.CubicBezier.isInstance(s[0])?{intersections:[],overlaps:s,count:s.length}:{intersections:s,overlaps:[],count:s.length}:{intersections:[],overlaps:[],count:0}}throw new Error("Not implemented")}function vt(t){const n=[];for(let e=0;e<t;e++)for(let s=0;s<=e;s++)n.push([e,s]);return n}function*X(t){for(const[n,e]of vt(t.length))n!==e&&(yield[t[n],t[e]])}class Lt extends l.Transformable{constructor(e,{ignoreChecks:s=!1}={}){super();A(this,"segments");A(this,"_boundingBox",null);s||zt(e),this.segments=e}get repr(){return this.segments.map(e=>e.repr).join(`
|
|
2
|
+
`)+`
|
|
3
|
+
`}get info(){return this.repr}get firstPoint(){return this.segments[0].firstPoint}get lastPoint(){return this.segments[this.segments.length-1].lastPoint}get segmentsCount(){return this.segments.length}onStroke(e){return this.segments.some(s=>s.isOnSegment(e))}intersects(e){return this.boundingBox.overlaps(e.boundingBox)?this.segments.some(s=>e.segments.some(i=>R(s,i).count>0)):!1}overlappingSegments(e){return this.segments.flatMap(s=>e.segments.flatMap(i=>s.boundingBox.overlaps(i.boundingBox)?R(s,i).overlaps:[]))}get boundingBox(){if(this._boundingBox===null){let e=this.segments[0].boundingBox;this.segments.slice(1).forEach(s=>{e=e.merge(s.boundingBox)}),this._boundingBox=e}return this._boundingBox}[Symbol.for("nodejs.util.inspect.custom")](){return this.repr}}function mn(t,n="Stroke"){vt(t.length).forEach(([e,s])=>{if(e===s)return;const i=t[e],r=t[s],c=R(i,r),o=Math.max(i.precision,r.precision);if(c.count!==0){if(c.count===1&&!c.overlaps.length){const u=e-s,f=c.intersections[0];if(u===1&&l.sameVector(i.firstPoint,f,o)||u===-1&&l.sameVector(i.lastPoint,f,o)||u===t.length-1&&l.sameVector(i.lastPoint,f,o)&&l.sameVector(r.firstPoint,f,o)||-u===t.length-1&&l.sameVector(i.firstPoint,f,o)&&l.sameVector(r.lastPoint,f,o))return}if(!(c.count===2&&t.length===2&&(l.sameVector(i.firstPoint,c.intersections[0],o)&&l.sameVector(i.lastPoint,c.intersections[1],o)||l.sameVector(i.firstPoint,c.intersections[1],o)&&l.sameVector(i.lastPoint,c.intersections[0],o))))throw new Error(`${n} segments must not intersect, but segments ${i.info} and ${r.info} do at ${JSON.stringify(c.intersections)}`)}})}function zt(t,n="Stroke"){if(t.length===0)throw new Error(`${n} must have at least one segment`);l.zip([t.slice(0,-1),t.slice(1)]).forEach(([e,s])=>{if(!l.sameVector(e.lastPoint,s.firstPoint))throw new Error(`${n} segments must be connected, but ${e.info} and ${s.info} are not`)}),mn(t,n)}function dt(t,n){return!!(l.Line.isInstance(t)&&l.Line.isInstance(n)&&l.parallel(t.V,n.V)||l.Arc.isInstance(t)&&l.Arc.isInstance(n)&&l.sameVector(t.center,n.center)&&t.radius-n.radius<t.precision)}function mt(t,n){if(l.Line.isInstance(t)&&l.Line.isInstance(n))return new l.Line(t.firstPoint,n.lastPoint);if(l.Arc.isInstance(t)&&l.Arc.isInstance(n))return new l.Arc(t.firstPoint,n.lastPoint,t.center,t.clockwise);throw new Error("Not implemented")}function Ot(t){let n=!1;const e=[];for(const s of t.segments){if(e.length===0){e.push(s);continue}const i=e[e.length-1];dt(i,s)?(n=!0,e.pop(),e.push(mt(i,s))):e.push(s)}if(l.sameVector(t.firstPoint,t.lastPoint)&&dt(e[0],e[e.length-1])){n=!0;const s=e.pop();e[0]=mt(s,e[0])}return n?e:null}const gt=Symbol.for("pantograph:Strand");class C extends Lt{constructor(e,{ignoreChecks:s=!1}={}){super(e,{ignoreChecks:s});A(this,"strokeType","STRAND");Object.defineProperty(this,gt,{value:!0})}static isInstance(e){return!!e&&e[gt]===!0}reverse(){const e=this.segments.map(s=>s.reverse());return e.reverse(),new C(e,{ignoreChecks:!0})}clone(){return new C(this.segments.map(e=>e.clone()),{ignoreChecks:!0})}extend(e){if(!l.sameVector(this.lastPoint,e.firstPoint))throw console.error(this.repr,e.repr),new Error("Cannot extend strand: connection point is not the same");return new C([...this.segments,...e.segments])}simplify(){const e=Ot(this);return e?new C(e,{ignoreChecks:!0}):this}transform(e){return new C(this.segments.map(s=>s.transform(e)),{ignoreChecks:!0})}}const gn=(t,n)=>{const e=l.lineLineParams(n,{V:[1,0],firstPoint:t,precision:n.precision});if(e==="parallel")return 0;const{intersectionParam1:s,intersectionParam2:i}=e;if(!n.isValidParameter(s)||i<=-n.precision)return 0;if(Math.abs(s)<n.precision||Math.abs(s-1)<n.precision){const[,r]=n.midPoint;return t[1]-r<0?1:0}return 1};class nt{constructor(n){A(this,"_count",0);A(this,"segment");this.segment=n}update(n,e=!1){!e&&!this.segment.isOnSegment(n)||(l.sameVector(n,this.segment.firstPoint)?this._count+=this.segment.tangentAtFirstPoint[1]>0?1:0:l.sameVector(n,this.segment.lastPoint)?this._count+=this.segment.tangentAtLastPoint[1]>0?0:1:this._count+=1)}get count(){return this._count}}const Pn=(t,n)=>{const e=n.precision,s=Math.abs(t[1]-n.center[1]);if(s>n.radius+e)return 0;const i=l.squareDistance(t,n.center),r=n.radius*n.radius,c=e*e;if(Math.abs(i-r)<c&&n.isOnSegment(t))return 0;const o=i-r>c;if(o&&n.center[0]<t[0])return 0;const u=Math.sqrt(n.radius*n.radius-s*s),f=new nt(n);return f.update([n.center[0]+u,t[1]]),o&&f.update([n.center[0]-u,t[1]]),f.count},In=(t,n)=>{const e=n.boundingBox.xMax+n.boundingBox.width/2,s=new l.Line(t,[e,t[1]]),i=new nt(n);return Y(s,n).forEach(r=>{i.update(r,!0)}),i.count},wn=(t,n)=>{const e=new nt(n);return n.paramsAtY(t[1]).map(s=>{try{return n.paramPoint(s)}catch{return null}}).filter(s=>s!==null).filter(s=>{const[i]=s;return i>=t[0]}).forEach(s=>{e.update(s,!0)}),e.count};function xn(t,n){if(l.Line.isInstance(n))return gn(t,n);if(l.Arc.isInstance(n))return Pn(t,n);if(l.EllipseArc.isInstance(n))return In(t,n);if(l.CubicBezier.isInstance(n)||l.QuadraticBezier.isInstance(n))return wn(t,n);throw new Error("Not implemented")}const Pt=Symbol.for("pantograph:Loop");class E extends Lt{constructor(e,{ignoreChecks:s=!1}={}){super(e,{ignoreChecks:!0});A(this,"strokeType","LOOP");A(this,"_clockwise",null);Object.defineProperty(this,Pt,{value:!0}),s||An(e)}static isInstance(e){return!!e&&e[Pt]===!0}get clockwise(){if(this._clockwise===null){const e=this.segments.flatMap(i=>l.Line.isInstance(i)?[i.firstPoint]:[i.firstPoint,i.paramPoint(.5)]),s=e.map((i,r)=>{const c=e[(r+1)%e.length];return(c[0]-i[0])*(c[1]+i[1])}).reduce((i,r)=>i+r,0);this._clockwise=s>0}return this._clockwise}clone(){return new E(this.segments.map(e=>e.clone()),{ignoreChecks:!0})}reverse(){const e=this.segments.map(s=>s.reverse());return e.reverse(),new E(e,{ignoreChecks:!0})}transform(e){return new E(this.segments.map(s=>s.transform(e)),{ignoreChecks:!0})}contains(e,{strokeIsInside:s=!1}={}){return this.onStroke(e)?s:this.boundingBox.contains(e)?this.segments.reduce((r,c)=>r+xn(e,c),0)%2===1:!1}simplify(){const e=Ot(this);return e?new E(e,{ignoreChecks:!0}):this}}function An(t){if(zt(t,"Loop"),!l.sameVector(t[0].firstPoint,t[t.length-1].lastPoint))throw new Error("Loop segment must be closed")}const bn=[l.Line,l.Arc,l.EllipseArc,l.QuadraticBezier,l.CubicBezier];function kt(t){return bn.some(n=>n.isInstance(t))}function _t(t){if(l.Line.isInstance(t))return{type:t.segmentType,firstPoint:t.firstPoint,lastPoint:t.lastPoint};if(l.Arc.isInstance(t))return{type:t.segmentType,firstPoint:t.firstPoint,lastPoint:t.lastPoint,center:t.center,clockwise:t.clockwise};if(l.EllipseArc.isInstance(t))return{type:t.segmentType,firstPoint:t.firstPoint,lastPoint:t.lastPoint,center:t.center,clockwise:t.clockwise,majorRadius:t.majorRadius,minorRadius:t.minorRadius,tiltAngle:t.tiltAngle};if(l.QuadraticBezier.isInstance(t))return{type:t.segmentType,firstPoint:t.firstPoint,lastPoint:t.lastPoint,controlPoint:t.controlPoint};if(l.CubicBezier.isInstance(t))return{type:t.segmentType,firstPoint:t.firstPoint,lastPoint:t.lastPoint,firstControlPoint:t.firstControlPoint,lastControlPoint:t.lastControlPoint};throw new Error("Unknown segment type")}function G(t){return{type:"LOOP",segments:t.segments.map(_t)}}function Tt(t){return{type:"FIGURE",contour:G(t.contour),holes:t.holes.map(G)}}function Sn(t){return{type:"DIAGRAM",figures:t.figures.map(Tt)}}function W(t){if(M.isInstance(t))return Sn(t);if(y.isInstance(t))return Tt(t);if(E.isInstance(t))return G(t);if(kt(t))return _t(t);throw new Error("Unknown shape type")}class yn{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(n,e){let s=this.length++;for(;s>0;){const i=s-1>>1,r=this.values[i];if(e>=r)break;this.ids[s]=this.ids[i],this.values[s]=r,s=i}this.ids[s]=n,this.values[s]=e}pop(){if(this.length===0)return;const n=this.ids[0];if(this.length--,this.length>0){const e=this.ids[0]=this.ids[this.length],s=this.values[0]=this.values[this.length],i=this.length>>1;let r=0;for(;r<i;){let c=(r<<1)+1;const o=c+1;let u=this.ids[c],f=this.values[c];const h=this.values[o];if(o<this.length&&h<f&&(c=o,u=this.ids[o],f=h),f>=s)break;this.ids[r]=u,this.values[r]=f,r=c}this.ids[r]=e,this.values[r]=s}return n}peek(){if(this.length!==0)return this.ids[0]}peekValue(){if(this.length!==0)return this.values[0]}shrink(){this.ids.length=this.values.length=this.length}}const It=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],H=3;class et{static from(n,e=0){if(e%8!==0)throw new Error("byteOffset must be 8-byte aligned.");if(!n||n.byteLength===void 0||n.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[s,i]=new Uint8Array(n,e+0,2);if(s!==251)throw new Error("Data does not appear to be in a Flatbush format.");const r=i>>4;if(r!==H)throw new Error(`Got v${r} data when expected v${H}.`);const c=It[i&15];if(!c)throw new Error("Unrecognized array type.");const[o]=new Uint16Array(n,e+2,1),[u]=new Uint32Array(n,e+4,1);return new et(u,o,c,void 0,n,e)}constructor(n,e=16,s=Float64Array,i=ArrayBuffer,r,c=0){if(n===void 0)throw new Error("Missing required argument: numItems.");if(isNaN(n)||n<=0)throw new Error(`Unexpected numItems value: ${n}.`);this.numItems=+n,this.nodeSize=Math.min(Math.max(+e,2),65535),this.byteOffset=c;let o=n,u=o;this._levelBounds=[o*4];do o=Math.ceil(o/this.nodeSize),u+=o,this._levelBounds.push(u*4);while(o!==1);this.ArrayType=s,this.IndexArrayType=u<16384?Uint16Array:Uint32Array;const f=It.indexOf(this.ArrayType),h=u*4*this.ArrayType.BYTES_PER_ELEMENT;if(f<0)throw new Error(`Unexpected typed array class: ${s}.`);r&&r.byteLength!==void 0&&!r.buffer?(this.data=r,this._boxes=new this.ArrayType(this.data,c+8,u*4),this._indices=new this.IndexArrayType(this.data,c+8+h,u),this._pos=u*4,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1]):(this.data=new i(8+h+u*this.IndexArrayType.BYTES_PER_ELEMENT),this._boxes=new this.ArrayType(this.data,8,u*4),this._indices=new this.IndexArrayType(this.data,8+h,u),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(this.data,0,2).set([251,(H<<4)+f]),new Uint16Array(this.data,2,1)[0]=e,new Uint32Array(this.data,4,1)[0]=n),this._queue=new yn}add(n,e,s=n,i=e){const r=this._pos>>2,c=this._boxes;return this._indices[r]=r,c[this._pos++]=n,c[this._pos++]=e,c[this._pos++]=s,c[this._pos++]=i,n<this.minX&&(this.minX=n),e<this.minY&&(this.minY=e),s>this.maxX&&(this.maxX=s),i>this.maxY&&(this.maxY=i),r}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);const n=this._boxes;if(this.numItems<=this.nodeSize){n[this._pos++]=this.minX,n[this._pos++]=this.minY,n[this._pos++]=this.maxX,n[this._pos++]=this.maxY;return}const e=this.maxX-this.minX||1,s=this.maxY-this.minY||1,i=new Uint32Array(this.numItems),r=65535;for(let c=0,o=0;c<this.numItems;c++){const u=n[o++],f=n[o++],h=n[o++],a=n[o++],p=Math.floor(r*((u+h)/2-this.minX)/e),d=Math.floor(r*((f+a)/2-this.minY)/s);i[c]=Mn(p,d)}J(i,n,this._indices,0,this.numItems-1,this.nodeSize);for(let c=0,o=0;c<this._levelBounds.length-1;c++){const u=this._levelBounds[c];for(;o<u;){const f=o;let h=n[o++],a=n[o++],p=n[o++],d=n[o++];for(let m=1;m<this.nodeSize&&o<u;m++)h=Math.min(h,n[o++]),a=Math.min(a,n[o++]),p=Math.max(p,n[o++]),d=Math.max(d,n[o++]);this._indices[this._pos>>2]=f,n[this._pos++]=h,n[this._pos++]=a,n[this._pos++]=p,n[this._pos++]=d}}}search(n,e,s,i,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let c=this._boxes.length-4;const o=[],u=[];for(;c!==void 0;){const f=Math.min(c+this.nodeSize*4,xt(c,this._levelBounds));for(let h=c;h<f;h+=4){if(s<this._boxes[h]||i<this._boxes[h+1]||n>this._boxes[h+2]||e>this._boxes[h+3])continue;const a=this._indices[h>>2]|0;c>=this.numItems*4?o.push(a):(r===void 0||r(a))&&u.push(a)}c=o.pop()}return u}neighbors(n,e,s=1/0,i=1/0,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let c=this._boxes.length-4;const o=this._queue,u=[],f=i*i;t:for(;c!==void 0;){const h=Math.min(c+this.nodeSize*4,xt(c,this._levelBounds));for(let a=c;a<h;a+=4){const p=this._indices[a>>2]|0,d=wt(n,this._boxes[a],this._boxes[a+2]),m=wt(e,this._boxes[a+1],this._boxes[a+3]),g=d*d+m*m;g>f||(c>=this.numItems*4?o.push(p<<1,g):(r===void 0||r(p))&&o.push((p<<1)+1,g))}for(;o.length&&o.peek()&1;)if(o.peekValue()>f||(u.push(o.pop()>>1),u.length===s))break t;c=o.length?o.pop()>>1:void 0}return o.clear(),u}}function wt(t,n,e){return t<n?n-t:t<=e?0:t-e}function xt(t,n){let e=0,s=n.length-1;for(;e<s;){const i=e+s>>1;n[i]>t?s=i:e=i+1}return n[e]}function J(t,n,e,s,i,r){if(Math.floor(s/r)>=Math.floor(i/r))return;const c=t[s+i>>1];let o=s-1,u=i+1;for(;;){do o++;while(t[o]<c);do u--;while(t[u]>c);if(o>=u)break;Cn(t,n,e,o,u)}J(t,n,e,s,u,r),J(t,n,e,u+1,i,r)}function Cn(t,n,e,s,i){const r=t[s];t[s]=t[i],t[i]=r;const c=4*s,o=4*i,u=n[c],f=n[c+1],h=n[c+2],a=n[c+3];n[c]=n[o],n[c+1]=n[o+1],n[c+2]=n[o+2],n[c+3]=n[o+3],n[o]=u,n[o+1]=f,n[o+2]=h,n[o+3]=a;const p=e[s];e[s]=e[i],e[i]=p}function Mn(t,n){let e=t^n,s=65535^e,i=65535^(t|n),r=t&(n^65535),c=e|s>>1,o=e>>1^e,u=i>>1^s&r>>1^i,f=e&i>>1^r>>1^r;e=c,s=o,i=u,r=f,c=e&e>>2^s&s>>2,o=e&s>>2^s&(e^s)>>2,u^=e&i>>2^s&r>>2,f^=s&i>>2^(e^s)&r>>2,e=c,s=o,i=u,r=f,c=e&e>>4^s&s>>4,o=e&s>>4^s&(e^s)>>4,u^=e&i>>4^s&r>>4,f^=s&i>>4^(e^s)&r>>4,e=c,s=o,i=u,r=f,u^=e&i>>8^s&r>>8,f^=s&i>>8^(e^s)&r>>8,e=u^u>>1,s=f^f>>1;let h=t^n,a=s|65535^(h|e);return h=(h|h<<8)&16711935,h=(h|h<<4)&252645135,h=(h|h<<2)&858993459,h=(h|h<<1)&1431655765,a=(a|a<<8)&16711935,a=(a|a<<4)&252645135,a=(a|a<<2)&858993459,a=(a|a<<1)&1431655765,(a<<1|h)>>>0}function st(t,n=1e-7){if(t.length===0)return[];if(t.length===1)return[t];const e=new et(t.length);t.forEach(r=>{const[c,o]=r.firstPoint;e.add(c-n,o-n,c+n,o+n)}),e.finish();const s=[],i=new Set;return t.forEach((r,c)=>{if(i.has(c))return;const o=[r];let u=c;i.add(c);let f=t.length;for(;;){if(f--<0)throw new Error("Infinite loop detected");const h=o[o.length-1].lastPoint,[a,p]=h,d=e.search(a-n,p-n,a+n,p+n),m=I=>Math.abs((u-I)%t.length),g=d.filter(I=>!i.has(I)).map(I=>[t[I],I,m(I)]).sort(([,,I],[,,S])=>m(I)-m(S));if(g.length===0){s.push(o);break}const[w,P]=g[0];o.push(w),i.add(P),u=P}}),s}const At=Symbol.for("pantograph:Figure");class y extends l.Transformable{constructor(e,s=[],{ignoreChecks:i=!1}={}){super();A(this,"contour");A(this,"holes");Object.defineProperty(this,At,{value:!0}),i||En(e,s),this.contour=e,this.holes=s}static isInstance(e){return!!e&&e[At]===!0}get boundingBox(){return this.contour.boundingBox}get isFull(){return this.holes.length===0}get allLoops(){return[this.contour,...this.holes]}clone(){return new y(this.contour.clone(),this.holes.map(e=>e.clone()))}transform(e){return new y(this.contour.transform(e),this.holes.map(s=>s.transform(e)))}contains(e,{strokeIsInside:s=!1}={}){return this.contour.contains(e,{strokeIsInside:s})&&!this.holes.some(i=>i.contains(e,{strokeIsInside:s}))}intersects(e){return this.allLoops.some(s=>e.allLoops.some(i=>s.intersects(i)))}overlappingStrands(e){const s=y.isInstance(e)?e.allLoops:[e],i=this.allLoops.flatMap(r=>s.flatMap(c=>r.overlappingSegments(c)));return st(i).map(r=>new C(r))}}function En(t,n=[]){if(!t)throw new Error("Figure must have a contour");for(const[e,s]of X([t,...n]))if(e.intersects(s))throw new Error("Loops in a figure must not intersect");if(n.some(e=>!t.contains(e.firstPoint)&&!t.onStroke(e.firstPoint)))throw new Error("Holes must be inside the contour");for(const[e,s]of X(n))if(e.contains(s.firstPoint))throw console.error(W(e),W(s)),new Error("Holes must not be inside other holes")}const j=(t,n,e=1e-7)=>Math.abs(t-n)<=e,Bn=(t,n)=>{const e=t.boundingBox,s=n.boundingBox;return j(e.xMin,s.xMin)&&j(e.yMin,s.yMin)&&j(e.xMax,s.xMax)&&j(e.yMax,s.yMax)},Fn=(t,n)=>{if(t.segmentsCount!==n.segmentsCount||!Bn(t,n))return!1;const e=t.segments,s=n.segments,i=e.length,r=(c,o)=>{for(let u=0;u<i;u+=1){const f=(c+o*u+i)%i;if(!e[u].isSame(s[f]))return!1}return!0};for(let c=0;c<i;c+=1)if(e[0].isSame(s[c])&&(r(c,1)||r(c,-1)))return!0;return!1},vn=t=>{const n=[];return t.forEach(e=>{n.some(s=>Fn(e,s))||n.push(e)}),n},Ln=t=>{const n=t.map((i,r)=>t.slice(r+1).map((c,o)=>[o+r+1,c]).filter(([,c])=>i.boundingBox.overlaps(c.boundingBox)).map(([c])=>c)),e=[],s=Array(n.length);return n.forEach((i,r)=>{let c=s[r];c||(c=[],e.push(c)),c.push(t[r]),i.length&&i.forEach(o=>{s[o]=c})}),e},Vt=t=>t.map((n,e)=>{const i=n.segments[0].midPoint,r=t.filter((c,o)=>e===o?!1:c.contains(i));return{loop:n,isIn:r}}),zn=(t,n)=>t.flatMap(({loop:e})=>it(n.filter(({loop:s,isIn:i})=>s===e||i.indexOf(e)!==-1))),On=(t,n)=>{const e=n.filter(({isIn:i})=>i.length<=1),s=it(Vt(t.map(({loop:i})=>i)));return[e,...s]},it=t=>{if(!t.length)return[];const n=t.filter(({isIn:s})=>!s.length),e=t.filter(({isIn:s})=>s.length>1);return n.length===1&&e.length===0?[t]:n.length>1?zn(n,t):On(e,t)};function q(t){const n=vn(t);return Ln(n).map(Vt).flatMap(it).map(s=>{if(s.length===1)return new y(s[0].loop);s.sort((c,o)=>c.isIn.length-o.isIn.length);const[i,...r]=s.map(({loop:c})=>c);return new y(i,r)})}function kn(t,n){const e=[];for(const s of t)for(const i of n)e.push([s,i]);return e}function*K(t,n,e){const s=o=>n.some(u=>l.sameVector(u,o.lastPoint)),i=(o,u)=>o.segmentType!==u.segmentType||!u.isOnSegment(o.firstPoint)||!u.isOnSegment(o.lastPoint)?!1:o.segmentType!=="LINE"?u.isOnSegment(o.midPoint):!0,r=o=>e.some(u=>o.isSame(u)||i(o,u));let c=[];for(const o of t)s(o)?(c.push(o),yield new C(c,{ignoreChecks:!0}),c=[]):r(o)?(c.length&&(yield new C(c,{ignoreChecks:!0}),c=[]),yield new C([o],{ignoreChecks:!0})):c.push(o);c.length&&(yield new C(c,{ignoreChecks:!0}))}const bt=(t,n)=>{const e=t.findIndex(r=>l.sameVector(n,r.firstPoint)),s=t.slice(0,e);return t.slice(e).concat(s)},St=(t,n)=>{let e=t;const s=o=>l.sameVector(o.firstPoint,n.firstPoint)&&l.sameVector(o.lastPoint,n.lastPoint);let i=t.findIndex(s);if(i===-1){const o=t.map(u=>u.reverse());if(o.reverse(),i=o.findIndex(s),i===-1)throw console.error(o.map(u=>u.repr),n.repr),new Error("Failed to rotate to segment start");e=o}const r=e.slice(0,i);return e.slice(i).concat(r)};function _n(t,n,e){return t.filter(s=>{const i=n.filter(o=>l.sameVector(o.firstPoint,s)||l.sameVector(o.lastPoint,s));if(i.length%2)throw new Error("Bug in the intersection algo on non crossing point");const r=i.map(o=>e.contains(o.midPoint));return!(r.every(o=>o)||!r.some(o=>o))})}function Tn(t,n,e,s=!1){let i=[];const r=[],c=new Array(t.segments.length).fill(0).map(()=>[]),o=new Array(n.segments.length).fill(0).map(()=>[]);if(t.segments.forEach((d,m)=>{n.segments.forEach((g,w)=>{const{intersections:P,overlaps:I}=R(d,g,e);i.push(...P),c[m].push(...P),o[w].push(...P),r.push(...I);const S=I.flatMap(x=>[x.firstPoint,x.lastPoint]);i.push(...S),c[m].push(...S),o[w].push(...S)})}),i=l.removeDuplicatePoints(i,e),!i.length||i.length===1)return null;const u=([d,m])=>m.length?d.splitAt(m):[d];let f=l.zip([t.segments,c]).flatMap(u),h=l.zip([n.segments,o]).flatMap(u);if(i=_n(i,f,n),!i.length&&!r.length)return null;if(r.length){const d=r[0];f=St(f,d),h=St(h,d)}else{const d=i[0];f=bt(f,d),h=bt(h,d)}let a=Array.from(K(f,i,r)),p=Array.from(K(h,i,r));return(!l.sameVector(p[0].lastPoint,a[0].lastPoint)||r.length>0&&p[0].segmentsCount!==1)&&(p=p.map(d=>d.reverse()).reverse(),l.sameVector(p[0].lastPoint,a[0].lastPoint)||(a=a.map(d=>d.reverse()).reverse())),l.zip([a,p]).map(([d,m])=>{if(s){if((w=>w.segments.every(P=>r.some(I=>P.isSame(I)||P.segmentType===I.segmentType&&I.isOnSegment(P.firstPoint)&&I.isOnSegment(P.lastPoint)&&(P.segmentType==="LINE"||I.isOnSegment(P.midPoint)))))(d))return[d,"same"]}else if(d.segmentsCount===1&&r.some(g=>d.segments[0].isSame(g)))return[d,"same"];return[d,m]})}function yt(t){let n=t[0];for(const e of t.slice(1))n=n.extend(e);if(!l.sameVector(n.firstPoint,n.lastPoint))throw console.error(l.reprVector(n.firstPoint),l.reprVector(n.lastPoint)),new Error("Bug in the intersection algo on non closing strand");return new E(n.segments)}function Vn(t,n){const e=l.zip([n.slice(0,-1),n.slice(1)]).map(([i,r])=>yt(t.slice(i,r)));let s=t.slice(n[n.length-1]);return n[0]!==0&&(s=s.concat(t.slice(0,n[0]))),e.push(yt(s)),e}function qn(t){if(!t.length)return[];const n=t.map(i=>i.firstPoint);let e=t.map(i=>i.lastPoint);e=e.slice(-1).concat(e.slice(0,-1));const s=l.zip([n,e]).flatMap(([i,r],c)=>l.sameVector(i,r)?[]:c);try{return Vn(t,s)}catch{return st(t.flatMap(r=>r.segments)).filter(r=>r.length>1).filter(r=>l.sameVector(r[0].firstPoint,r.at(-1).lastPoint)).map(r=>new E(r))}}const Ct=(t,n)=>{if(t.length===0)return[n];const e=t.at(-1);return l.sameVector(e.lastPoint,n.firstPoint)?t.slice(0,-1).concat([e.extend(n)]):l.sameVector(e.lastPoint,n.lastPoint)?t.slice(0,-1).concat([e.extend(n.reverse())]):t.concat([n])},Dn=(t,n)=>t.length===0?[n]:l.sameVector(t[0].firstPoint,n.lastPoint)?[n.extend(t[0])].concat(t.slice(1)):[n].concat(t);function rt(t,n,{firstInside:e,secondInside:s,firstBoundaryInside:i=!1,secondBoundaryInside:r=!1}){const c=Tn(t,n,void 0,i||r);if(!c){const h=t.segments[0].midPoint,a=n.contains(h,{strokeIsInside:r}),p=n.segments[0].midPoint,d=t.contains(p,{strokeIsInside:i});return{identical:!1,firstCurveInSecond:a,secondCurveInFirst:d}}if(c.every(([,h])=>h==="same"))return{identical:!0};let o=null,u=null;const f=c.flatMap(([h,a])=>{let p=[],d=0;if(a==="same")return u===1?(u=1,h):u===2||u===0?(u=null,[]):u===null?(o?o=o.extend(h):o=h,[]):(console.error("weird situation"),[]);const m=h.segments[0].midPoint,g=n.contains(m,{strokeIsInside:r});(e==="keep"&&g||e==="remove"&&!g)&&(d+=1,p=Ct(p,h));const w=a.segments[0].midPoint,P=t.contains(w,{strokeIsInside:i});if(s==="keep"&&P||s==="remove"&&!P){const I=a;d+=1,d===2&&p.length?(p=Ct(p,I),o=null):p=[I]}return u===null&&d===1&&o&&(p=Dn(p,o)),d===1&&(u=d,o=null),p.length?p:(o=null,[])});return qn(f)}const Rn=(t,n,e)=>{const s=rt(t,n,{firstInside:"remove",secondInside:"remove",...e});return Array.isArray(s)?s:s.identical?[t]:s.firstCurveInSecond?[n]:s.secondCurveInFirst?[t]:[t,n]},Q=(t,n,e)=>{const s=rt(t,n,{firstInside:"remove",secondInside:"keep",...e});return Array.isArray(s)?s:s.identical?[]:s.firstCurveInSecond?[]:s.secondCurveInFirst?[t,n]:[t]},ot=(t,n,e)=>{const s=(e==null?void 0:e.firstBoundaryInside)??!1,i=(e==null?void 0:e.secondBoundaryInside)??!1,r=s||i,c=(u,f,h)=>u.segments.every(a=>f.contains(a.midPoint,{strokeIsInside:h}));if(r){if(c(t,n,i))return[t];if(c(n,t,s))return[n]}const o=rt(t,n,{firstInside:"keep",secondInside:"keep",...e});return Array.isArray(o)?o:o.identical?[t]:o.firstCurveInSecond?[t]:o.secondCurveInFirst?[n]:[]};function Nn(t){const n=new Map,e=[];return t.forEach((s,i)=>{let r;n.has(i)?r=n.get(i):(r={current:[s],fusedWith:new Set([i])},e.push(r)),t.slice(i+1).forEach((c,o)=>{const u=r.current,f=i+o+1;if(r.fusedWith.has(f))return;let h=[c],a=!1;if(n.has(f)&&(h=n.get(f).current,a=!0),!u.some(m=>h.some(g=>m.intersects(g))))return;let d;u.length>1||h.length>1?d=O(u,h):d=qt(u[0],h[0]),r.fusedWith.add(f),r.current=d,a||n.set(f,r)})}),e.flatMap(({current:s})=>s)}function qt(t,n){const e=Rn(t.contour,n.contour),s=n.holes.flatMap(c=>Q(c,t.contour)),i=t.holes.flatMap(c=>Q(c,n.contour)),r=kn(t.holes,n.holes).flatMap(([c,o])=>ot(c,o));return q([...e,...s,...i,...r])}function U(t,n){if(t.isFull&&n.isFull)return q(Q(t.contour,n.contour));if(t.isFull){const s=Q(t.contour,n.contour),i=n.holes.flatMap(r=>ot(r,t.contour,{firstBoundaryInside:!0}));return q([...s,...i])}else if(n.isFull&&!t.contour.intersects(n.contour))if(t.contour.contains(n.contour.firstPoint)){const s=O(t.holes.map(i=>new y(i)),[n]);return q([t.contour,...s.flatMap(i=>i.allLoops)])}else return[t];let e=U(new y(t.contour),n);return t.holes.forEach(s=>{e=e.flatMap(i=>U(i,new y(s)))}),e}function jn(t,n){const e=ot(t.contour,n.contour);if(!e.length)return[];let s=q(e);return s=k(s,t.holes.map(i=>new y(i))),k(s,n.holes.map(i=>new y(i)))}function O(t,n){if(!t.length)return n;if(!n.length)return t;if(t.length===1&&n.length>1||n.length===1&&t.length>1)return Nn([...t,...n]);if(t.length>1&&n.length>1){let e=O([t[0]],n);return t.slice(1).forEach(s=>{e=O([s],e)}),e}return t.length===1&&n.length===1?qt(t[0],n[0]):[]}function k(t,n){if(!t.length)return[];if(!n.length)return t;if(t.length===1&&n.length===1)return U(t[0],n[0]);if(t.length>1)return t.flatMap(s=>k([s],n));let e=U(t[0],n[0]);return n.slice(1).forEach(s=>{e=k(e,[s])}),e}function $(t,n){return!t.length||!n.length?[]:t.length===1&&n.length===1?jn(t[0],n[0]):t.length>1?t.flatMap(e=>$([e],n)):n.flatMap(e=>$(t,[e]))}const Mt=Symbol.for("pantograph:Diagram");class M extends l.Transformable{constructor(e=[],{ignoreChecks:s=!1}={}){super();A(this,"figures");A(this,"_boundingBox",null);Object.defineProperty(this,Mt,{value:!0}),s||Qn(e),this.figures=e}static isInstance(e){return!!e&&e[Mt]===!0}get isEmpty(){return this.figures.length===0}get boundingBox(){if(this.isEmpty)return new l.BoundingBox;if(this._boundingBox===null){let e=this.figures[0].boundingBox;for(const s of this.figures.slice(1))e=e.merge(s.boundingBox);this._boundingBox=e}return this._boundingBox}clone(){return new M(this.figures.map(e=>e.clone()))}transform(e){return new M(this.figures.map(s=>s.transform(e)))}contains(e,{strokeIsInside:s=!1}={}){return this.figures.some(i=>i.contains(e,{strokeIsInside:s}))}intersects(e){return this.figures.some(s=>e.figures.some(i=>s.intersects(i)))}overlappingStrands(e){return this.figures.flatMap(s=>M.isInstance(e)?e.figures.flatMap(i=>s.overlappingStrands(i)):s.overlappingStrands(e))}fuse(e){return new M(O(this.figures,e.figures))}cut(e){return new M(k(this.figures,e.figures))}intersect(e){return new M($(this.figures,e.figures))}}function Qn(t){for(const[n,e]of X(t))if(n.intersects(e))throw new Error("Diagram figures must not intersect")}exports.Diagram=M;exports.Figure=y;exports.Loop=E;exports.Strand=C;exports.arcArcIntersection=Z;exports.cutFiguresLists=k;exports.exportJSON=W;exports.findIntersections=dn;exports.findIntersectionsAndOverlaps=R;exports.fuseFiguresLists=O;exports.intersectFiguresLists=$;exports.isSegment=kt;exports.lineArcIntersection=D;exports.projectPointOnLine=Et;exports.stitchSegments=st;exports.strandsBetweenIntersections=K;
|
|
4
|
+
//# sourceMappingURL=models-Fv9xfQBT.cjs.map
|