pantograph2d 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- "use strict";function H(e,t,n,s){return e<=s&&t>=n}class ${constructor(t=1/0,n=1/0,s=-1/0,i=-1/0){this.xMin=t,this.yMin=n,this.xMax=s,this.yMax=i}get width(){return this.xMax-this.xMin}get height(){return this.yMax-this.yMin}contains(t){const[n,s]=t;return H(this.xMin,this.xMax,n,n)&&H(this.yMin,this.yMax,s,s)}overlaps(t){return H(this.xMin,this.xMax,t.xMin,t.xMax)&&H(this.yMin,this.yMax,t.yMin,t.yMax)}addPoint(t){const[n,s]=t;return new $(Math.min(this.xMin,n),Math.min(this.yMin,s),Math.max(this.xMax,n),Math.max(this.yMax,s))}merge(t){return new $(Math.min(this.xMin,t.xMin),Math.min(this.yMin,t.yMin),Math.max(this.xMax,t.xMax),Math.max(this.yMax,t.yMax))}}const dt=(e,t=1e-9)=>{let n=e;return Math.abs(e)<t&&(n=0),n.toFixed(-Math.log10(t))};function z(e,t=1e-9){return Array.from(new Map(e.map(([n,s])=>[`[${dt(n,t)},${dt(s,t)}]`,[n,s]])).values())}const _t=Math.PI/180,k=e=>`[${e[0]}, ${e[1]}]`,g=([e,t],[n,s],i=1e-9)=>Math.abs(e-n)<=i&&Math.abs(t-s)<=i,A=([e,t],[n,s])=>[e+n,t+s],y=([e,t],[n,s])=>[e-n,t-s],K=([e,t])=>e*e+t*t,I=([e,t],n)=>[e*n,t*n],q=([e,t],[n,s]=[0,0])=>(e-n)**2+(t-s)**2,_=(e,t=[0,0])=>Math.sqrt(q(e,t));function T([e,t],[n,s]){return e*s-t*n}function it([e,t],[n,s]){return e*n+t*s}function V([e,t]){const n=_([e,t]);return[e/n,t/n]}function N(e,t){const n=Math.cos(t)*e,s=Math.sin(t)*e;return[n,s]}function kt([e,t]){return Math.atan2(t,e)}function Ut(e){const t=_(e),n=kt(e);return[t,n]}function Ft(e,t,n=1e-9){const s=T(e,t),i=K(e),r=K(t);return s*s<i*r*n*n}function F(e){return[-e[1],e[0]]}function Q(e){return[e[1],-e[0]]}const D=(e,t)=>{const[n,s,i,r,a,o,u,l,h]=e,[c,f,m,P,w,M,v,x,L]=t;return[n*c+s*P+i*v,n*f+s*w+i*x,n*m+s*M+i*L,r*c+a*P+o*v,r*f+a*w+o*x,r*m+a*M+o*L,u*c+l*P+h*v,u*f+l*w+h*x,u*m+l*M+h*L]};class E{constructor(){this._matrix=[1,0,0,0,1,0,0,0,1]}translate(t,n){return this._matrix=D(this._matrix,[1,0,t,0,1,n,0,0,1]),this}rotate(t,n){const s=Math.cos(t),i=Math.sin(t),r=[s,-i,0,i,s,0,0,0,1];return n&&this.translate(n[0],n[1]),this._matrix=D(this._matrix,r),n&&this.translate(-n[0],-n[1]),this}mirrorX(){return this._matrix=D(this._matrix,[1,0,0,0,-1,0,0,0,1]),this}mirrorY(){return this._matrix=D(this._matrix,[-1,0,0,0,1,0,0,0,1]),this}mirrorLine(t,n){const[s,i]=t,r=Math.atan2(i,s);return n&&this.translate(n[0],n[1]),this.rotate(r),this.mirrorX(),this.rotate(-r),n&&this.translate(-n[0],-n[1]),this}mirrorCenter(t){return t&&this.translate(t[0],t[1]),this._matrix=D(this._matrix,[-1,0,0,0,-1,0,0,0,1]),t&&this.translate(-t[0],-t[1]),this}scale(t,n){return n&&this.translate(n[0],n[1]),this._matrix=D(this._matrix,[t,0,0,0,t,0,0,0,1]),n&&this.translate(-n[0],-n[1]),this}transform(t){const[n,s]=t,[i,r,a,o,u,l]=this._matrix;return[i*n+r*s+a,o*n+u*s+l]}keepsOrientation(){const[t,,,,n]=this._matrix;return t*n>0}}class G{translateX(t){const n=new E().translate(t,0);return this.transform(n)}translateY(t){const n=new E().translate(0,t);return this.transform(n)}translate(t,n){const s=new E().translate(t,n);return this.transform(s)}translateTo([t,n]){const s=new E().translate(t,n);return this.transform(s)}rotate(t,n){const s=new E().rotate(t*_t,n);return this.transform(s)}scale(t,n){const s=new E().scale(t,n);return this.transform(s)}mirrorCenter(t){const n=new E().mirrorCenter(t);return this.transform(n)}mirror(t="x",n){const s=new E;return t==="x"?s.mirrorX():t==="y"?s.mirrorY():s.mirrorLine(t,n),this.transform(s)}}class Et extends G{constructor(t,n){super(),this.firstPoint=t,this.lastPoint=n,this.precision=1e-9,this.firstPoint=t,this.lastPoint=n}get repr(){return`${this.segmentType} ${k(this.firstPoint)} - ${k(this.lastPoint)}`}get info(){return this.repr}[Symbol.for("nodejs.util.inspect.custom")](){return this.repr}}class d extends Et{constructor(){super(...arguments),this.segmentType="LINE",this._V=null,this._boundingBox=null}isValidParameter(t){const n=this.length*this.precision;return t>=-n&&1-t>=-n}paramPoint(t){return A(this.firstPoint,I(this.V,t))}get length(){return _(this.firstPoint,this.lastPoint)}get squareLength(){return q(this.firstPoint,this.lastPoint)}get V(){return this._V===null&&(this._V=y(this.lastPoint,this.firstPoint)),this._V}get midPoint(){return A(this.firstPoint,I(this.V,.5))}isSame(t){return t instanceof d?g(this.firstPoint,t.firstPoint)&&g(this.lastPoint,t.lastPoint)||g(this.lastPoint,t.firstPoint)&&g(this.firstPoint,t.lastPoint):!1}clone(){return new d(this.firstPoint,this.lastPoint)}reverse(){return new d(this.lastPoint,this.firstPoint)}get boundingBox(){return this._boundingBox===null&&(this._boundingBox=new $(Math.min(this.firstPoint[0],this.lastPoint[0])-this.precision,Math.min(this.firstPoint[1],this.lastPoint[1])-this.precision,Math.max(this.firstPoint[0],this.lastPoint[0])+this.precision,Math.max(this.firstPoint[1],this.lastPoint[1])+this.precision)),this._boundingBox}distanceFrom(t){const n=y(t,this.firstPoint),s=it(n,this.V)/this.squareLength;if(s<0)return _(t,this.firstPoint);if(s>1)return _(t,this.lastPoint);const i=this.paramPoint(s);return _(t,i)}isOnSegment(t){if(g(t,this.firstPoint,this.precision))return!0;const n=y(t,this.firstPoint);if(!Ft(this.V,n))return!1;const s=it(n,this.V)/this.squareLength;return this.isValidParameter(s)}tangentAt(t){if(!this.isOnSegment(t))throw new Error("Point is not on segment");return V(this.V)}get normalVector(){return F(V(this.V))}get tangentAtFirstPoint(){return V(this.V)}get tangentAtLastPoint(){return V(this.V)}splitAt(t){let n;if(Array.isArray(t)&&t.length===0)return[this];Array.isArray(t[0])?n=t:n=[t],n.forEach(u=>{if(!this.isOnSegment(u))throw new Error(`Point ${k(u)} is not on segment ${this.repr}`)});const s=[this.firstPoint,...n,this.lastPoint],i=z(s),r=this.lastPoint[0]-this.firstPoint[0];let a=Math.sign(r),o=0;return Math.abs(r)<this.precision&&(a=Math.sign(this.lastPoint[1]-this.firstPoint[1]),o=1),i.sort((u,l)=>a*(u[o]-l[o])),i.flatMap((u,l)=>l===i.length-1?[]:new d(u,i[l+1]))}transform(t){return new d(t.transform(this.firstPoint),t.transform(this.lastPoint))}}function Nt(e){return Array.from(Array(e).keys())}function O(e){const t=Math.min(...e.map(n=>n.length));return Nt(t).map(n=>e.map(s=>s[n]))}function et(e,t=1e-9){return e<0?e+2*Math.PI:e>=2*Math.PI?e%(2*Math.PI):e>2*Math.PI-t?0:e}function Pt(e,t,n,s=1e-9){let i=t-e;return n&&(i=-i),i<0&&(i+=2*Math.PI),i>2*Math.PI-s?0:i}const W=(e,t,n)=>{const s=T(e.V,t.V),i=K(e.V),r=K(t.V),a=n?n*n:e.precision*t.precision;if(s*s<i*r*a)return"parallel";const o=y(t.firstPoint,e.firstPoint),u=T(o,t.V)/s,l=T(o,e.V)/s;return{intersectionParam1:u,intersectionParam2:l}};function Ct(e,t,n=!1,s){const i=W(e,t,s);if(i==="parallel"){if(!n)return null;if(e.isSame(t))return e;const o=z([t.isOnSegment(e.firstPoint)?e.firstPoint:null,t.isOnSegment(e.lastPoint)?e.lastPoint:null,e.isOnSegment(t.firstPoint)?t.firstPoint:null,e.isOnSegment(t.lastPoint)?t.lastPoint:null].filter(u=>u!==null)).sort((u,l)=>u[0]-l[0]);if(o.length===0)return null;if(o.length===1)return null;if(o.length===2)return new d(o[0],o[1]);throw console.error(o),new Error("Unexpected number of points while intersecting parallel lines")}const{intersectionParam1:r,intersectionParam2:a}=i;return!e.isValidParameter(r)||!t.isValidParameter(a)?null:e.paramPoint(r)}const J=(e,t)=>{const n=y(e,t);return Ut(n)};class p extends Et{constructor(t,n,s,i=!1,{ignoreChecks:r=!1}={}){if(super(t,n),this.segmentType="ARC",this._angularLength=null,this._radius=null,this._firstAngle=null,this._lastAngle=null,this._boundingBox=null,this.center=s,this.clockwise=i,!r){if(g(t,n))throw new Error("Invalid arc, cannot be a full circle");if(Math.abs(this.radius-_(this.lastPoint,this.center))>this.precision)throw new Error("Invalid arc, radius does not match between start and end")}}get info(){return`ARC(${k(this.firstPoint)}, ${k(this.lastPoint)}, ${k(this.center)}, ${this.clockwise?"CW":"CCW"})`}isValidParameter(t){return 1-t>=-this.precision&&t>=-this.precision}angleToParam(t){return Pt(this.firstAngle,et(t),this.clockwise)/this.angularLength}get angularLength(){return this._angularLength||(this._angularLength=Pt(this.firstAngle,this.lastAngle,this.clockwise)),this._angularLength}paramPoint(t){return A(this.center,N(this.radius,this.firstAngle+t*this.angularLength*(this.clockwise?-1:1)))}pointToParam(t){const[n,s]=J(t,this.center);if(Math.abs(n-this.radius)>this.precision)throw new Error(`Point ${k(t)} is not on segment ${this.repr}`);const i=this.angleToParam(s);if(!this.isValidParameter(i))throw new Error(`Point ${k(t)} is not on segment ${this.repr}`);return i}get radius(){return this._radius===null&&(this._radius=_(this.firstPoint,this.center)),this._radius}get firstAngle(){if(this._firstAngle===null){const[t,n]=y(this.firstPoint,this.center);this._firstAngle=et(Math.atan2(n,t))}return this._firstAngle}get lastAngle(){if(this._lastAngle===null){const[t,n]=y(this.lastPoint,this.center);this._lastAngle=et(Math.atan2(n,t))}return this._lastAngle}get length(){return this.radius*this.angularLength}get squareLength(){return this.length*this.length}get midPoint(){return this.paramPoint(.5)}isSame(t){return!(t instanceof p)||!g(this.center,t.center)?!1:g(this.firstPoint,t.firstPoint)&&g(this.lastPoint,t.lastPoint)&&this.clockwise===t.clockwise||g(this.lastPoint,t.firstPoint)&&g(this.firstPoint,t.lastPoint)&&this.clockwise===!t.clockwise}clone(){return new p(this.firstPoint,this.lastPoint,this.center,this.clockwise)}reverse(){return new p(this.lastPoint,this.firstPoint,this.center,!this.clockwise)}get boundingBox(){if(this._boundingBox===null){const t=this.radius+this.precision,n=s=>this.isValidParameter(this.angleToParam(s));this._boundingBox=new $(n(Math.PI)?this.center[0]-t:Math.min(this.firstPoint[0],this.lastPoint[0])-this.precision,n(Math.PI*1.5)?this.center[1]-t:Math.min(this.firstPoint[1],this.lastPoint[1])-this.precision,n(0)?this.center[0]+t:Math.max(this.firstPoint[0],this.lastPoint[0])+this.precision,n(Math.PI/2)?this.center[1]+t:Math.max(this.firstPoint[1],this.lastPoint[1])+this.precision)}return this._boundingBox}distanceFrom(t){const[n,s]=J(t,this.center);return this.isValidParameter(this.angleToParam(s))?Math.abs(n-this.radius):Math.sqrt(Math.min(q(t,this.firstPoint),q(t,this.lastPoint)))}isOnSegment(t){if(g(t,this.firstPoint)||g(t,this.lastPoint))return!0;const[n,s]=J(t,this.center);if(Math.abs(n-this.radius)>this.precision)return!1;const i=this.angleToParam(s);return this.isValidParameter(i)}tangentAt(t){const[n,s]=J(t,this.center);if(Math.abs(n-this.radius)>this.precision)throw new Error("Point is not on the arc");const i=this.angleToParam(s);if(!this.isValidParameter(i))throw new Error("Point is not on the arc");const r=N(1,s);return(this.clockwise?Q:F)(V(r))}get tangentAtFirstPoint(){const t=N(1,this.firstAngle);return(this.clockwise?Q:F)(V(t))}get tangentAtLastPoint(){const t=N(1,this.lastAngle);return(this.clockwise?Q:F)(V(t))}splitAt(t){let n;if(Array.isArray(t)&&t.length===0)return[this];Array.isArray(t[0])?n=t:n=[t];const i=[0,1,...n.map(o=>this.pointToParam(o))],r=new Map(O([i,[this.firstPoint,this.lastPoint,...n]]));i.sort((o,u)=>o-u);let a=null;return i.flatMap((o,u)=>{if(u===i.length-1)return[];const l=i[u+1];if(l-o<this.precision)return a===null&&(a=o),[];const h=a===null?o:a,c=new p(r.get(h)||this.paramPoint(h),r.get(l)||this.paramPoint(l),this.center,this.clockwise);return a=null,c})}transform(t){return new p(t.transform(this.firstPoint),t.transform(this.lastPoint),t.transform(this.center),t.keepsOrientation()?this.clockwise:!this.clockwise)}}function Xt(e,t,n){const s=new d(t,e),i=new d(t,n),r=F(s.tangentAtFirstPoint),a=F(i.tangentAtLastPoint),o=W({firstPoint:s.midPoint,V:r,precision:1e-9},{firstPoint:i.midPoint,V:a,precision:1e-9});if(o==="parallel")throw new Error("Cannot create an arc from three colinear points");const u=T(y(e,t),y(n,t))>0;return new p(e,n,A(s.midPoint,I(r,o.intersectionParam1)),u,{ignoreChecks:!0})}function Rt(e,t,n){const s=new d(t,e),i=F(s.tangentAtFirstPoint),r=W({firstPoint:s.midPoint,V:i,precision:1e-9},{firstPoint:e,V:F(n),precision:1e-9});if(r==="parallel")throw new Error("Cannot create an arc from three colinear points");const a=A(s.midPoint,I(i,r.intersectionParam1)),o=T(y(a,e),y(a,A(e,n)))<0;return new p(e,t,a,o,{ignoreChecks:!0})}function Vt(e,t){const n=y(t,e.firstPoint),s=it(n,e.V)/e.squareLength;return e.paramPoint(s)}function R(e,t,n){const s=n||e.precision,i=Vt(e,t.center),r=_(i,t.center);if(r>t.radius+s)return[];if(Math.abs(r-t.radius)<s){const c=i;return e.isOnSegment(c)&&t.isOnSegment(c)?[c]:[]}const a=[],o=Math.sqrt(t.radius*t.radius-r*r),u=e.tangentAtFirstPoint,l=A(i,I(u,o));e.isOnSegment(l)&&t.isOnSegment(l)&&a.push(l);const h=A(i,I(u,-o));return e.isOnSegment(h)&&t.isOnSegment(h)&&a.push(h),a}const jt=e=>{const{firstPoint:t,lastPoint:n,center:s,clockwise:i}=e;return new p(n,t,s,i,{ignoreChecks:!0})},zt=(e,t)=>{if(e.isSame(t))return[e];const n=z([t.isOnSegment(e.firstPoint)?e.firstPoint:null,t.isOnSegment(e.lastPoint)?e.lastPoint:null,e.isOnSegment(t.firstPoint)?t.firstPoint:null,e.isOnSegment(t.lastPoint)?t.lastPoint:null].filter(s=>s!==null)).sort((s,i)=>e.pointToParam(s)-e.pointToParam(i));if(n.length===0)return[];if(n.length===1)return[];if(n.length===2)return e.isSame(jt(t))?[]:[new p(n[0],n[1],e.center,e.clockwise)];if(n.length===3){const s=g(n[0],t.lastPoint)||g(n[0],t.firstPoint)?1:0;return[new p(n[0+s],n[1+s],e.center,e.clockwise)]}else if(n.length===4)return[new p(n[0],n[1],e.center,e.clockwise),new p(n[2],n[3],e.center,e.clockwise)];throw new Error("Bug in the arc arc overlap algorithm")};function lt(e,t,n=!1,s){const i=s||e.precision,r=_(e.center,t.center),a=e.radius+t.radius;if(r>a+i)return[];const o=Math.abs(e.radius-t.radius);if(r<o-i)return[];if(r<i)return o>i?[]:n?zt(e,t):[];const u=V(y(t.center,e.center)),l=r>a-i;if(l||Math.abs(r-o)<i){const v=l||e.radius>t.radius?1:-1,x=A(e.center,I(u,v*e.radius));return e.isOnSegment(x)&&t.isOnSegment(x)?[x]:[]}const h=e.radius*e.radius/(2*r)-t.radius*t.radius/(2*r)+r/2,c=A(e.center,I(u,h)),f=Math.sqrt(e.radius*e.radius-h*h),m=F(u),P=A(c,I(m,f)),w=A(c,I(m,-f)),M=[];return e.isOnSegment(P)&&t.isOnSegment(P)&&M.push(P),e.isOnSegment(w)&&t.isOnSegment(w)&&M.push(w),M}function Gt(e,t,n){if(e instanceof d&&t instanceof d){const s=Ct(e,t,!1,n);return s===null?[]:[s]}if(e instanceof d&&t instanceof p)return R(e,t,n);if(e instanceof p&&t instanceof d)return R(t,e,n);if(e instanceof p&&t instanceof p)return lt(e,t,!1,n);throw new Error("Not implemented")}function j(e,t,n){if(e instanceof d&&t instanceof d){const s=Ct(e,t,!0,n);return s===null?{intersections:[],overlaps:[],count:0}:s instanceof d?{intersections:[],overlaps:[s],count:1}:{intersections:[s],overlaps:[],count:1}}if(!e.boundingBox.overlaps(t.boundingBox))return{intersections:[],overlaps:[],count:0};if(e instanceof d&&t instanceof p){const s=R(e,t,n);return{intersections:s,overlaps:[],count:s.length}}if(e instanceof p&&t instanceof d){const s=R(t,e,n);return{intersections:s,overlaps:[],count:s.length}}if(e instanceof p&&t instanceof p){const s=lt(e,t,!0,n);return s.length?s[0]instanceof p?{intersections:[],overlaps:s,count:s.length}:{intersections:s,overlaps:[],count:s.length}:{intersections:[],overlaps:[],count:0}}throw new Error("Not implemented")}function Bt(e){const t=[];for(let n=0;n<e;n++)for(let s=0;s<=n;s++)t.push([n,s]);return t}function*rt(e){for(const[t,n]of Bt(e.length))t!==n&&(yield[e[t],e[n]])}class Lt extends G{constructor(t,{ignoreChecks:n=!1}={}){super(),this._boundingBox=null,n||Ot(t),this.segments=t}get repr(){return this.segments.map(t=>t.repr).join(`
1
+ "use strict";function H(e,t,n,s){return e<=s&&t>=n}class ${constructor(t=1/0,n=1/0,s=-1/0,i=-1/0){this.xMin=t,this.yMin=n,this.xMax=s,this.yMax=i}get width(){return this.xMax-this.xMin}get height(){return this.yMax-this.yMin}contains(t){const[n,s]=t;return H(this.xMin,this.xMax,n,n)&&H(this.yMin,this.yMax,s,s)}overlaps(t){return H(this.xMin,this.xMax,t.xMin,t.xMax)&&H(this.yMin,this.yMax,t.yMin,t.yMax)}addPoint(t){const[n,s]=t;return new $(Math.min(this.xMin,n),Math.min(this.yMin,s),Math.max(this.xMax,n),Math.max(this.yMax,s))}merge(t){return new $(Math.min(this.xMin,t.xMin),Math.min(this.yMin,t.yMin),Math.max(this.xMax,t.xMax),Math.max(this.yMax,t.yMax))}}const dt=(e,t=1e-9)=>{let n=e;return Math.abs(e)<t&&(n=0),n.toFixed(-Math.log10(t))};function z(e,t=1e-9){return Array.from(new Map(e.map(([n,s])=>[`[${dt(n,t)},${dt(s,t)}]`,[n,s]])).values())}const _t=Math.PI/180,A=e=>`[${e[0]}, ${e[1]}]`,g=([e,t],[n,s],i=1e-9)=>Math.abs(e-n)<=i&&Math.abs(t-s)<=i,S=([e,t],[n,s])=>[e+n,t+s],y=([e,t],[n,s])=>[e-n,t-s],K=([e,t])=>e*e+t*t,_=([e,t],n)=>[e*n,t*n],q=([e,t],[n,s]=[0,0])=>(e-n)**2+(t-s)**2,k=(e,t=[0,0])=>Math.sqrt(q(e,t));function T([e,t],[n,s]){return e*s-t*n}function it([e,t],[n,s]){return e*n+t*s}function V([e,t]){const n=k([e,t]);return[e/n,t/n]}function N(e,t){const n=Math.cos(t)*e,s=Math.sin(t)*e;return[n,s]}function kt([e,t]){return Math.atan2(t,e)}function Ut(e){const t=k(e),n=kt(e);return[t,n]}function Ft(e,t,n=1e-9){const s=T(e,t),i=K(e),r=K(t);return s*s<i*r*n*n}function F(e){return[-e[1],e[0]]}function Q(e){return[e[1],-e[0]]}const D=(e,t)=>{const[n,s,i,r,a,o,u,l,h]=e,[c,f,m,P,w,M,I,x,L]=t;return[n*c+s*P+i*I,n*f+s*w+i*x,n*m+s*M+i*L,r*c+a*P+o*I,r*f+a*w+o*x,r*m+a*M+o*L,u*c+l*P+h*I,u*f+l*w+h*x,u*m+l*M+h*L]};class E{constructor(){this._matrix=[1,0,0,0,1,0,0,0,1]}translate(t,n){return this._matrix=D(this._matrix,[1,0,t,0,1,n,0,0,1]),this}rotate(t,n){const s=Math.cos(t),i=Math.sin(t),r=[s,-i,0,i,s,0,0,0,1];return n&&this.translate(n[0],n[1]),this._matrix=D(this._matrix,r),n&&this.translate(-n[0],-n[1]),this}mirrorX(){return this._matrix=D(this._matrix,[1,0,0,0,-1,0,0,0,1]),this}mirrorY(){return this._matrix=D(this._matrix,[-1,0,0,0,1,0,0,0,1]),this}mirrorLine(t,n){const[s,i]=t,r=Math.atan2(i,s);return n&&this.translate(n[0],n[1]),this.rotate(r),this.mirrorX(),this.rotate(-r),n&&this.translate(-n[0],-n[1]),this}mirrorCenter(t){return t&&this.translate(t[0],t[1]),this._matrix=D(this._matrix,[-1,0,0,0,-1,0,0,0,1]),t&&this.translate(-t[0],-t[1]),this}scale(t,n){return n&&this.translate(n[0],n[1]),this._matrix=D(this._matrix,[t,0,0,0,t,0,0,0,1]),n&&this.translate(-n[0],-n[1]),this}transform(t){const[n,s]=t,[i,r,a,o,u,l]=this._matrix;return[i*n+r*s+a,o*n+u*s+l]}keepsOrientation(){const[t,,,,n]=this._matrix;return t*n>0}}class G{translateX(t){const n=new E().translate(t,0);return this.transform(n)}translateY(t){const n=new E().translate(0,t);return this.transform(n)}translate(t,n){const s=new E().translate(t,n);return this.transform(s)}translateTo([t,n]){const s=new E().translate(t,n);return this.transform(s)}rotate(t,n){const s=new E().rotate(t*_t,n);return this.transform(s)}scale(t,n){const s=new E().scale(t,n);return this.transform(s)}mirrorCenter(t){const n=new E().mirrorCenter(t);return this.transform(n)}mirror(t="x",n){const s=new E;return t==="x"?s.mirrorX():t==="y"?s.mirrorY():s.mirrorLine(t,n),this.transform(s)}}class Et extends G{constructor(t,n){super(),this.firstPoint=t,this.lastPoint=n,this.precision=1e-9,this.firstPoint=t,this.lastPoint=n}get repr(){return`${this.segmentType} ${A(this.firstPoint)} - ${A(this.lastPoint)}`}get info(){return this.repr}[Symbol.for("nodejs.util.inspect.custom")](){return this.repr}}class d extends Et{constructor(){super(...arguments),this.segmentType="LINE",this._V=null,this._boundingBox=null}isValidParameter(t){const n=this.length*this.precision;return t>=-n&&1-t>=-n}paramPoint(t){return S(this.firstPoint,_(this.V,t))}get length(){return k(this.firstPoint,this.lastPoint)}get squareLength(){return q(this.firstPoint,this.lastPoint)}get V(){return this._V===null&&(this._V=y(this.lastPoint,this.firstPoint)),this._V}get midPoint(){return S(this.firstPoint,_(this.V,.5))}isSame(t){return t instanceof d?g(this.firstPoint,t.firstPoint)&&g(this.lastPoint,t.lastPoint)||g(this.lastPoint,t.firstPoint)&&g(this.firstPoint,t.lastPoint):!1}clone(){return new d(this.firstPoint,this.lastPoint)}reverse(){return new d(this.lastPoint,this.firstPoint)}get boundingBox(){return this._boundingBox===null&&(this._boundingBox=new $(Math.min(this.firstPoint[0],this.lastPoint[0])-this.precision,Math.min(this.firstPoint[1],this.lastPoint[1])-this.precision,Math.max(this.firstPoint[0],this.lastPoint[0])+this.precision,Math.max(this.firstPoint[1],this.lastPoint[1])+this.precision)),this._boundingBox}distanceFrom(t){const n=y(t,this.firstPoint),s=it(n,this.V)/this.squareLength;if(s<0)return k(t,this.firstPoint);if(s>1)return k(t,this.lastPoint);const i=this.paramPoint(s);return k(t,i)}isOnSegment(t){if(g(t,this.firstPoint,this.precision))return!0;const n=y(t,this.firstPoint);if(!Ft(this.V,n))return!1;const s=it(n,this.V)/this.squareLength;return this.isValidParameter(s)}tangentAt(t){if(!this.isOnSegment(t))throw new Error("Point is not on segment");return V(this.V)}get normalVector(){return F(V(this.V))}get tangentAtFirstPoint(){return V(this.V)}get tangentAtLastPoint(){return V(this.V)}splitAt(t){let n;if(Array.isArray(t)&&t.length===0)return[this];Array.isArray(t[0])?n=t:n=[t],n.forEach(u=>{if(!this.isOnSegment(u))throw new Error(`Point ${A(u)} is not on segment ${this.repr}`)});const s=[this.firstPoint,...n,this.lastPoint],i=z(s),r=this.lastPoint[0]-this.firstPoint[0];let a=Math.sign(r),o=0;return Math.abs(r)<this.precision&&(a=Math.sign(this.lastPoint[1]-this.firstPoint[1]),o=1),i.sort((u,l)=>a*(u[o]-l[o])),i.flatMap((u,l)=>l===i.length-1?[]:new d(u,i[l+1]))}transform(t){return new d(t.transform(this.firstPoint),t.transform(this.lastPoint))}}function Nt(e){return Array.from(Array(e).keys())}function O(e){const t=Math.min(...e.map(n=>n.length));return Nt(t).map(n=>e.map(s=>s[n]))}function et(e,t=1e-9){return e<0?e+2*Math.PI:e>=2*Math.PI?e%(2*Math.PI):e>2*Math.PI-t?0:e}function Pt(e,t,n,s=1e-9){let i=t-e;return n&&(i=-i),i<0&&(i+=2*Math.PI),i>2*Math.PI-s?0:i}const W=(e,t,n)=>{const s=T(e.V,t.V),i=K(e.V),r=K(t.V),a=n?n*n:e.precision*t.precision;if(s*s<i*r*a)return"parallel";const o=y(t.firstPoint,e.firstPoint),u=T(o,t.V)/s,l=T(o,e.V)/s;return{intersectionParam1:u,intersectionParam2:l}};function Ct(e,t,n=!1,s){const i=W(e,t,s);if(i==="parallel"){if(!n)return null;if(e.isSame(t))return e;const o=z([t.isOnSegment(e.firstPoint)?e.firstPoint:null,t.isOnSegment(e.lastPoint)?e.lastPoint:null,e.isOnSegment(t.firstPoint)?t.firstPoint:null,e.isOnSegment(t.lastPoint)?t.lastPoint:null].filter(u=>u!==null)).sort((u,l)=>u[0]-l[0]);if(o.length===0)return null;if(o.length===1)return null;if(o.length===2)return new d(o[0],o[1]);throw console.error(o),new Error("Unexpected number of points while intersecting parallel lines")}const{intersectionParam1:r,intersectionParam2:a}=i;return!e.isValidParameter(r)||!t.isValidParameter(a)?null:e.paramPoint(r)}const J=(e,t)=>{const n=y(e,t);return Ut(n)};class p extends Et{constructor(t,n,s,i=!1,{ignoreChecks:r=!1}={}){if(super(t,n),this.segmentType="ARC",this._angularLength=null,this._radius=null,this._firstAngle=null,this._lastAngle=null,this._boundingBox=null,this.center=s,this.clockwise=i,!r){if(g(t,n))throw new Error("Invalid arc, cannot be a full circle");if(Math.abs(this.radius-k(this.lastPoint,this.center))>this.precision)throw new Error(`Invalid arc, radius does not match between ${A(t)} and ${A(n)}} (center ${A(s)})`)}}get info(){return`ARC(${A(this.firstPoint)}, ${A(this.lastPoint)}, ${A(this.center)}, ${this.clockwise?"CW":"CCW"})`}isValidParameter(t){return 1-t>=-this.precision&&t>=-this.precision}angleToParam(t){return Pt(this.firstAngle,et(t),this.clockwise)/this.angularLength}get angularLength(){return this._angularLength||(this._angularLength=Pt(this.firstAngle,this.lastAngle,this.clockwise)),this._angularLength}paramPoint(t){return S(this.center,N(this.radius,this.firstAngle+t*this.angularLength*(this.clockwise?-1:1)))}pointToParam(t){const[n,s]=J(t,this.center);if(Math.abs(n-this.radius)>this.precision)throw new Error(`Point ${A(t)} is not on segment ${this.repr}`);const i=this.angleToParam(s);if(!this.isValidParameter(i))throw new Error(`Point ${A(t)} is not on segment ${this.repr}`);return i}get radius(){return this._radius===null&&(this._radius=k(this.firstPoint,this.center)),this._radius}get firstAngle(){if(this._firstAngle===null){const[t,n]=y(this.firstPoint,this.center);this._firstAngle=et(Math.atan2(n,t))}return this._firstAngle}get lastAngle(){if(this._lastAngle===null){const[t,n]=y(this.lastPoint,this.center);this._lastAngle=et(Math.atan2(n,t))}return this._lastAngle}get length(){return this.radius*this.angularLength}get squareLength(){return this.length*this.length}get midPoint(){return this.paramPoint(.5)}isSame(t){return!(t instanceof p)||!g(this.center,t.center)?!1:g(this.firstPoint,t.firstPoint)&&g(this.lastPoint,t.lastPoint)&&this.clockwise===t.clockwise||g(this.lastPoint,t.firstPoint)&&g(this.firstPoint,t.lastPoint)&&this.clockwise===!t.clockwise}clone(){return new p(this.firstPoint,this.lastPoint,this.center,this.clockwise)}reverse(){return new p(this.lastPoint,this.firstPoint,this.center,!this.clockwise)}get boundingBox(){if(this._boundingBox===null){const t=this.radius+this.precision,n=s=>this.isValidParameter(this.angleToParam(s));this._boundingBox=new $(n(Math.PI)?this.center[0]-t:Math.min(this.firstPoint[0],this.lastPoint[0])-this.precision,n(Math.PI*1.5)?this.center[1]-t:Math.min(this.firstPoint[1],this.lastPoint[1])-this.precision,n(0)?this.center[0]+t:Math.max(this.firstPoint[0],this.lastPoint[0])+this.precision,n(Math.PI/2)?this.center[1]+t:Math.max(this.firstPoint[1],this.lastPoint[1])+this.precision)}return this._boundingBox}distanceFrom(t){const[n,s]=J(t,this.center);return this.isValidParameter(this.angleToParam(s))?Math.abs(n-this.radius):Math.sqrt(Math.min(q(t,this.firstPoint),q(t,this.lastPoint)))}isOnSegment(t){if(g(t,this.firstPoint)||g(t,this.lastPoint))return!0;const[n,s]=J(t,this.center);if(Math.abs(n-this.radius)>this.precision)return!1;const i=this.angleToParam(s);return this.isValidParameter(i)}tangentAt(t){const[n,s]=J(t,this.center);if(Math.abs(n-this.radius)>this.precision)throw new Error("Point is not on the arc");const i=this.angleToParam(s);if(!this.isValidParameter(i))throw new Error("Point is not on the arc");const r=N(1,s);return(this.clockwise?Q:F)(V(r))}get tangentAtFirstPoint(){const t=N(1,this.firstAngle);return(this.clockwise?Q:F)(V(t))}get tangentAtLastPoint(){const t=N(1,this.lastAngle);return(this.clockwise?Q:F)(V(t))}splitAt(t){let n;if(Array.isArray(t)&&t.length===0)return[this];Array.isArray(t[0])?n=t:n=[t];const i=[0,1,...n.map(o=>this.pointToParam(o))],r=new Map(O([i,[this.firstPoint,this.lastPoint,...n]]));i.sort((o,u)=>o-u);let a=null;return i.flatMap((o,u)=>{if(u===i.length-1)return[];const l=i[u+1];if(l-o<this.precision)return a===null&&(a=o),[];const h=a===null?o:a,c=new p(r.get(h)||this.paramPoint(h),r.get(l)||this.paramPoint(l),this.center,this.clockwise);return a=null,c})}transform(t){return new p(t.transform(this.firstPoint),t.transform(this.lastPoint),t.transform(this.center),t.keepsOrientation()?this.clockwise:!this.clockwise)}}function Xt(e,t,n){const s=new d(t,e),i=new d(t,n),r=F(s.tangentAtFirstPoint),a=F(i.tangentAtLastPoint),o=W({firstPoint:s.midPoint,V:r,precision:1e-9},{firstPoint:i.midPoint,V:a,precision:1e-9});if(o==="parallel")throw new Error("Cannot create an arc from three colinear points");const u=T(y(e,t),y(n,t))>0;return new p(e,n,S(s.midPoint,_(r,o.intersectionParam1)),u,{ignoreChecks:!0})}function Rt(e,t,n){const s=new d(t,e),i=F(s.tangentAtFirstPoint),r=W({firstPoint:s.midPoint,V:i,precision:1e-9},{firstPoint:e,V:F(n),precision:1e-9});if(r==="parallel")throw new Error("Cannot create an arc from three colinear points");const a=S(s.midPoint,_(i,r.intersectionParam1)),o=T(y(a,e),y(a,S(e,n)))<0;return new p(e,t,a,o,{ignoreChecks:!0})}function Vt(e,t){const n=y(t,e.firstPoint),s=it(n,e.V)/e.squareLength;return e.paramPoint(s)}function R(e,t,n){const s=n||e.precision,i=Vt(e,t.center),r=k(i,t.center);if(r>t.radius+s)return[];if(Math.abs(r-t.radius)<s){const c=i;return e.isOnSegment(c)&&t.isOnSegment(c)?[c]:[]}const a=[],o=Math.sqrt(t.radius*t.radius-r*r),u=e.tangentAtFirstPoint,l=S(i,_(u,o));e.isOnSegment(l)&&t.isOnSegment(l)&&a.push(l);const h=S(i,_(u,-o));return e.isOnSegment(h)&&t.isOnSegment(h)&&a.push(h),a}const jt=e=>{const{firstPoint:t,lastPoint:n,center:s,clockwise:i}=e;return new p(n,t,s,i,{ignoreChecks:!0})},zt=(e,t)=>{if(e.isSame(t))return[e];const n=z([t.isOnSegment(e.firstPoint)?e.firstPoint:null,t.isOnSegment(e.lastPoint)?e.lastPoint:null,e.isOnSegment(t.firstPoint)?t.firstPoint:null,e.isOnSegment(t.lastPoint)?t.lastPoint:null].filter(s=>s!==null)).sort((s,i)=>e.pointToParam(s)-e.pointToParam(i));if(n.length===0)return[];if(n.length===1)return[];if(n.length===2)return e.isSame(jt(t))?[]:[new p(n[0],n[1],e.center,e.clockwise)];if(n.length===3){const s=g(n[0],t.lastPoint)||g(n[0],t.firstPoint)?1:0;return[new p(n[0+s],n[1+s],e.center,e.clockwise)]}else if(n.length===4)return[new p(n[0],n[1],e.center,e.clockwise),new p(n[2],n[3],e.center,e.clockwise)];throw new Error("Bug in the arc arc overlap algorithm")};function lt(e,t,n=!1,s){const i=s||e.precision,r=k(e.center,t.center),a=e.radius+t.radius;if(r>a+i)return[];const o=Math.abs(e.radius-t.radius);if(r<o-i)return[];if(r<i)return o>i?[]:n?zt(e,t):[];const u=V(y(t.center,e.center)),l=r>a-i;if(l||Math.abs(r-o)<i){const I=l||e.radius>t.radius?1:-1,x=S(e.center,_(u,I*e.radius));return e.isOnSegment(x)&&t.isOnSegment(x)?[x]:[]}const h=e.radius*e.radius/(2*r)-t.radius*t.radius/(2*r)+r/2,c=S(e.center,_(u,h)),f=Math.sqrt(e.radius*e.radius-h*h),m=F(u),P=S(c,_(m,f)),w=S(c,_(m,-f)),M=[];return e.isOnSegment(P)&&t.isOnSegment(P)&&M.push(P),e.isOnSegment(w)&&t.isOnSegment(w)&&M.push(w),M}function Gt(e,t,n){if(e instanceof d&&t instanceof d){const s=Ct(e,t,!1,n);return s===null?[]:[s]}if(e instanceof d&&t instanceof p)return R(e,t,n);if(e instanceof p&&t instanceof d)return R(t,e,n);if(e instanceof p&&t instanceof p)return lt(e,t,!1,n);throw new Error("Not implemented")}function j(e,t,n){if(e instanceof d&&t instanceof d){const s=Ct(e,t,!0,n);return s===null?{intersections:[],overlaps:[],count:0}:s instanceof d?{intersections:[],overlaps:[s],count:1}:{intersections:[s],overlaps:[],count:1}}if(!e.boundingBox.overlaps(t.boundingBox))return{intersections:[],overlaps:[],count:0};if(e instanceof d&&t instanceof p){const s=R(e,t,n);return{intersections:s,overlaps:[],count:s.length}}if(e instanceof p&&t instanceof d){const s=R(t,e,n);return{intersections:s,overlaps:[],count:s.length}}if(e instanceof p&&t instanceof p){const s=lt(e,t,!0,n);return s.length?s[0]instanceof p?{intersections:[],overlaps:s,count:s.length}:{intersections:s,overlaps:[],count:s.length}:{intersections:[],overlaps:[],count:0}}throw new Error("Not implemented")}function Bt(e){const t=[];for(let n=0;n<e;n++)for(let s=0;s<=n;s++)t.push([n,s]);return t}function*rt(e){for(const[t,n]of Bt(e.length))t!==n&&(yield[e[t],e[n]])}class Lt extends G{constructor(t,{ignoreChecks:n=!1}={}){super(),this._boundingBox=null,n||Ot(t),this.segments=t}get repr(){return this.segments.map(t=>t.repr).join(`
2
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(t){return this.segments.some(n=>n.isOnSegment(t))}intersects(t){return this.boundingBox.overlaps(t.boundingBox)?this.segments.some(n=>t.segments.some(s=>j(n,s).count>0)):!1}overlappingSegments(t){return this.segments.flatMap(n=>t.segments.flatMap(s=>n.boundingBox.overlaps(s.boundingBox)?j(n,s).overlaps:[]))}get boundingBox(){if(this._boundingBox===null){let t=this.segments[0].boundingBox;this.segments.slice(1).forEach(n=>{t=t.merge(n.boundingBox)}),this._boundingBox=t}return this._boundingBox}[Symbol.for("nodejs.util.inspect.custom")](){return this.repr}}function Wt(e,t="Stroke"){Bt(e.length).forEach(([n,s])=>{if(n===s)return;const i=e[n],r=e[s],a=j(i,r);if(a.count!==0){if(a.count===1&&!a.overlaps.length){const o=n-s,u=a.intersections[0];if(o===1&&g(i.firstPoint,u)||o===-1&&g(i.lastPoint,u)||o===e.length-1&&g(i.lastPoint,u)&&g(r.firstPoint,u)||-o===e.length-1&&g(i.firstPoint,u)&&g(r.lastPoint,u))return}throw new Error(`${t} segments must not intersect, but segments ${i.info} and ${r.info} do at ${JSON.stringify(a.intersections)}`)}})}function Ot(e,t="Stroke"){if(e.length===0)throw new Error(`${t} must have at least one segment`);O([e.slice(0,-1),e.slice(1)]).forEach(([n,s])=>{if(!g(n.lastPoint,s.firstPoint))throw new Error(`${t} segments must be connected, but ${n.info} and ${s.info} are not`)}),Wt(e,t)}function wt(e,t){return!!(e instanceof d&&t instanceof d&&Ft(e.V,t.V)||e instanceof p&&t instanceof p&&g(e.center,t.center)&&e.radius-t.radius<e.precision)}function xt(e,t){if(e instanceof d&&t instanceof d)return new d(e.firstPoint,t.lastPoint);if(e instanceof p&&t instanceof p)return new p(e.firstPoint,t.lastPoint,e.center,e.clockwise);throw new Error("Not implemented")}function Tt(e){let t=!1;const n=[];for(const s of e.segments){if(n.length===0){n.push(s);continue}const i=n[n.length-1];wt(i,s)?(t=!0,n.pop(),n.push(xt(i,s))):n.push(s)}if(g(e.firstPoint,e.lastPoint)&&wt(n[0],n[n.length-1])){t=!0;const s=n.pop();n[0]=xt(s,n[0])}return t?n:null}class b extends Lt{constructor(){super(...arguments),this.strokeType="STRAND"}reverse(){const t=this.segments.map(n=>n.reverse());return t.reverse(),new b(t,{ignoreChecks:!0})}clone(){return new b(this.segments.map(t=>t.clone()),{ignoreChecks:!0})}extend(t){if(!g(this.lastPoint,t.firstPoint))throw console.error(this.repr,t.repr),new Error("Cannot extend strand: connection point is not the same");return new b([...this.segments,...t.segments])}simplify(){const t=Tt(this);return t?new b(t,{ignoreChecks:!0}):this}transform(t){return new b(this.segments.map(n=>n.transform(t)),{ignoreChecks:!0})}}const Ht=(e,t)=>{const n=W(t,{V:[1,0],firstPoint:e,precision:t.precision});if(n==="parallel")return 0;const{intersectionParam1:s,intersectionParam2:i}=n;if(!t.isValidParameter(s)||i<=-t.precision)return 0;if(Math.abs(s)<t.precision||Math.abs(s-1)<t.precision){const[,r]=t.midPoint;return e[1]-r<0?1:0}return 1},Jt=(e,t)=>{const n=t.precision,s=Math.abs(e[1]-t.center[1]);if(s>t.radius+n)return 0;const i=q(e,t.center),r=t.radius*t.radius,a=n*n;if(Math.abs(i-r)<a&&t.isOnSegment(e))return 0;const o=i-r>a;if(o&&t.center[0]<e[0])return 0;const u=Math.sqrt(t.radius*t.radius-s*s);let l=0;const h=c=>{t.isOnSegment(c)&&(g(c,t.firstPoint)?l+=t.tangentAtFirstPoint[1]>0?1:0:g(c,t.lastPoint)?l+=t.tangentAtLastPoint[1]>0?0:1:l+=1)};return h([t.center[0]+u,e[1]]),o&&h([t.center[0]-u,e[1]]),l};function Qt(e,t){if(t instanceof d)return Ht(e,t);if(t instanceof p)return Jt(e,t);throw new Error("Not implemented")}class B extends Lt{constructor(t,{ignoreChecks:n=!1}={}){super(t,{ignoreChecks:!0}),this.strokeType="LOOP",this._clockwise=null,n||Kt(t)}get clockwise(){if(this._clockwise===null){const t=this.segments.flatMap(s=>s instanceof d?[s.firstPoint]:[s.firstPoint,s.paramPoint(.5)]),n=t.map((s,i)=>{const r=t[(i+1)%t.length];return(r[0]-s[0])*(r[1]+s[1])}).reduce((s,i)=>s+i,0);this._clockwise=n>0}return this._clockwise}clone(){return new B(this.segments.map(t=>t.clone()),{ignoreChecks:!0})}reverse(){const t=this.segments.map(n=>n.reverse());return t.reverse(),new B(t,{ignoreChecks:!0})}transform(t){return new B(this.segments.map(n=>n.transform(t)),{ignoreChecks:!0})}contains(t){return this.onStroke(t)||!this.boundingBox.contains(t)?!1:this.segments.reduce((s,i)=>s+Qt(t,i),0)%2===1}simplify(){const t=Tt(this);return t?new B(t,{ignoreChecks:!0}):this}}function Kt(e){if(Ot(e,"Loop"),!g(e[0].firstPoint,e[e.length-1].lastPoint))throw new Error("Loop segment must be closed")}function $t(e){if(e instanceof d)return{type:e.segmentType,firstPoint:e.firstPoint,lastPoint:e.lastPoint};if(e instanceof p)return{type:e.segmentType,firstPoint:e.firstPoint,lastPoint:e.lastPoint,center:e.center,clockwise:e.clockwise};throw new Error("Unknown segment type")}function ot(e){return{type:"LOOP",segments:e.segments.map($t)}}function Dt(e){return{type:"FIGURE",contour:ot(e.contour),holes:e.holes.map(ot)}}function Zt(e){return{type:"DIAGRAM",figures:e.figures.map(Dt)}}function at(e){if(e instanceof C)return Zt(e);if(e instanceof S)return Dt(e);if(e instanceof B)return ot(e);if(e instanceof p||e instanceof d)return $t(e);throw new Error("Unknown shape type")}class tn{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,n){let s=this.length++;for(;s>0;){const i=s-1>>1,r=this.values[i];if(n>=r)break;this.ids[s]=this.ids[i],this.values[s]=r,s=i}this.ids[s]=t,this.values[s]=n}pop(){if(this.length===0)return;const t=this.ids[0];if(this.length--,this.length>0){const n=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 a=(r<<1)+1;const o=a+1;let u=this.ids[a],l=this.values[a];const h=this.values[o];if(o<this.length&&h<l&&(a=o,u=this.ids[o],l=h),l>=s)break;this.ids[r]=u,this.values[r]=l,r=a}this.ids[r]=n,this.values[r]=s}return t}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 Mt=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],st=3;class ct{static from(t){if(!t||t.byteLength===void 0||t.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[n,s]=new Uint8Array(t,0,2);if(n!==251)throw new Error("Data does not appear to be in a Flatbush format.");if(s>>4!==st)throw new Error(`Got v${s>>4} data when expected v${st}.`);const[i]=new Uint16Array(t,2,1),[r]=new Uint32Array(t,4,1);return new ct(r,i,Mt[s&15],void 0,t)}constructor(t,n=16,s=Float64Array,i=ArrayBuffer,r){if(t===void 0)throw new Error("Missing required argument: numItems.");if(isNaN(t)||t<=0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+n,2),65535);let a=t,o=a;this._levelBounds=[a*4];do a=Math.ceil(a/this.nodeSize),o+=a,this._levelBounds.push(o*4);while(a!==1);this.ArrayType=s||Float64Array,this.IndexArrayType=o<16384?Uint16Array:Uint32Array;const u=Mt.indexOf(this.ArrayType),l=o*4*this.ArrayType.BYTES_PER_ELEMENT;if(u<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,8,o*4),this._indices=new this.IndexArrayType(this.data,8+l,o),this._pos=o*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+l+o*this.IndexArrayType.BYTES_PER_ELEMENT),this._boxes=new this.ArrayType(this.data,8,o*4),this._indices=new this.IndexArrayType(this.data,8+l,o),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,(st<<4)+u]),new Uint16Array(this.data,2,1)[0]=n,new Uint32Array(this.data,4,1)[0]=t),this._queue=new tn}add(t,n,s,i){const r=this._pos>>2,a=this._boxes;return this._indices[r]=r,a[this._pos++]=t,a[this._pos++]=n,a[this._pos++]=s,a[this._pos++]=i,t<this.minX&&(this.minX=t),n<this.minY&&(this.minY=n),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 t=this._boxes;if(this.numItems<=this.nodeSize){t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,t[this._pos++]=this.maxY;return}const n=this.maxX-this.minX||1,s=this.maxY-this.minY||1,i=new Uint32Array(this.numItems),r=(1<<16)-1;for(let a=0,o=0;a<this.numItems;a++){const u=t[o++],l=t[o++],h=t[o++],c=t[o++],f=Math.floor(r*((u+h)/2-this.minX)/n),m=Math.floor(r*((l+c)/2-this.minY)/s);i[a]=en(f,m)}ut(i,t,this._indices,0,this.numItems-1,this.nodeSize);for(let a=0,o=0;a<this._levelBounds.length-1;a++){const u=this._levelBounds[a];for(;o<u;){const l=o;let h=t[o++],c=t[o++],f=t[o++],m=t[o++];for(let P=1;P<this.nodeSize&&o<u;P++)h=Math.min(h,t[o++]),c=Math.min(c,t[o++]),f=Math.max(f,t[o++]),m=Math.max(m,t[o++]);this._indices[this._pos>>2]=l,t[this._pos++]=h,t[this._pos++]=c,t[this._pos++]=f,t[this._pos++]=m}}}search(t,n,s,i,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let a=this._boxes.length-4;const o=[],u=[];for(;a!==void 0;){const l=Math.min(a+this.nodeSize*4,At(a,this._levelBounds));for(let h=a;h<l;h+=4){if(s<this._boxes[h]||i<this._boxes[h+1]||t>this._boxes[h+2]||n>this._boxes[h+3])continue;const c=this._indices[h>>2]|0;a>=this.numItems*4?o.push(c):(r===void 0||r(c))&&u.push(c)}a=o.pop()}return u}neighbors(t,n,s=1/0,i=1/0,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let a=this._boxes.length-4;const o=this._queue,u=[],l=i*i;for(;a!==void 0;){const h=Math.min(a+this.nodeSize*4,At(a,this._levelBounds));for(let c=a;c<h;c+=4){const f=this._indices[c>>2]|0,m=yt(t,this._boxes[c],this._boxes[c+2]),P=yt(n,this._boxes[c+1],this._boxes[c+3]),w=m*m+P*P;a>=this.numItems*4?o.push(f<<1,w):(r===void 0||r(f))&&o.push((f<<1)+1,w)}for(;o.length&&o.peek()&1;)if(o.peekValue()>l||(u.push(o.pop()>>1),u.length===s))return o.clear(),u;a=o.pop()>>1}return o.clear(),u}}function yt(e,t,n){return e<t?t-e:e<=n?0:e-n}function At(e,t){let n=0,s=t.length-1;for(;n<s;){const i=n+s>>1;t[i]>e?s=i:n=i+1}return t[n]}function ut(e,t,n,s,i,r){if(Math.floor(s/r)>=Math.floor(i/r))return;const a=e[s+i>>1];let o=s-1,u=i+1;for(;;){do o++;while(e[o]<a);do u--;while(e[u]>a);if(o>=u)break;nn(e,t,n,o,u)}ut(e,t,n,s,u,r),ut(e,t,n,u+1,i,r)}function nn(e,t,n,s,i){const r=e[s];e[s]=e[i],e[i]=r;const a=4*s,o=4*i,u=t[a],l=t[a+1],h=t[a+2],c=t[a+3];t[a]=t[o],t[a+1]=t[o+1],t[a+2]=t[o+2],t[a+3]=t[o+3],t[o]=u,t[o+1]=l,t[o+2]=h,t[o+3]=c;const f=n[s];n[s]=n[i],n[i]=f}function en(e,t){let n=e^t,s=65535^n,i=65535^(e|t),r=e&(t^65535),a=n|s>>1,o=n>>1^n,u=i>>1^s&r>>1^i,l=n&i>>1^r>>1^r;n=a,s=o,i=u,r=l,a=n&n>>2^s&s>>2,o=n&s>>2^s&(n^s)>>2,u^=n&i>>2^s&r>>2,l^=s&i>>2^(n^s)&r>>2,n=a,s=o,i=u,r=l,a=n&n>>4^s&s>>4,o=n&s>>4^s&(n^s)>>4,u^=n&i>>4^s&r>>4,l^=s&i>>4^(n^s)&r>>4,n=a,s=o,i=u,r=l,u^=n&i>>8^s&r>>8,l^=s&i>>8^(n^s)&r>>8,n=u^u>>1,s=l^l>>1;let h=e^t,c=s|65535^(h|n);return h=(h|h<<8)&16711935,h=(h|h<<4)&252645135,h=(h|h<<2)&858993459,h=(h|h<<1)&1431655765,c=(c|c<<8)&16711935,c=(c|c<<4)&252645135,c=(c|c<<2)&858993459,c=(c|c<<1)&1431655765,(c<<1|h)>>>0}function ft(e,t=1e-7){const n=new ct(e.length);e.forEach(r=>{const[a,o]=r.firstPoint;n.add(a-t,o-t,a+t,o+t)}),n.finish();const s=[],i=new Set;return e.forEach((r,a)=>{if(i.has(a))return;const o=[r];let u=a;i.add(a);let l=e.length;for(;;){if(l--<0)throw new Error("Infinite loop detected");const h=o[o.length-1].lastPoint,[c,f]=h,m=n.search(c-t,f-t,c+t,f+t),P=x=>Math.abs((u-x)%e.length),w=m.filter(x=>!i.has(x)).map(x=>[e[x],x,P(x)]).sort(([,,x],[,,L])=>P(x)-P(L));if(w.length===0){s.push(o);break}const[M,v]=w[0];o.push(M),i.add(v),u=v}}),s}class S extends G{constructor(t,n=[],{ignoreChecks:s=!1}={}){super(),s||sn(t,n),this.contour=t,this.holes=n}get boundingBox(){return this.contour.boundingBox}get isFull(){return this.holes.length===0}get allLoops(){return[this.contour,...this.holes]}clone(){return new S(this.contour.clone(),this.holes.map(t=>t.clone()))}transform(t){return new S(this.contour.transform(t),this.holes.map(n=>n.transform(t)))}contains(t){return this.contour.contains(t)&&!this.holes.some(n=>n.contains(t))}intersects(t){return this.allLoops.some(n=>t.allLoops.some(s=>n.intersects(s)))}overlappingStrands(t){const n=t instanceof S?t.allLoops:[t],s=this.allLoops.flatMap(i=>n.flatMap(r=>i.overlappingSegments(r)));return ft(s).map(i=>new b(i))}}function sn(e,t=[]){if(!e)throw new Error("Figure must have a contour");for(const[n,s]of rt([e,...t]))if(n.intersects(s))throw new Error("Loops in a figure must not intersect");if(t.some(n=>!e.contains(n.firstPoint)&&!e.onStroke(n.firstPoint)))throw new Error("Holes must be inside the contour");for(const[n,s]of rt(t))if(n.contains(s.firstPoint))throw console.error(at(n),at(s)),new Error("Holes must not be inside other holes")}const rn=e=>{const t=e.map((i,r)=>e.slice(r+1).map((a,o)=>[o+r+1,a]).filter(([,a])=>i.boundingBox.overlaps(a.boundingBox)).map(([a])=>a)),n=[],s=Array(t.length);return t.forEach((i,r)=>{let a=s[r];a||(a=[],n.push(a)),a.push(e[r]),i.length&&i.forEach(o=>{s[o]=a})}),n},qt=e=>e.map((t,n)=>{const i=t.segments[0].midPoint,r=e.filter((a,o)=>n===o?!1:a.contains(i));return{loop:t,isIn:r}}),on=(e,t)=>e.flatMap(({loop:n})=>gt(t.filter(({loop:s,isIn:i})=>s===n||i.indexOf(n)!==-1))),an=(e,t)=>{const n=t.filter(({isIn:i})=>i.length<=1),s=gt(qt(e.map(({loop:i})=>i)));return[n,...s]},gt=e=>{if(!e.length)return[];const t=e.filter(({isIn:s})=>!s.length),n=e.filter(({isIn:s})=>s.length>1);return t.length===1&&n.length===0?[e]:t.length>1?on(t,e):an(n,e)};function X(e){return rn(e).map(qt).flatMap(gt).map(n=>{if(n.length===1)return new S(n[0].loop);n.sort((r,a)=>r.isIn.length-a.isIn.length);const[s,...i]=n.map(({loop:r})=>r);return new S(s,i)})}function un(e,t){const n=[];for(const s of e)for(const i of t)n.push([s,i]);return n}function*ht(e,t,n){const s=a=>t.some(o=>g(o,a.lastPoint)),i=a=>n.some(o=>a.isSame(o));let r=[];for(const a of e)s(a)?(r.push(a),yield new b(r,{ignoreChecks:!0}),r=[]):i(a)?(r.length&&(yield new b(r,{ignoreChecks:!0}),r=[]),yield new b([a],{ignoreChecks:!0})):r.push(a);r.length&&(yield new b(r,{ignoreChecks:!0}))}const St=(e,t)=>{const n=e.findIndex(r=>g(t,r.firstPoint)),s=e.slice(0,n);return e.slice(n).concat(s)},bt=(e,t)=>{let n=e;const s=o=>g(o.firstPoint,t.firstPoint)&&g(o.lastPoint,t.lastPoint);let i=e.findIndex(s);if(i===-1){const o=e.map(u=>u.reverse());if(o.reverse(),i=o.findIndex(s),i===-1)throw console.error(o.map(u=>u.repr),t.repr),new Error("Failed to rotate to segment start");n=o}const r=n.slice(0,i);return n.slice(i).concat(r)};function hn(e,t,n){return e.filter(s=>{const i=t.filter(o=>g(o.firstPoint,s)||g(o.lastPoint,s));if(i.length%2)throw new Error("Bug in the intersection algo on non crossing point");const r=i.map(o=>n.contains(o.midPoint));return!(r.every(o=>o)||!r.some(o=>o))})}function ln(e,t,n){let s=[];const i=[],r=new Array(e.segments.length).fill(0).map(()=>[]),a=new Array(t.segments.length).fill(0).map(()=>[]);if(e.segments.forEach((f,m)=>{t.segments.forEach((P,w)=>{const{intersections:M,overlaps:v}=j(f,P,n);s.push(...M),r[m].push(...M),a[w].push(...M),i.push(...v);const x=v.flatMap(L=>[L.firstPoint,L.lastPoint]);s.push(...x),r[m].push(...x),a[w].push(...x)})}),s=z(s,n),!s.length||s.length===1)return null;const o=([f,m])=>m.length?f.splitAt(m):[f];let u=O([e.segments,r]).flatMap(o),l=O([t.segments,a]).flatMap(o);if(s=hn(s,u,t),!s.length&&!i.length)return null;if(i.length){const f=i[0];u=bt(u,f),l=bt(l,f)}else{const f=s[0];u=St(u,f),l=St(l,f)}let h=Array.from(ht(u,s,i)),c=Array.from(ht(l,s,i));return(!g(c[0].lastPoint,h[0].lastPoint)||i.length>0&&c[0].segmentsCount!==1)&&(c=c.map(f=>f.reverse()).reverse(),g(c[0].lastPoint,h[0].lastPoint)||(h=h.map(f=>f.reverse()).reverse())),O([h,c]).map(([f,m])=>f.segmentsCount===1&&i.some(P=>f.segments[0].isSame(P))?[f,"same"]:[f,m])}function vt(e){let t=e[0];for(const n of e.slice(1))t=t.extend(n);if(!g(t.firstPoint,t.lastPoint))throw console.error(k(t.firstPoint),k(t.lastPoint)),new Error("Bug in the intersection algo on non closing strand");return new B(t.segments)}function cn(e,t){const n=O([t.slice(0,-1),t.slice(1)]).map(([i,r])=>vt(e.slice(i,r)));let s=e.slice(t[t.length-1]);return t[0]!==0&&(s=s.concat(e.slice(0,t[0]))),n.push(vt(s)),n}function fn(e){if(!e.length)return[];const t=e.map(i=>i.firstPoint);let n=e.map(i=>i.lastPoint);n=n.slice(-1).concat(n.slice(0,-1));const s=O([t,n]).flatMap(([i,r],a)=>g(i,r)?[]:a);try{return cn(e,s)}catch{return ft(e.flatMap(r=>r.segments)).filter(r=>r.length>1).filter(r=>g(r[0].firstPoint,r.at(-1).lastPoint)).map(r=>new B(r))}}const It=(e,t)=>{if(e.length===0)return[t];const n=e.at(-1);return g(n.lastPoint,t.firstPoint)?e.slice(0,-1).concat([n.extend(t)]):g(n.lastPoint,t.lastPoint)?e.slice(0,-1).concat([n.extend(t.reverse())]):e.concat([t])},gn=(e,t)=>e.length===0?[t]:g(e[0].firstPoint,t.lastPoint)?[t.extend(e[0])].concat(e.slice(1)):[t].concat(e);function mt(e,t,{firstInside:n,secondInside:s}){const i=ln(e,t);if(!i){const u=e.segments[0].midPoint,l=t.contains(u),h=t.segments[0].midPoint,c=e.contains(h);return{identical:!1,firstCurveInSecond:l,secondCurveInFirst:c}}if(i.every(([,u])=>u==="same"))return{identical:!0};let r=null,a=null;const o=i.flatMap(([u,l])=>{let h=[],c=0;if(l==="same")return a===1?(a=1,u):a===2||a===0?(a=null,[]):a===null?(r?r=r.extend(u):r=u,[]):(console.error("weird situation"),[]);const f=u.segments[0].midPoint,m=t.contains(f);(n==="keep"&&m||n==="remove"&&!m)&&(c+=1,h=It(h,u));const P=l.segments[0].midPoint,w=e.contains(P);if(s==="keep"&&w||s==="remove"&&!w){const M=l;c+=1,c===2&&h.length?(h=It(h,M),r=null):h=[M]}return a===null&&c===1&&r&&(h=gn(h,r)),c===1&&(a=c,r=null),h.length?h:(r=null,[])});return fn(o)}const mn=(e,t)=>{const n=mt(e,t,{firstInside:"remove",secondInside:"remove"});return Array.isArray(n)?n:n.identical?[e]:n.firstCurveInSecond?[t]:n.secondCurveInFirst?[e]:[e,t]},Z=(e,t)=>{const n=mt(e,t,{firstInside:"remove",secondInside:"keep"});return Array.isArray(n)?n:n.identical?[]:n.firstCurveInSecond?[]:n.secondCurveInFirst?[e,t]:[e]},pt=(e,t)=>{const n=mt(e,t,{firstInside:"keep",secondInside:"keep"});return Array.isArray(n)?n:n.identical?[e]:n.firstCurveInSecond?[e]:n.secondCurveInFirst?[t]:[]};function pn(e){const t=new Map,n=[];return e.forEach((s,i)=>{let r;t.has(i)?r=t.get(i):(r={current:[s],fusedWith:new Set([i])},n.push(r)),e.slice(i+1).forEach((a,o)=>{const u=r.current,l=i+o+1;if(r.fusedWith.has(l))return;let h=[a],c=!1;if(t.has(l)&&(h=t.get(l).current,c=!0),!u.some(P=>h.some(w=>P.intersects(w))))return;let m;u.length>1||h.length>1?m=Y(u,h):m=Yt(u[0],h[0]),r.fusedWith.add(l),r.current=m,c||t.set(l,r)})}),n.flatMap(({current:s})=>s)}function Yt(e,t){const n=mn(e.contour,t.contour),s=t.holes.flatMap(a=>Z(a,e.contour)),i=e.holes.flatMap(a=>Z(a,t.contour)),r=un(e.holes,t.holes).flatMap(([a,o])=>pt(a,o));return X([...n,...s,...i,...r])}function tt(e,t){if(e.isFull&&t.isFull)return X(Z(e.contour,t.contour));if(e.isFull){const s=Z(e.contour,t.contour),i=t.holes.flatMap(r=>pt(r,e.contour));return X([...s,...i])}else if(t.isFull&&!e.contour.intersects(t.contour))if(e.contour.contains(t.contour.firstPoint)){const s=Y(e.holes.map(i=>new S(i)),[t]);return X([e.contour,...s.flatMap(i=>i.allLoops)])}else return[e];let n=tt(new S(e.contour),t);return e.holes.forEach(s=>{n=n.flatMap(i=>tt(i,new S(s)))}),n}function dn(e,t){const n=pt(e.contour,t.contour);if(!n.length)return[];let s=X(n);return s=U(s,e.holes.map(i=>new S(i))),U(s,t.holes.map(i=>new S(i)))}function Y(e,t){if(!e.length)return t;if(!t.length)return e;if(e.length===1&&t.length>1||t.length===1&&e.length>1)return pn([...e,...t]);if(e.length>1&&t.length>1){let n=Y([e[0]],t);return e.slice(1).forEach(s=>{n=Y([s],n)}),n}return e.length===1&&t.length===1?Yt(e[0],t[0]):[]}function U(e,t){if(!e.length)return[];if(!t.length)return e;if(e.length===1&&t.length===1)return tt(e[0],t[0]);if(e.length>1)return e.flatMap(s=>U([s],t));let n=tt(e[0],t[0]);return t.slice(1).forEach(s=>{n=U(n,[s])}),n}function nt(e,t){return!e.length||!t.length?[]:e.length===1&&t.length===1?dn(e[0],t[0]):e.length>1?e.flatMap(n=>nt([n],t)):t.flatMap(n=>nt(e,[n]))}class C extends G{constructor(t=[],{ignoreChecks:n=!1}={}){super(),this._boundingBox=null,n||Pn(t),this.figures=t}get isEmpty(){return this.figures.length===0}get boundingBox(){if(this.isEmpty)return new $;if(this._boundingBox===null){let t=this.figures[0].boundingBox;for(const n of this.figures.slice(1))t=t.merge(n.boundingBox);this._boundingBox=t}return this._boundingBox}clone(){return new C(this.figures.map(t=>t.clone()))}transform(t){return new C(this.figures.map(n=>n.transform(t)))}contains(t){return this.figures.some(n=>n.contains(t))}intersects(t){return this.figures.some(n=>t.figures.some(s=>n.intersects(s)))}overlappingStrands(t){return this.figures.flatMap(n=>t instanceof C?t.figures.flatMap(s=>n.overlappingStrands(s)):n.overlappingStrands(t))}fuse(t){return new C(Y(this.figures,t.figures))}cut(t){return new C(U(this.figures,t.figures))}intersect(t){return new C(nt(this.figures,t.figures))}}function Pn(e){for(const[t,n]of rt(e))if(t.intersects(n))throw new Error("Diagram figures must not intersect")}exports.Arc=p;exports.BoundingBox=$;exports.DEG2RAD=_t;exports.Diagram=C;exports.Figure=S;exports.Line=d;exports.Loop=B;exports.Strand=b;exports.Transformable=G;exports.TransformationMatrix=E;exports.add=A;exports.arcArcIntersection=lt;exports.crossProduct=T;exports.cutFiguresLists=U;exports.distance=_;exports.exportJSON=at;exports.findIntersections=Gt;exports.findIntersectionsAndOverlaps=j;exports.fuseFiguresLists=Y;exports.intersectFiguresLists=nt;exports.lineArcIntersection=R;exports.lineLineParams=W;exports.normalize=V;exports.perpendicular=F;exports.perpendicularClockwise=Q;exports.polarAngle=kt;exports.polarToCartesian=N;exports.projectPointOnLine=Vt;exports.removeDuplicatePoints=z;exports.sameVector=g;exports.scalarMultiply=I;exports.squareDistance=q;exports.stitchSegments=ft;exports.strandsBetweenIntersections=ht;exports.subtract=y;exports.tangentArc=Rt;exports.threePointsArc=Xt;exports.zip=O;
4
- //# sourceMappingURL=Diagram-4fa55d2b.cjs.map
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(t){return this.segments.some(n=>n.isOnSegment(t))}intersects(t){return this.boundingBox.overlaps(t.boundingBox)?this.segments.some(n=>t.segments.some(s=>j(n,s).count>0)):!1}overlappingSegments(t){return this.segments.flatMap(n=>t.segments.flatMap(s=>n.boundingBox.overlaps(s.boundingBox)?j(n,s).overlaps:[]))}get boundingBox(){if(this._boundingBox===null){let t=this.segments[0].boundingBox;this.segments.slice(1).forEach(n=>{t=t.merge(n.boundingBox)}),this._boundingBox=t}return this._boundingBox}[Symbol.for("nodejs.util.inspect.custom")](){return this.repr}}function Wt(e,t="Stroke"){Bt(e.length).forEach(([n,s])=>{if(n===s)return;const i=e[n],r=e[s],a=j(i,r);if(a.count!==0){if(a.count===1&&!a.overlaps.length){const o=n-s,u=a.intersections[0];if(o===1&&g(i.firstPoint,u)||o===-1&&g(i.lastPoint,u)||o===e.length-1&&g(i.lastPoint,u)&&g(r.firstPoint,u)||-o===e.length-1&&g(i.firstPoint,u)&&g(r.lastPoint,u))return}throw new Error(`${t} segments must not intersect, but segments ${i.info} and ${r.info} do at ${JSON.stringify(a.intersections)}`)}})}function Ot(e,t="Stroke"){if(e.length===0)throw new Error(`${t} must have at least one segment`);O([e.slice(0,-1),e.slice(1)]).forEach(([n,s])=>{if(!g(n.lastPoint,s.firstPoint))throw new Error(`${t} segments must be connected, but ${n.info} and ${s.info} are not`)}),Wt(e,t)}function wt(e,t){return!!(e instanceof d&&t instanceof d&&Ft(e.V,t.V)||e instanceof p&&t instanceof p&&g(e.center,t.center)&&e.radius-t.radius<e.precision)}function xt(e,t){if(e instanceof d&&t instanceof d)return new d(e.firstPoint,t.lastPoint);if(e instanceof p&&t instanceof p)return new p(e.firstPoint,t.lastPoint,e.center,e.clockwise);throw new Error("Not implemented")}function Tt(e){let t=!1;const n=[];for(const s of e.segments){if(n.length===0){n.push(s);continue}const i=n[n.length-1];wt(i,s)?(t=!0,n.pop(),n.push(xt(i,s))):n.push(s)}if(g(e.firstPoint,e.lastPoint)&&wt(n[0],n[n.length-1])){t=!0;const s=n.pop();n[0]=xt(s,n[0])}return t?n:null}class v extends Lt{constructor(){super(...arguments),this.strokeType="STRAND"}reverse(){const t=this.segments.map(n=>n.reverse());return t.reverse(),new v(t,{ignoreChecks:!0})}clone(){return new v(this.segments.map(t=>t.clone()),{ignoreChecks:!0})}extend(t){if(!g(this.lastPoint,t.firstPoint))throw console.error(this.repr,t.repr),new Error("Cannot extend strand: connection point is not the same");return new v([...this.segments,...t.segments])}simplify(){const t=Tt(this);return t?new v(t,{ignoreChecks:!0}):this}transform(t){return new v(this.segments.map(n=>n.transform(t)),{ignoreChecks:!0})}}const Ht=(e,t)=>{const n=W(t,{V:[1,0],firstPoint:e,precision:t.precision});if(n==="parallel")return 0;const{intersectionParam1:s,intersectionParam2:i}=n;if(!t.isValidParameter(s)||i<=-t.precision)return 0;if(Math.abs(s)<t.precision||Math.abs(s-1)<t.precision){const[,r]=t.midPoint;return e[1]-r<0?1:0}return 1},Jt=(e,t)=>{const n=t.precision,s=Math.abs(e[1]-t.center[1]);if(s>t.radius+n)return 0;const i=q(e,t.center),r=t.radius*t.radius,a=n*n;if(Math.abs(i-r)<a&&t.isOnSegment(e))return 0;const o=i-r>a;if(o&&t.center[0]<e[0])return 0;const u=Math.sqrt(t.radius*t.radius-s*s);let l=0;const h=c=>{t.isOnSegment(c)&&(g(c,t.firstPoint)?l+=t.tangentAtFirstPoint[1]>0?1:0:g(c,t.lastPoint)?l+=t.tangentAtLastPoint[1]>0?0:1:l+=1)};return h([t.center[0]+u,e[1]]),o&&h([t.center[0]-u,e[1]]),l};function Qt(e,t){if(t instanceof d)return Ht(e,t);if(t instanceof p)return Jt(e,t);throw new Error("Not implemented")}class B extends Lt{constructor(t,{ignoreChecks:n=!1}={}){super(t,{ignoreChecks:!0}),this.strokeType="LOOP",this._clockwise=null,n||Kt(t)}get clockwise(){if(this._clockwise===null){const t=this.segments.flatMap(s=>s instanceof d?[s.firstPoint]:[s.firstPoint,s.paramPoint(.5)]),n=t.map((s,i)=>{const r=t[(i+1)%t.length];return(r[0]-s[0])*(r[1]+s[1])}).reduce((s,i)=>s+i,0);this._clockwise=n>0}return this._clockwise}clone(){return new B(this.segments.map(t=>t.clone()),{ignoreChecks:!0})}reverse(){const t=this.segments.map(n=>n.reverse());return t.reverse(),new B(t,{ignoreChecks:!0})}transform(t){return new B(this.segments.map(n=>n.transform(t)),{ignoreChecks:!0})}contains(t){return this.onStroke(t)||!this.boundingBox.contains(t)?!1:this.segments.reduce((s,i)=>s+Qt(t,i),0)%2===1}simplify(){const t=Tt(this);return t?new B(t,{ignoreChecks:!0}):this}}function Kt(e){if(Ot(e,"Loop"),!g(e[0].firstPoint,e[e.length-1].lastPoint))throw new Error("Loop segment must be closed")}function $t(e){if(e instanceof d)return{type:e.segmentType,firstPoint:e.firstPoint,lastPoint:e.lastPoint};if(e instanceof p)return{type:e.segmentType,firstPoint:e.firstPoint,lastPoint:e.lastPoint,center:e.center,clockwise:e.clockwise};throw new Error("Unknown segment type")}function ot(e){return{type:"LOOP",segments:e.segments.map($t)}}function Dt(e){return{type:"FIGURE",contour:ot(e.contour),holes:e.holes.map(ot)}}function Zt(e){return{type:"DIAGRAM",figures:e.figures.map(Dt)}}function at(e){if(e instanceof C)return Zt(e);if(e instanceof b)return Dt(e);if(e instanceof B)return ot(e);if(e instanceof p||e instanceof d)return $t(e);throw new Error("Unknown shape type")}class tn{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,n){let s=this.length++;for(;s>0;){const i=s-1>>1,r=this.values[i];if(n>=r)break;this.ids[s]=this.ids[i],this.values[s]=r,s=i}this.ids[s]=t,this.values[s]=n}pop(){if(this.length===0)return;const t=this.ids[0];if(this.length--,this.length>0){const n=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 a=(r<<1)+1;const o=a+1;let u=this.ids[a],l=this.values[a];const h=this.values[o];if(o<this.length&&h<l&&(a=o,u=this.ids[o],l=h),l>=s)break;this.ids[r]=u,this.values[r]=l,r=a}this.ids[r]=n,this.values[r]=s}return t}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 Mt=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],st=3;class ct{static from(t){if(!t||t.byteLength===void 0||t.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[n,s]=new Uint8Array(t,0,2);if(n!==251)throw new Error("Data does not appear to be in a Flatbush format.");if(s>>4!==st)throw new Error(`Got v${s>>4} data when expected v${st}.`);const[i]=new Uint16Array(t,2,1),[r]=new Uint32Array(t,4,1);return new ct(r,i,Mt[s&15],void 0,t)}constructor(t,n=16,s=Float64Array,i=ArrayBuffer,r){if(t===void 0)throw new Error("Missing required argument: numItems.");if(isNaN(t)||t<=0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+n,2),65535);let a=t,o=a;this._levelBounds=[a*4];do a=Math.ceil(a/this.nodeSize),o+=a,this._levelBounds.push(o*4);while(a!==1);this.ArrayType=s||Float64Array,this.IndexArrayType=o<16384?Uint16Array:Uint32Array;const u=Mt.indexOf(this.ArrayType),l=o*4*this.ArrayType.BYTES_PER_ELEMENT;if(u<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,8,o*4),this._indices=new this.IndexArrayType(this.data,8+l,o),this._pos=o*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+l+o*this.IndexArrayType.BYTES_PER_ELEMENT),this._boxes=new this.ArrayType(this.data,8,o*4),this._indices=new this.IndexArrayType(this.data,8+l,o),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,(st<<4)+u]),new Uint16Array(this.data,2,1)[0]=n,new Uint32Array(this.data,4,1)[0]=t),this._queue=new tn}add(t,n,s,i){const r=this._pos>>2,a=this._boxes;return this._indices[r]=r,a[this._pos++]=t,a[this._pos++]=n,a[this._pos++]=s,a[this._pos++]=i,t<this.minX&&(this.minX=t),n<this.minY&&(this.minY=n),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 t=this._boxes;if(this.numItems<=this.nodeSize){t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,t[this._pos++]=this.maxY;return}const n=this.maxX-this.minX||1,s=this.maxY-this.minY||1,i=new Uint32Array(this.numItems),r=(1<<16)-1;for(let a=0,o=0;a<this.numItems;a++){const u=t[o++],l=t[o++],h=t[o++],c=t[o++],f=Math.floor(r*((u+h)/2-this.minX)/n),m=Math.floor(r*((l+c)/2-this.minY)/s);i[a]=en(f,m)}ut(i,t,this._indices,0,this.numItems-1,this.nodeSize);for(let a=0,o=0;a<this._levelBounds.length-1;a++){const u=this._levelBounds[a];for(;o<u;){const l=o;let h=t[o++],c=t[o++],f=t[o++],m=t[o++];for(let P=1;P<this.nodeSize&&o<u;P++)h=Math.min(h,t[o++]),c=Math.min(c,t[o++]),f=Math.max(f,t[o++]),m=Math.max(m,t[o++]);this._indices[this._pos>>2]=l,t[this._pos++]=h,t[this._pos++]=c,t[this._pos++]=f,t[this._pos++]=m}}}search(t,n,s,i,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let a=this._boxes.length-4;const o=[],u=[];for(;a!==void 0;){const l=Math.min(a+this.nodeSize*4,At(a,this._levelBounds));for(let h=a;h<l;h+=4){if(s<this._boxes[h]||i<this._boxes[h+1]||t>this._boxes[h+2]||n>this._boxes[h+3])continue;const c=this._indices[h>>2]|0;a>=this.numItems*4?o.push(c):(r===void 0||r(c))&&u.push(c)}a=o.pop()}return u}neighbors(t,n,s=1/0,i=1/0,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let a=this._boxes.length-4;const o=this._queue,u=[],l=i*i;for(;a!==void 0;){const h=Math.min(a+this.nodeSize*4,At(a,this._levelBounds));for(let c=a;c<h;c+=4){const f=this._indices[c>>2]|0,m=yt(t,this._boxes[c],this._boxes[c+2]),P=yt(n,this._boxes[c+1],this._boxes[c+3]),w=m*m+P*P;a>=this.numItems*4?o.push(f<<1,w):(r===void 0||r(f))&&o.push((f<<1)+1,w)}for(;o.length&&o.peek()&1;)if(o.peekValue()>l||(u.push(o.pop()>>1),u.length===s))return o.clear(),u;a=o.pop()>>1}return o.clear(),u}}function yt(e,t,n){return e<t?t-e:e<=n?0:e-n}function At(e,t){let n=0,s=t.length-1;for(;n<s;){const i=n+s>>1;t[i]>e?s=i:n=i+1}return t[n]}function ut(e,t,n,s,i,r){if(Math.floor(s/r)>=Math.floor(i/r))return;const a=e[s+i>>1];let o=s-1,u=i+1;for(;;){do o++;while(e[o]<a);do u--;while(e[u]>a);if(o>=u)break;nn(e,t,n,o,u)}ut(e,t,n,s,u,r),ut(e,t,n,u+1,i,r)}function nn(e,t,n,s,i){const r=e[s];e[s]=e[i],e[i]=r;const a=4*s,o=4*i,u=t[a],l=t[a+1],h=t[a+2],c=t[a+3];t[a]=t[o],t[a+1]=t[o+1],t[a+2]=t[o+2],t[a+3]=t[o+3],t[o]=u,t[o+1]=l,t[o+2]=h,t[o+3]=c;const f=n[s];n[s]=n[i],n[i]=f}function en(e,t){let n=e^t,s=65535^n,i=65535^(e|t),r=e&(t^65535),a=n|s>>1,o=n>>1^n,u=i>>1^s&r>>1^i,l=n&i>>1^r>>1^r;n=a,s=o,i=u,r=l,a=n&n>>2^s&s>>2,o=n&s>>2^s&(n^s)>>2,u^=n&i>>2^s&r>>2,l^=s&i>>2^(n^s)&r>>2,n=a,s=o,i=u,r=l,a=n&n>>4^s&s>>4,o=n&s>>4^s&(n^s)>>4,u^=n&i>>4^s&r>>4,l^=s&i>>4^(n^s)&r>>4,n=a,s=o,i=u,r=l,u^=n&i>>8^s&r>>8,l^=s&i>>8^(n^s)&r>>8,n=u^u>>1,s=l^l>>1;let h=e^t,c=s|65535^(h|n);return h=(h|h<<8)&16711935,h=(h|h<<4)&252645135,h=(h|h<<2)&858993459,h=(h|h<<1)&1431655765,c=(c|c<<8)&16711935,c=(c|c<<4)&252645135,c=(c|c<<2)&858993459,c=(c|c<<1)&1431655765,(c<<1|h)>>>0}function ft(e,t=1e-7){const n=new ct(e.length);e.forEach(r=>{const[a,o]=r.firstPoint;n.add(a-t,o-t,a+t,o+t)}),n.finish();const s=[],i=new Set;return e.forEach((r,a)=>{if(i.has(a))return;const o=[r];let u=a;i.add(a);let l=e.length;for(;;){if(l--<0)throw new Error("Infinite loop detected");const h=o[o.length-1].lastPoint,[c,f]=h,m=n.search(c-t,f-t,c+t,f+t),P=x=>Math.abs((u-x)%e.length),w=m.filter(x=>!i.has(x)).map(x=>[e[x],x,P(x)]).sort(([,,x],[,,L])=>P(x)-P(L));if(w.length===0){s.push(o);break}const[M,I]=w[0];o.push(M),i.add(I),u=I}}),s}class b extends G{constructor(t,n=[],{ignoreChecks:s=!1}={}){super(),s||sn(t,n),this.contour=t,this.holes=n}get boundingBox(){return this.contour.boundingBox}get isFull(){return this.holes.length===0}get allLoops(){return[this.contour,...this.holes]}clone(){return new b(this.contour.clone(),this.holes.map(t=>t.clone()))}transform(t){return new b(this.contour.transform(t),this.holes.map(n=>n.transform(t)))}contains(t){return this.contour.contains(t)&&!this.holes.some(n=>n.contains(t))}intersects(t){return this.allLoops.some(n=>t.allLoops.some(s=>n.intersects(s)))}overlappingStrands(t){const n=t instanceof b?t.allLoops:[t],s=this.allLoops.flatMap(i=>n.flatMap(r=>i.overlappingSegments(r)));return ft(s).map(i=>new v(i))}}function sn(e,t=[]){if(!e)throw new Error("Figure must have a contour");for(const[n,s]of rt([e,...t]))if(n.intersects(s))throw new Error("Loops in a figure must not intersect");if(t.some(n=>!e.contains(n.firstPoint)&&!e.onStroke(n.firstPoint)))throw new Error("Holes must be inside the contour");for(const[n,s]of rt(t))if(n.contains(s.firstPoint))throw console.error(at(n),at(s)),new Error("Holes must not be inside other holes")}const rn=e=>{const t=e.map((i,r)=>e.slice(r+1).map((a,o)=>[o+r+1,a]).filter(([,a])=>i.boundingBox.overlaps(a.boundingBox)).map(([a])=>a)),n=[],s=Array(t.length);return t.forEach((i,r)=>{let a=s[r];a||(a=[],n.push(a)),a.push(e[r]),i.length&&i.forEach(o=>{s[o]=a})}),n},qt=e=>e.map((t,n)=>{const i=t.segments[0].midPoint,r=e.filter((a,o)=>n===o?!1:a.contains(i));return{loop:t,isIn:r}}),on=(e,t)=>e.flatMap(({loop:n})=>gt(t.filter(({loop:s,isIn:i})=>s===n||i.indexOf(n)!==-1))),an=(e,t)=>{const n=t.filter(({isIn:i})=>i.length<=1),s=gt(qt(e.map(({loop:i})=>i)));return[n,...s]},gt=e=>{if(!e.length)return[];const t=e.filter(({isIn:s})=>!s.length),n=e.filter(({isIn:s})=>s.length>1);return t.length===1&&n.length===0?[e]:t.length>1?on(t,e):an(n,e)};function X(e){return rn(e).map(qt).flatMap(gt).map(n=>{if(n.length===1)return new b(n[0].loop);n.sort((r,a)=>r.isIn.length-a.isIn.length);const[s,...i]=n.map(({loop:r})=>r);return new b(s,i)})}function un(e,t){const n=[];for(const s of e)for(const i of t)n.push([s,i]);return n}function*ht(e,t,n){const s=a=>t.some(o=>g(o,a.lastPoint)),i=a=>n.some(o=>a.isSame(o));let r=[];for(const a of e)s(a)?(r.push(a),yield new v(r,{ignoreChecks:!0}),r=[]):i(a)?(r.length&&(yield new v(r,{ignoreChecks:!0}),r=[]),yield new v([a],{ignoreChecks:!0})):r.push(a);r.length&&(yield new v(r,{ignoreChecks:!0}))}const St=(e,t)=>{const n=e.findIndex(r=>g(t,r.firstPoint)),s=e.slice(0,n);return e.slice(n).concat(s)},bt=(e,t)=>{let n=e;const s=o=>g(o.firstPoint,t.firstPoint)&&g(o.lastPoint,t.lastPoint);let i=e.findIndex(s);if(i===-1){const o=e.map(u=>u.reverse());if(o.reverse(),i=o.findIndex(s),i===-1)throw console.error(o.map(u=>u.repr),t.repr),new Error("Failed to rotate to segment start");n=o}const r=n.slice(0,i);return n.slice(i).concat(r)};function hn(e,t,n){return e.filter(s=>{const i=t.filter(o=>g(o.firstPoint,s)||g(o.lastPoint,s));if(i.length%2)throw new Error("Bug in the intersection algo on non crossing point");const r=i.map(o=>n.contains(o.midPoint));return!(r.every(o=>o)||!r.some(o=>o))})}function ln(e,t,n){let s=[];const i=[],r=new Array(e.segments.length).fill(0).map(()=>[]),a=new Array(t.segments.length).fill(0).map(()=>[]);if(e.segments.forEach((f,m)=>{t.segments.forEach((P,w)=>{const{intersections:M,overlaps:I}=j(f,P,n);s.push(...M),r[m].push(...M),a[w].push(...M),i.push(...I);const x=I.flatMap(L=>[L.firstPoint,L.lastPoint]);s.push(...x),r[m].push(...x),a[w].push(...x)})}),s=z(s,n),!s.length||s.length===1)return null;const o=([f,m])=>m.length?f.splitAt(m):[f];let u=O([e.segments,r]).flatMap(o),l=O([t.segments,a]).flatMap(o);if(s=hn(s,u,t),!s.length&&!i.length)return null;if(i.length){const f=i[0];u=bt(u,f),l=bt(l,f)}else{const f=s[0];u=St(u,f),l=St(l,f)}let h=Array.from(ht(u,s,i)),c=Array.from(ht(l,s,i));return(!g(c[0].lastPoint,h[0].lastPoint)||i.length>0&&c[0].segmentsCount!==1)&&(c=c.map(f=>f.reverse()).reverse(),g(c[0].lastPoint,h[0].lastPoint)||(h=h.map(f=>f.reverse()).reverse())),O([h,c]).map(([f,m])=>f.segmentsCount===1&&i.some(P=>f.segments[0].isSame(P))?[f,"same"]:[f,m])}function vt(e){let t=e[0];for(const n of e.slice(1))t=t.extend(n);if(!g(t.firstPoint,t.lastPoint))throw console.error(A(t.firstPoint),A(t.lastPoint)),new Error("Bug in the intersection algo on non closing strand");return new B(t.segments)}function cn(e,t){const n=O([t.slice(0,-1),t.slice(1)]).map(([i,r])=>vt(e.slice(i,r)));let s=e.slice(t[t.length-1]);return t[0]!==0&&(s=s.concat(e.slice(0,t[0]))),n.push(vt(s)),n}function fn(e){if(!e.length)return[];const t=e.map(i=>i.firstPoint);let n=e.map(i=>i.lastPoint);n=n.slice(-1).concat(n.slice(0,-1));const s=O([t,n]).flatMap(([i,r],a)=>g(i,r)?[]:a);try{return cn(e,s)}catch{return ft(e.flatMap(r=>r.segments)).filter(r=>r.length>1).filter(r=>g(r[0].firstPoint,r.at(-1).lastPoint)).map(r=>new B(r))}}const It=(e,t)=>{if(e.length===0)return[t];const n=e.at(-1);return g(n.lastPoint,t.firstPoint)?e.slice(0,-1).concat([n.extend(t)]):g(n.lastPoint,t.lastPoint)?e.slice(0,-1).concat([n.extend(t.reverse())]):e.concat([t])},gn=(e,t)=>e.length===0?[t]:g(e[0].firstPoint,t.lastPoint)?[t.extend(e[0])].concat(e.slice(1)):[t].concat(e);function mt(e,t,{firstInside:n,secondInside:s}){const i=ln(e,t);if(!i){const u=e.segments[0].midPoint,l=t.contains(u),h=t.segments[0].midPoint,c=e.contains(h);return{identical:!1,firstCurveInSecond:l,secondCurveInFirst:c}}if(i.every(([,u])=>u==="same"))return{identical:!0};let r=null,a=null;const o=i.flatMap(([u,l])=>{let h=[],c=0;if(l==="same")return a===1?(a=1,u):a===2||a===0?(a=null,[]):a===null?(r?r=r.extend(u):r=u,[]):(console.error("weird situation"),[]);const f=u.segments[0].midPoint,m=t.contains(f);(n==="keep"&&m||n==="remove"&&!m)&&(c+=1,h=It(h,u));const P=l.segments[0].midPoint,w=e.contains(P);if(s==="keep"&&w||s==="remove"&&!w){const M=l;c+=1,c===2&&h.length?(h=It(h,M),r=null):h=[M]}return a===null&&c===1&&r&&(h=gn(h,r)),c===1&&(a=c,r=null),h.length?h:(r=null,[])});return fn(o)}const mn=(e,t)=>{const n=mt(e,t,{firstInside:"remove",secondInside:"remove"});return Array.isArray(n)?n:n.identical?[e]:n.firstCurveInSecond?[t]:n.secondCurveInFirst?[e]:[e,t]},Z=(e,t)=>{const n=mt(e,t,{firstInside:"remove",secondInside:"keep"});return Array.isArray(n)?n:n.identical?[]:n.firstCurveInSecond?[]:n.secondCurveInFirst?[e,t]:[e]},pt=(e,t)=>{const n=mt(e,t,{firstInside:"keep",secondInside:"keep"});return Array.isArray(n)?n:n.identical?[e]:n.firstCurveInSecond?[e]:n.secondCurveInFirst?[t]:[]};function pn(e){const t=new Map,n=[];return e.forEach((s,i)=>{let r;t.has(i)?r=t.get(i):(r={current:[s],fusedWith:new Set([i])},n.push(r)),e.slice(i+1).forEach((a,o)=>{const u=r.current,l=i+o+1;if(r.fusedWith.has(l))return;let h=[a],c=!1;if(t.has(l)&&(h=t.get(l).current,c=!0),!u.some(P=>h.some(w=>P.intersects(w))))return;let m;u.length>1||h.length>1?m=Y(u,h):m=Yt(u[0],h[0]),r.fusedWith.add(l),r.current=m,c||t.set(l,r)})}),n.flatMap(({current:s})=>s)}function Yt(e,t){const n=mn(e.contour,t.contour),s=t.holes.flatMap(a=>Z(a,e.contour)),i=e.holes.flatMap(a=>Z(a,t.contour)),r=un(e.holes,t.holes).flatMap(([a,o])=>pt(a,o));return X([...n,...s,...i,...r])}function tt(e,t){if(e.isFull&&t.isFull)return X(Z(e.contour,t.contour));if(e.isFull){const s=Z(e.contour,t.contour),i=t.holes.flatMap(r=>pt(r,e.contour));return X([...s,...i])}else if(t.isFull&&!e.contour.intersects(t.contour))if(e.contour.contains(t.contour.firstPoint)){const s=Y(e.holes.map(i=>new b(i)),[t]);return X([e.contour,...s.flatMap(i=>i.allLoops)])}else return[e];let n=tt(new b(e.contour),t);return e.holes.forEach(s=>{n=n.flatMap(i=>tt(i,new b(s)))}),n}function dn(e,t){const n=pt(e.contour,t.contour);if(!n.length)return[];let s=X(n);return s=U(s,e.holes.map(i=>new b(i))),U(s,t.holes.map(i=>new b(i)))}function Y(e,t){if(!e.length)return t;if(!t.length)return e;if(e.length===1&&t.length>1||t.length===1&&e.length>1)return pn([...e,...t]);if(e.length>1&&t.length>1){let n=Y([e[0]],t);return e.slice(1).forEach(s=>{n=Y([s],n)}),n}return e.length===1&&t.length===1?Yt(e[0],t[0]):[]}function U(e,t){if(!e.length)return[];if(!t.length)return e;if(e.length===1&&t.length===1)return tt(e[0],t[0]);if(e.length>1)return e.flatMap(s=>U([s],t));let n=tt(e[0],t[0]);return t.slice(1).forEach(s=>{n=U(n,[s])}),n}function nt(e,t){return!e.length||!t.length?[]:e.length===1&&t.length===1?dn(e[0],t[0]):e.length>1?e.flatMap(n=>nt([n],t)):t.flatMap(n=>nt(e,[n]))}class C extends G{constructor(t=[],{ignoreChecks:n=!1}={}){super(),this._boundingBox=null,n||Pn(t),this.figures=t}get isEmpty(){return this.figures.length===0}get boundingBox(){if(this.isEmpty)return new $;if(this._boundingBox===null){let t=this.figures[0].boundingBox;for(const n of this.figures.slice(1))t=t.merge(n.boundingBox);this._boundingBox=t}return this._boundingBox}clone(){return new C(this.figures.map(t=>t.clone()))}transform(t){return new C(this.figures.map(n=>n.transform(t)))}contains(t){return this.figures.some(n=>n.contains(t))}intersects(t){return this.figures.some(n=>t.figures.some(s=>n.intersects(s)))}overlappingStrands(t){return this.figures.flatMap(n=>t instanceof C?t.figures.flatMap(s=>n.overlappingStrands(s)):n.overlappingStrands(t))}fuse(t){return new C(Y(this.figures,t.figures))}cut(t){return new C(U(this.figures,t.figures))}intersect(t){return new C(nt(this.figures,t.figures))}}function Pn(e){for(const[t,n]of rt(e))if(t.intersects(n))throw new Error("Diagram figures must not intersect")}exports.Arc=p;exports.BoundingBox=$;exports.DEG2RAD=_t;exports.Diagram=C;exports.Figure=b;exports.Line=d;exports.Loop=B;exports.Strand=v;exports.Transformable=G;exports.TransformationMatrix=E;exports.add=S;exports.arcArcIntersection=lt;exports.crossProduct=T;exports.cutFiguresLists=U;exports.distance=k;exports.exportJSON=at;exports.findIntersections=Gt;exports.findIntersectionsAndOverlaps=j;exports.fuseFiguresLists=Y;exports.intersectFiguresLists=nt;exports.lineArcIntersection=R;exports.lineLineParams=W;exports.normalize=V;exports.perpendicular=F;exports.perpendicularClockwise=Q;exports.polarAngle=kt;exports.polarToCartesian=N;exports.projectPointOnLine=Vt;exports.removeDuplicatePoints=z;exports.sameVector=g;exports.scalarMultiply=_;exports.squareDistance=q;exports.stitchSegments=ft;exports.strandsBetweenIntersections=ht;exports.subtract=y;exports.tangentArc=Rt;exports.threePointsArc=Xt;exports.zip=O;
4
+ //# sourceMappingURL=Diagram-c2ca1c3b.cjs.map