From d00e1497fa10ccc5c36aa98752bdac9c3385ed85 Mon Sep 17 00:00:00 2001 From: William Ngan Date: Sat, 2 Mar 2024 00:17:18 -0800 Subject: [PATCH] rebuild --- dist/index.d.ts | 6 +++++- dist/index.js | 27 ++++++++++++++++++++++++++- dist/index.mjs | 27 ++++++++++++++++++++++++++- dist/pts.js | 29 +++++++++++++++++++++++++++-- dist/pts.min.js | 8 ++++---- dist/pts.min.js.map | 2 +- 6 files changed, 89 insertions(+), 10 deletions(-) diff --git a/dist/index.d.ts b/dist/index.d.ts index 261711e1..0161441e 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -22,6 +22,8 @@ declare const UIPointerActions: { click: string; keydown: string; keyup: string; + pointerdown: string; + pointerup: string; contextmenu: string; all: string; }; @@ -464,9 +466,11 @@ declare abstract class MultiTouchSpace extends Space { bindTouch(bind?: boolean, passive?: boolean, customTarget?: Element): this; bindKeyboard(bind?: boolean): this; touchesToPoints(evt: TouchEvent, which?: TouchPointsKey): Pt[]; - protected _mouseAction(type: string, evt: MouseEvent | TouchEvent): void; + protected _mouseAction(type: string, evt: MouseEvent | TouchEvent | PointerEvent): void; protected _mouseDown(evt: MouseEvent | TouchEvent): boolean; + protected _pointerDown(evt: PointerEvent): boolean; protected _mouseUp(evt: MouseEvent | TouchEvent): boolean; + protected _pointerUp(evt: PointerEvent): boolean; protected _mouseMove(evt: MouseEvent | TouchEvent): boolean; protected _mouseOver(evt: MouseEvent | TouchEvent): boolean; protected _mouseOut(evt: MouseEvent | TouchEvent): boolean; diff --git a/dist/index.js b/dist/index.js index f15238e2..982b600d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4300,6 +4300,8 @@ var UIPointerActions = { click: "click", keydown: "keydown", keyup: "keyup", + pointerdown: "pointerdown", + pointerup: "pointerup", contextmenu: "contextmenu", all: "all" }; @@ -4775,7 +4777,7 @@ var Space = class { add(p) { let player = typeof p == "function" ? { animate: p } : p; let k = this.playerCount++; - let pid = this.id + k; + let pid = player.animateID || this.id + k; this.players[pid] = player; player.animateID = pid; if (player.resize && this.bound.inited) @@ -5012,9 +5014,13 @@ var MultiTouchSpace = class extends Space { this._mouseOut = this._mouseOut.bind(this); this._mouseMove = this._mouseMove.bind(this); this._mouseClick = this._mouseClick.bind(this); + this._pointerDown = this._pointerDown.bind(this); + this._pointerUp = this._pointerUp.bind(this); this._contextMenu = this._contextMenu.bind(this); this.bindCanvas("mousedown", this._mouseDown, {}, customTarget); + this.bindCanvas("pointerdown", this._pointerDown, {}, customTarget); this.bindCanvas("mouseup", this._mouseUp, {}, customTarget); + this.bindCanvas("pointerup", this._pointerUp, {}, customTarget); this.bindCanvas("mouseover", this._mouseOver, {}, customTarget); this.bindCanvas("mouseout", this._mouseOut, {}, customTarget); this.bindCanvas("mousemove", this._mouseMove, {}, customTarget); @@ -5023,7 +5029,9 @@ var MultiTouchSpace = class extends Space { this._hasMouse = true; } else { this.unbindCanvas("mousedown", this._mouseDown, {}, customTarget); + this.unbindCanvas("pointerdown", this._pointerDown, {}, customTarget); this.unbindCanvas("mouseup", this._mouseUp, {}, customTarget); + this.unbindCanvas("pointerup", this._pointerUp, {}, customTarget); this.unbindCanvas("mouseover", this._mouseOver, {}, customTarget); this.unbindCanvas("mouseout", this._mouseOut, {}, customTarget); this.unbindCanvas("mousemove", this._mouseMove, {}, customTarget); @@ -5135,6 +5143,13 @@ var MultiTouchSpace = class extends Space { this._pressed = true; return false; } + _pointerDown(evt) { + this._mouseAction(UIPointerActions.pointerdown, evt); + if (evt.target instanceof Element) { + evt.target.setPointerCapture(evt.pointerId); + } + return false; + } /** * MouseUp handler. * @param evt @@ -5149,6 +5164,16 @@ var MultiTouchSpace = class extends Space { this._dragged = false; return false; } + _pointerUp(evt) { + this._mouseAction(UIPointerActions.pointerup, evt); + if (evt.target instanceof Element) { + evt.target.releasePointerCapture(evt.pointerId); + if (this._dragged) + this._mouseAction(UIPointerActions.drop, evt); + this._dragged = false; + } + return false; + } /** * MouseMove handler. * @param evt diff --git a/dist/index.mjs b/dist/index.mjs index d19868ff..68e0bac4 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -4232,6 +4232,8 @@ var UIPointerActions = { click: "click", keydown: "keydown", keyup: "keyup", + pointerdown: "pointerdown", + pointerup: "pointerup", contextmenu: "contextmenu", all: "all" }; @@ -4707,7 +4709,7 @@ var Space = class { add(p) { let player = typeof p == "function" ? { animate: p } : p; let k = this.playerCount++; - let pid = this.id + k; + let pid = player.animateID || this.id + k; this.players[pid] = player; player.animateID = pid; if (player.resize && this.bound.inited) @@ -4944,9 +4946,13 @@ var MultiTouchSpace = class extends Space { this._mouseOut = this._mouseOut.bind(this); this._mouseMove = this._mouseMove.bind(this); this._mouseClick = this._mouseClick.bind(this); + this._pointerDown = this._pointerDown.bind(this); + this._pointerUp = this._pointerUp.bind(this); this._contextMenu = this._contextMenu.bind(this); this.bindCanvas("mousedown", this._mouseDown, {}, customTarget); + this.bindCanvas("pointerdown", this._pointerDown, {}, customTarget); this.bindCanvas("mouseup", this._mouseUp, {}, customTarget); + this.bindCanvas("pointerup", this._pointerUp, {}, customTarget); this.bindCanvas("mouseover", this._mouseOver, {}, customTarget); this.bindCanvas("mouseout", this._mouseOut, {}, customTarget); this.bindCanvas("mousemove", this._mouseMove, {}, customTarget); @@ -4955,7 +4961,9 @@ var MultiTouchSpace = class extends Space { this._hasMouse = true; } else { this.unbindCanvas("mousedown", this._mouseDown, {}, customTarget); + this.unbindCanvas("pointerdown", this._pointerDown, {}, customTarget); this.unbindCanvas("mouseup", this._mouseUp, {}, customTarget); + this.unbindCanvas("pointerup", this._pointerUp, {}, customTarget); this.unbindCanvas("mouseover", this._mouseOver, {}, customTarget); this.unbindCanvas("mouseout", this._mouseOut, {}, customTarget); this.unbindCanvas("mousemove", this._mouseMove, {}, customTarget); @@ -5067,6 +5075,13 @@ var MultiTouchSpace = class extends Space { this._pressed = true; return false; } + _pointerDown(evt) { + this._mouseAction(UIPointerActions.pointerdown, evt); + if (evt.target instanceof Element) { + evt.target.setPointerCapture(evt.pointerId); + } + return false; + } /** * MouseUp handler. * @param evt @@ -5081,6 +5096,16 @@ var MultiTouchSpace = class extends Space { this._dragged = false; return false; } + _pointerUp(evt) { + this._mouseAction(UIPointerActions.pointerup, evt); + if (evt.target instanceof Element) { + evt.target.releasePointerCapture(evt.pointerId); + if (this._dragged) + this._mouseAction(UIPointerActions.drop, evt); + this._dragged = false; + } + return false; + } /** * MouseMove handler. * @param evt diff --git a/dist/pts.js b/dist/pts.js index 29b71601..44c9c426 100644 --- a/dist/pts.js +++ b/dist/pts.js @@ -1,4 +1,4 @@ -/* Copyright © 2017-2023 William Ngan and contributors. +/* Copyright © 2017-2024 William Ngan and contributors. Licensed under Apache 2.0 License. See https://github.com/williamngan/pts for details. */ (() => { @@ -4318,6 +4318,8 @@ See https://github.com/williamngan/pts for details. */ click: "click", keydown: "keydown", keyup: "keyup", + pointerdown: "pointerdown", + pointerup: "pointerup", contextmenu: "contextmenu", all: "all" }; @@ -4793,7 +4795,7 @@ See https://github.com/williamngan/pts for details. */ add(p) { let player = typeof p == "function" ? { animate: p } : p; let k = this.playerCount++; - let pid = this.id + k; + let pid = player.animateID || this.id + k; this.players[pid] = player; player.animateID = pid; if (player.resize && this.bound.inited) @@ -5030,9 +5032,13 @@ See https://github.com/williamngan/pts for details. */ this._mouseOut = this._mouseOut.bind(this); this._mouseMove = this._mouseMove.bind(this); this._mouseClick = this._mouseClick.bind(this); + this._pointerDown = this._pointerDown.bind(this); + this._pointerUp = this._pointerUp.bind(this); this._contextMenu = this._contextMenu.bind(this); this.bindCanvas("mousedown", this._mouseDown, {}, customTarget); + this.bindCanvas("pointerdown", this._pointerDown, {}, customTarget); this.bindCanvas("mouseup", this._mouseUp, {}, customTarget); + this.bindCanvas("pointerup", this._pointerUp, {}, customTarget); this.bindCanvas("mouseover", this._mouseOver, {}, customTarget); this.bindCanvas("mouseout", this._mouseOut, {}, customTarget); this.bindCanvas("mousemove", this._mouseMove, {}, customTarget); @@ -5041,7 +5047,9 @@ See https://github.com/williamngan/pts for details. */ this._hasMouse = true; } else { this.unbindCanvas("mousedown", this._mouseDown, {}, customTarget); + this.unbindCanvas("pointerdown", this._pointerDown, {}, customTarget); this.unbindCanvas("mouseup", this._mouseUp, {}, customTarget); + this.unbindCanvas("pointerup", this._pointerUp, {}, customTarget); this.unbindCanvas("mouseover", this._mouseOver, {}, customTarget); this.unbindCanvas("mouseout", this._mouseOut, {}, customTarget); this.unbindCanvas("mousemove", this._mouseMove, {}, customTarget); @@ -5153,6 +5161,13 @@ See https://github.com/williamngan/pts for details. */ this._pressed = true; return false; } + _pointerDown(evt) { + this._mouseAction(UIPointerActions.pointerdown, evt); + if (evt.target instanceof Element) { + evt.target.setPointerCapture(evt.pointerId); + } + return false; + } /** * MouseUp handler. * @param evt @@ -5167,6 +5182,16 @@ See https://github.com/williamngan/pts for details. */ this._dragged = false; return false; } + _pointerUp(evt) { + this._mouseAction(UIPointerActions.pointerup, evt); + if (evt.target instanceof Element) { + evt.target.releasePointerCapture(evt.pointerId); + if (this._dragged) + this._mouseAction(UIPointerActions.drop, evt); + this._dragged = false; + } + return false; + } /** * MouseMove handler. * @param evt diff --git a/dist/pts.min.js b/dist/pts.min.js index e675d107..58be7b7f 100644 --- a/dist/pts.min.js +++ b/dist/pts.min.js @@ -1,8 +1,8 @@ -/* Copyright © 2017-2023 William Ngan and contributors. +/* Copyright © 2017-2024 William Ngan and contributors. Licensed under Apache 2.0 License. See https://github.com/williamngan/pts for details. */ -(()=>{var Ut=Object.defineProperty;var qt=Object.getOwnPropertySymbols;var jt=Object.prototype.hasOwnProperty,Vt=Object.prototype.propertyIsEnumerable;var Ht=(y,i,t)=>i in y?Ut(y,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):y[i]=t,z=(y,i)=>{for(var t in i||(i={}))jt.call(i,t)&&Ht(y,t,i[t]);if(qt)for(var t of qt(i))Vt.call(i,t)&&Ht(y,t,i[t]);return y};var B=(y,i)=>{for(var t in i)Ut(y,t,{get:i[t],enumerable:!0})};var lt=(y,i,t)=>new Promise((e,r)=>{var n=l=>{try{o(t.next(l))}catch(a){r(a)}},s=l=>{try{o(t.throw(l))}catch(a){r(a)}},o=l=>l.done?e(l.value):Promise.resolve(l.value).then(n,s);o((t=t.apply(y,i)).next())});var Tt={};B(Tt,{CanvasForm:()=>E,CanvasSpace:()=>at});var Mt={};B(Mt,{MultiTouchSpace:()=>tt,Space:()=>dt});var Lt={};B(Lt,{Bound:()=>G,Group:()=>c,Pt:()=>u});var vt={};B(vt,{Const:()=>L,Util:()=>m});var kt={};B(kt,{Geom:()=>g,Num:()=>v,Range:()=>xt,Shaping:()=>K});var wt={};B(wt,{Circle:()=>q,Curve:()=>D,Line:()=>M,Polygon:()=>C,Rectangle:()=>k,Triangle:()=>O});var Pt={};B(Pt,{Mat:()=>P,Vec:()=>x});var x=class{static add(i,t){if(typeof t=="number")for(let e=0,r=i.length;eMath.max(s,o.length),0):i[0].length;for(let s=0;sm.warn("Group's length is less than "+i,y),Wt=(y,i="")=>m.warn(`Index ${i} is out of bound in Group`,y),M=class{static fromAngle(i,t,e){let r=new c(new u(i),new u(i));return r[1].toAngle(t,e,!0),r}static slope(i,t){return t[0]-i[0]===0?void 0:(t[1]-i[1])/(t[0]-i[0])}static intercept(i,t){if(t[0]-i[0]!==0){let e=(t[1]-i[1])/(t[0]-i[0]),r=i[1]-e*i[0];return{slope:e,yi:r,xi:e===0?void 0:-r/e}}}static sideOfPt2D(i,t){let e=m.iterToArray(i);return(e[1][0]-e[0][0])*(t[1]-e[0][1])-(t[0]-e[0][0])*(e[1][1]-e[0][1])}static collinear(i,t,e,r=.01){let n=new u(0,0,0).to(i).$subtract(t),s=new u(0,0,0).to(i).$subtract(e);return n.$cross(s).divide(1e3).equals(new u(0,0,0),r)}static magnitude(i){let t=m.iterToArray(i);return t.length>=2?t[1].$subtract(t[0]).magnitude():0}static magnitudeSq(i){let t=m.iterToArray(i);return t.length>=2?t[1].$subtract(t[0]).magnitudeSq():0}static perpendicularFromPt(i,t,e=!1){let r=m.iterToArray(i);if(r[0].equals(r[1]))return;let n=r[0].$subtract(r[1]),s=r[1].$subtract(t),o=s.$subtract(n.$project(s));return e?o:o.$add(t)}static distanceFromPt(i,t){let e=m.iterToArray(i),r=M.perpendicularFromPt(e,t,!0);return r?r.magnitude():e[0].$subtract(t).magnitude()}static intersectRay2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n=M.intercept(e[0],e[1]),s=M.intercept(r[0],r[1]),o=e[0],l=r[0];if(n==null){if(s==null)return;let a=-s.slope*(l[0]-o[0])+l[1];return new u(o[0],a)}else if(s==null){let a=-n.slope*(o[0]-l[0])+o[1];return new u(l[0],a)}else if(s.slope!=n.slope){let a=(n.slope*o[0]-s.slope*l[0]+l[1]-o[1])/(n.slope-s.slope),h=n.slope*(a-o[0])+o[1];return new u(a,h)}else return n.yi==s.yi?new u(o[0],o[1]):void 0}static intersectLine2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n=M.intersectRay2D(e,r);return n&&g.withinBound(n,e[0],e[1])&&g.withinBound(n,r[0],r[1])?n:void 0}static intersectLineWithRay2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n=M.intersectRay2D(e,r);return n&&g.withinBound(n,e[0],e[1])?n:void 0}static intersectPolygon2D(i,t,e=!1){let r=m.iterToArray(i),n=m.iterToArray(t),s=e?M.intersectLineWithRay2D:M.intersectLine2D,o=new c;for(let l=0,a=n.length;l0?o:void 0}static intersectLines2D(i,t,e=!1){let r=new c,n=e?M.intersectLineWithRay2D:M.intersectLine2D;for(let s of i)for(let o of t){let l=n(s,o);l&&r.push(l)}return r}static intersectGridWithRay2D(i,t){let e=m.iterToArray(i),r=M.intercept(new u(e[0]).subtract(t),new u(e[1]).subtract(t)),n=new c;return r&&r.xi&&n.push(new u(t[0]+r.xi,t[1])),r&&r.yi&&n.push(new u(t[0],t[1]+r.yi)),n}static intersectGridWithLine2D(i,t){let e=m.iterToArray(i),r=M.intersectGridWithRay2D(e,t),n=new c;for(let s=0,o=r.length;sMath.abs(t[1]/t[0])?h=o[1]<0?0:2:h=o[0]<0?3:1,M.intersectRay2D(a[h],n)}}static marker(i,t,e="arrow",r=!0){let n=m.iterToArray(i),s=r?0:1,o=r?1:0,l=n[s].$subtract(n[o]);if(l.magnitudeSq()===0)return new c;l.unit();let a=g.perpendicular(l).multiply(t[0]).add(n[o]);return e=="arrow"?(a.add(l.$multiply(t[1])),new c(n[o],a[0],a[1])):new c(a[0],a[1])}static toRect(i){let t=m.iterToArray(i);return new c(t[0].$min(t[1]),t[0].$max(t[1]))}},k=class{static from(i,t,e){return k.fromTopLeft(i,t,e)}static fromTopLeft(i,t,e){let r=typeof t=="number"?[t,e||t]:t;return new c(new u(i),new u(i).add(r))}static fromCenter(i,t,e){let r=typeof t=="number"?[t/2,(e||t)/2]:new u(t).divide(2);return new c(new u(i).subtract(r),new u(i).add(r))}static toCircle(i,t=!0){return q.fromRect(i,t)}static toSquare(i,t=!1){let e=m.iterToArray(i),r=k.size(e),n=t?r.maxValue().value:r.minValue().value;return k.fromCenter(k.center(e),n,n)}static size(i){let t=m.iterToArray(i);return t[0].$max(t[1]).subtract(t[0].$min(t[1]))}static center(i){let t=m.iterToArray(i),e=t[0].$min(t[1]),r=t[0].$max(t[1]);return e.add(r.$subtract(e).divide(2))}static corners(i){let t=m.iterToArray(i),e=t[0].$min(t[1]),r=t[0].$max(t[1]);return new c(e,new u(r.x,e.y),r,new u(e.x,r.y))}static sides(i){let[t,e,r,n]=k.corners(i);return[new c(t,e),new c(e,r),new c(r,n),new c(n,t)]}static boundingBox(i){let t=m.iterToArray(i),e=m.flatten(t,!1),r=u.make(2,Number.MAX_VALUE),n=u.make(2,Number.MIN_VALUE);for(let s=0,o=e.length;s=2)break}return new c(r,n)}static polygon(i){return k.corners(i)}static quadrants(i,t){let e=m.iterToArray(i),r=k.corners(e),n=t!=null?new u(t):k.center(e);return r.map(s=>new c(s,n).boundingBox())}static halves(i,t=.5,e=!1){let r=m.iterToArray(i),n=r[0].$min(r[1]),s=r[0].$max(r[1]),o=e?v.lerp(n[1],s[1],t):v.lerp(n[0],s[0],t);return e?[new c(n,new u(s[0],o)),new c(new u(n[0],o),s)]:[new c(n,new u(o,s[1])),new c(new u(o,n[1]),s)]}static withinBound(i,t){let e=m.iterToArray(i);return g.withinBound(t,e[0],e[1])}static hasIntersectRect2D(i,t,e=!1){let r=m.iterToArray(i),n=m.iterToArray(t);return e&&(r=g.boundingBox(r),n=g.boundingBox(n)),!(r[0][0]>n[1][0]||n[0][0]>r[1][0]||r[0][1]>n[1][1]||n[0][1]>r[1][1])}static intersectRect2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t);return k.hasIntersectRect2D(e,r)?M.intersectLines2D(k.sides(e),k.sides(r)):new c}},q=class{static fromRect(i,t=!1){let e=m.iterToArray(i),r=0,n=r=k.size(e).minValue().value/2;if(t){let s=k.size(e).maxValue().value/2;r=Math.sqrt(n*n+s*s)}else r=n;return new c(k.center(e),new u(r,r))}static fromTriangle(i,t=!1){return t?O.circumcircle(i):O.incircle(i)}static fromCenter(i,t){return new c(new u(i),new u(t,t))}static withinBound(i,t,e=0){let r=m.iterToArray(i),n=r[0].$subtract(t);return n.dot(n)+e0)for(let o=0,l=n.length;ol+a)return new c;if(o0&&s.push(a)}return m.flatten(s)}static toRect(i,t=!1){let e=m.iterToArray(i),r=e[1][0];if(t){let n=Math.sqrt(r*r)/2;return new c(e[0].$subtract(n),e[0].$add(n))}else return new c(e[0].$subtract(r),e[0].$add(r))}static toTriangle(i,t=!0){let e=m.iterToArray(i);if(t){let r=-Math.PI/2,n=Math.PI*2/3,s=new c;for(let o=0;o<3;o++)s.push(e[0].clone().toAngle(r,e[1][0],!0)),r+=n;return s}else return O.fromCenter(e[0],e[1][0])}},O=class{static fromRect(i){let t=m.iterToArray(i),e=t[0].$add(t[1]).divide(2);e.y=t[0][1];let r=t[1].clone();return r.x=t[0][0],new c(e,t[1].clone(),r)}static fromCircle(i){return q.toTriangle(i,!0)}static fromCenter(i,t){return O.fromCircle(q.fromCenter(i,t))}static medial(i){let t=m.iterToArray(i);return t.length<3?Y(new c,3):C.midpoints(t,!0)}static oppositeSide(i,t){let e=m.iterToArray(i);return e.length<3?Y(new c,3):t===0?c.fromPtArray([e[1],e[2]]):t===1?c.fromPtArray([e[0],e[2]]):c.fromPtArray([e[0],e[1]])}static altitude(i,t){let e=m.iterToArray(i),r=O.oppositeSide(e,t);return r.length>1?new c(e[t],M.perpendicularFromPt(r,e[t])):new c}static orthocenter(i){let t=m.iterToArray(i);if(t.length<3)return Y(void 0,3);let e=O.altitude(t,0),r=O.altitude(t,1);return M.intersectRay2D(e,r)}static incenter(i){let t=m.iterToArray(i);if(t.length<3)return Y(void 0,3);let e=C.bisector(t,0).add(t[0]),r=C.bisector(t,1).add(t[1]);return M.intersectRay2D(new c(t[0],e),new c(t[1],r))}static incircle(i,t){let e=m.iterToArray(i),r=t||O.incenter(e),n=C.area(e),s=C.perimeter(e,!0),o=2*n/s.total;return q.fromCenter(r,o)}static circumcenter(i){let t=m.iterToArray(i),e=O.medial(t),r=[e[0],g.perpendicular(t[0].$subtract(e[0])).p1.$add(e[0])],n=[e[1],g.perpendicular(t[1].$subtract(e[1])).p1.$add(e[1])];return M.intersectRay2D(r,n)}static circumcircle(i,t){let e=m.iterToArray(i),r=t||O.circumcenter(e),n=e[0].$subtract(r).magnitude();return q.fromCenter(r,n)}},C=class{static centroid(i){return g.centroid(i)}static rectangle(i,t,e){return k.corners(k.fromCenter(i,t,e))}static fromCenter(i,t,e){let r=new c;for(let n=0;n=e.length)throw new Error("index out of the Polygon's range");return new c(e[t],t===e.length-1?e[0]:e[t+1])}static lines(i,t=!0){let e=m.iterToArray(i);if(e.length<2)return Y(new c,2);let r=m.split(e,2,1);return t&&r.push(new c(e[e.length-1],e[0])),r.map(n=>n)}static midpoints(i,t=!1,e=.5){return C.lines(i,t).map(s=>g.interpolate(s[0],s[1],e))}static adjacentSides(i,t,e=!1){let r=m.iterToArray(i);if(r.length<2)return Y(new c,2);if(t<0||t>=r.length)return Wt(new c,t);let n=[],s=t-1;e&&s<0&&(s=r.length-1),s>=0&&n.push(new c(r[t],r[s]));let o=t+1;return e&&o>r.length-1&&(o=0),o<=r.length-1&&n.push(new c(r[t],r[o])),n}static bisector(i,t){let e=C.adjacentSides(i,t,!0);if(e.length>=2){let r=e[0][1].$subtract(e[0][0]).unit(),n=e[1][1].$subtract(e[1][0]).unit();return r.add(n).divide(2)}else return}static perimeter(i,t=!1){let e=C.lines(i,t),r=0,n=u.make(e.length,0);for(let s=0,o=e.length;sn[0]*s[1]-n[1]*s[0],r=0;for(let n=0,s=t.length;na[0]-h[0]));let r=(a,h,p)=>(h[0]-a[0])*(p[1]-a[1])-(p[0]-a[0])*(h[1]-a[1])>0,n=[],s=e.length-2,o=s+3;n[s]=e[2],n[o]=e[2],r(e[0],e[1],e[2])?(n[s+1]=e[0],n[s+2]=e[1]):(n[s+1]=e[1],n[s+2]=e[0]);for(let a=3,h=e.length;at[1]!=o[1][1]>t[1]&&t[0]<(o[1][0]-o[0][0])*(t[1]-o[0][1])/(o[1][1]-o[0][1])+o[0][0]&&(r=!r)}return r}static hasIntersectCircle(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n={which:-1,dist:0,normal:null,edge:null,vertex:null},s=r[0],o=r[1][0],l=Number.MAX_SAFE_INTEGER;for(let h=0,p=e.length;h0)return null;Math.abs(_)0)&&(n.edge=d,n.normal=f,l=Math.abs(_),n.which=h)}return n.edge?(s.$subtract(C.centroid(e)).dot(n.normal)<0&&n.normal.multiply(-1),n.dist=l,n.vertex=s,n):null}static hasIntersectPolygon(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n={which:-1,dist:0,normal:new u,edge:new c,vertex:new u},s=Number.MAX_SAFE_INTEGER;for(let f=0,w=e.length+r.length;f0)return null;Math.abs(S)r.length-1)return new c;let n=o=>on+s.x*t[o],0),r=i.reduce((n,s,o)=>n+s.y*t[o],0);if(i[0].length>2){let n=i.reduce((s,o,l)=>s+o.z*t[l],0);return new u(e,r,n)}return new u(e,r)}static catmullRom(i,t=10){let e=m.iterToArray(i);if(e.length<2)return new c;let r=new c,n=D.getSteps(t),s=D.controlPoints(e,0,!0);for(let l=0;l<=t;l++)r.push(D.catmullRomStep(n[l],s));let o=0;for(;o0){for(let a=0;a<=t;a++)r.push(D.catmullRomStep(n[a],l));o++}}return r}static catmullRomStep(i,t){let e=new c(new u(-.5,1,-.5,0),new u(1.5,-2.5,0,1),new u(-1.5,2,.5,0),new u(.5,-.5,0,0));return D._calcPt(t,P.multiply([i],e,!0)[0])}static cardinal(i,t=10,e=.5){let r=m.iterToArray(i);if(r.length<2)return new c;let n=new c,s=D.getSteps(t),o=D.controlPoints(r,0,!0);for(let a=0;a<=t;a++)n.push(D.cardinalStep(s[a],o,e));let l=0;for(;l0){for(let h=0;h<=t;h++)n.push(D.cardinalStep(s[h],a,e));l++}}return n}static cardinalStep(i,t,e=.5){let r=new c(new u(-1,2,-1,0),new u(-1,1,0,0),new u(1,-2,1,0),new u(1,-1,0,0)),n=P.multiply([i],r,!0)[0].multiply(e),s=2*i[0]-3*i[1]+1,o=-2*i[0]+3*i[1],l=D._calcPt(t,n);return l.x+=s*t[1].x+o*t[2].x,l.y+=s*t[1].y+o*t[2].y,l.length>2&&(l.z+=s*t[1].z+o*t[2].z),l}static bezier(i,t=10){let e=m.iterToArray(i);if(e.length<4)return new c;let r=new c,n=D.getSteps(t),s=0;for(;s0){for(let l=0;l<=t;l++)r.push(D.bezierStep(n[l],o));s+=3}}return r}static bezierStep(i,t){let e=new c(new u(-1,3,-3,1),new u(3,-6,3,0),new u(-3,3,0,0),new u(1,0,0,0));return D._calcPt(t,P.multiply([i],e,!0)[0])}static bspline(i,t=10,e=1){let r=m.iterToArray(i);if(r.length<2)return new c;let n=new c,s=D.getSteps(t),o=0;for(;o0){if(e!==1)for(let a=0;a<=t;a++)n.push(D.bsplineTensionStep(s[a],l,e));else for(let a=0;a<=t;a++)n.push(D.bsplineStep(s[a],l));o++}}return n}static bsplineStep(i,t){let e=new c(new u(-.16666666666666666,.5,-.5,.16666666666666666),new u(.5,-1,0,.6666666666666666),new u(-.5,.5,.5,.16666666666666666),new u(.16666666666666666,0,0,0));return D._calcPt(t,P.multiply([i],e,!0)[0])}static bsplineTensionStep(i,t,e=1){let r=new c(new u(-.16666666666666666,.5,-.5,.16666666666666666),new u(-1.5,2,0,-.3333333333333333),new u(1.5,-2.5,.5,.16666666666666666),new u(.16666666666666666,0,0,0)),n=P.multiply([i],r,!0)[0].multiply(e),s=2*i[0]-3*i[1]+1,o=-2*i[0]+3*i[1],l=D._calcPt(t,n);return l.x+=s*t[1].x+o*t[2].x,l.y+=s*t[1].y+o*t[2].y,l.length>2&&(l.z+=s*t[1].z+o*t[2].z),l}};function Xt(){var y=4022871197,i=function(t){if(t){t=t.toString();for(var e=0;e>>0,r-=y,r*=y,y=r>>>0,r-=y,y+=r*4294967296}return(y>>>0)*23283064365386963e-26}else y=4022871197};return i}function Ft(y){var i=48,t=1,e=i,r=new Array(i),n,s,o=0,l=Xt();for(n=0;n=i&&(e=0);var d=1768863*r[e]+t*23283064365386963e-26;return r[e]=d-(t=d|0)}}}var v=class{static equals(i,t,e=1e-5){return Math.abs(i-t)e?n-=r:n=Math.min(t,e)&&i<=Math.max(t,e)}static randomRange(i,t=0){let e=i>t?i-t:t-i;return i+v.random()*e}static randomPt(i,t){let e=new u(i.length),r=t?x.subtract(t.slice(),i):i,n=t?i:new u(i.length).fill(0);for(let s=0,o=e.length;s.5?2-i*2:i*2)}static mapToRange(i,t,e,r,n){if(t==e)throw new Error("[currMin, currMax] must define a range that is not zero");let s=Math.min(r,n),o=Math.max(r,n);return v.normalizeValue(i,t,e)*(o-s)+s}static seed(i){this.generator=Ft(i)}static random(){return this.generator?this.generator.random():Math.random()}},g=class{static boundAngle(i){return v.boundValue(i,0,360)}static boundRadian(i){return v.boundValue(i,0,L.two_pi)}static toRadian(i){return i*L.deg_to_rad}static toDegree(i){return i*L.rad_to_deg}static boundingBox(i){let t,e;for(let r of i)t==null?(t=r.clone(),e=r.clone()):(t=t.$min(r),e=e.$max(r));return new c(t,e)}static centroid(i){return v.average(i)}static anchor(i,t=0,e="to"){let r=e=="to"?"subtract":"add",n=0;for(let s of i)typeof t=="number"?t!==n&&s[r](i[t]):s[r](t),n++}static interpolate(i,t,e=.5){let r=Math.min(i.length,t.length),n=u.make(r);for(let s=0;s{if(s.length<2||o.length<2)throw new Error("Pt dimension cannot be less than 2");let l=s.$subtract(r),a=o.$subtract(r);if(l[0]>=0&&a[0]<0)return 1;if(l[0]<0&&a[0]>=0)return-1;if(l[0]==0&&a[0]==0)return l[1]>=0||a[1]>=0?l[1]>a[1]?1:-1:a[1]>l[1]?1:-1;let h=l.$cross2D(a);return h<0?1:h>0?-1:l[0]*l[0]+l[1]*l[1]>a[0]*a[0]+a[1]*a[1]?1:-1};return t.sort(n)}static scale(i,t,e){let r=m.iterToArray(i[0]!==void 0&&typeof i[0]=="number"?[i]:i),n=typeof t=="number"?u.make(r[0].length,t):t;e||(e=u.make(r[0].length,0));for(let s=0,o=r.length;si[Math.floor(g.boundAngle(g.toDegree(e)))]}}static sinTable(){let i=new Float64Array(360);for(let e=0;e<360;e++)i[e]=Math.sin(e*Math.PI/180);return{table:i,sin:e=>i[Math.floor(g.boundAngle(g.toDegree(e)))]}}},K=class{static linear(i,t=1){return t*i}static quadraticIn(i,t=1){return t*i*i}static quadraticOut(i,t=1){return-t*i*(i-2)}static quadraticInOut(i,t=1){let e=i*2;return i<.5?t/2*i*i*4:-t/2*((e-1)*(e-3)-1)}static cubicIn(i,t=1){return t*i*i*i}static cubicOut(i,t=1){let e=i-1;return t*(e*e*e+1)}static cubicInOut(i,t=1){let e=i*2;return i<.5?t/2*e*e*e:t/2*((e-2)*(e-2)*(e-2)+2)}static exponentialIn(i,t=1,e=.25){return t*Math.pow(i,1/e)}static exponentialOut(i,t=1,e=.25){return t*Math.pow(i,e)}static sineIn(i,t=1){return-t*Math.cos(i*L.half_pi)+t}static sineOut(i,t=1){return t*Math.sin(i*L.half_pi)}static sineInOut(i,t=1){return-t/2*(Math.cos(Math.PI*i)-1)}static cosineApprox(i,t=1){let e=i*i,r=e*e,n=r*e;return t*(4*n/9-17*r/9+22*e/9)}static circularIn(i,t=1){return-t*(Math.sqrt(1-i*i)-1)}static circularOut(i,t=1){let e=i-1;return t*Math.sqrt(1-e*e)}static circularInOut(i,t=1){let e=i*2;return i<.5?-t/2*(Math.sqrt(1-e*e)-1):t/2*(Math.sqrt(1-(e-2)*(e-2))+1)}static elasticIn(i,t=1,e=.7){let r=i-1,n=e/L.two_pi*1.5707963267948966;return t*(-Math.pow(2,10*r)*Math.sin((r-n)*L.two_pi/e))}static elasticOut(i,t=1,e=.7){let r=e/L.two_pi*1.5707963267948966;return t*(Math.pow(2,-10*i)*Math.sin((i-r)*L.two_pi/e))+t}static elasticInOut(i,t=1,e=.6){let r=i*2,n=e/L.two_pi*1.5707963267948966;return i<.5?(r-=1,t*(-.5*(Math.pow(2,10*r)*Math.sin((r-n)*L.two_pi/e)))):(r-=1,t*(.5*(Math.pow(2,-10*r)*Math.sin((r-n)*L.two_pi/e)))+t)}static bounceIn(i,t=1){return t-K.bounceOut(1-i,t)}static bounceOut(i,t=1){return i<1/2.75?t*(7.5625*i*i):i<2/2.75?(i-=1.5/2.75,t*(7.5625*i*i+.75)):i<2.5/2.75?(i-=2.25/2.75,t*(7.5625*i*i+.9375)):(i-=2.625/2.75,t*(7.5625*i*i+.984375))}static bounceInOut(i,t=1){return i<.5?K.bounceIn(i*2,t)/2:K.bounceOut(i*2-1,t)/2+t/2}static sigmoid(i,t=1,e=10){let r=e*(i-.5);return t/(1+Math.exp(-r))}static logSigmoid(i,t=1,e=.7){e=Math.max(L.epsilon,Math.min(1-L.epsilon,e)),e=1/(1-e);let r=1/(1+Math.exp((i-.5)*e*-2)),n=1/(1+Math.exp(e)),s=1/(1+Math.exp(-e));return t*(r-n)/(s-n)}static seat(i,t=1,e=.5){return i<.5?t*Math.pow(2*i,1-e)/2:t*(1-Math.pow(2*(1-i),1-e)/2)}static quadraticBezier(i,t=1,e=[.05,.95]){let r=typeof e!="number"?e[0]:e,n=typeof e!="number"?e[1]:.5,s=1-2*r;s===0&&(s=L.epsilon);let o=(Math.sqrt(r*r+s*i)-r)/s;return t*((1-2*n)*(o*o)+2*n*o)}static cubicBezier(i,t=1,e=[.1,.7],r=[.9,.2]){let n=new c(new u(0,0),new u(e),new u(r),new u(1,1));return t*D.bezierStep(new u(i*i*i,i*i,i,1),D.controlPoints(n)).y}static quadraticTarget(i,t=1,e=[.2,.35]){let r=Math.min(1-L.epsilon,Math.max(L.epsilon,e[0])),n=Math.min(1,Math.max(0,e[1])),s=(1-n)/(1-r)-n/r,o=(s*(r*r)-n)/r,l=s*(i*i)-o*i;return t*Math.min(1,Math.max(0,l))}static cliff(i,t=1,e=.5){return i>e?t:0}static step(i,t,e,r,...n){let s=1/t,o=Math.floor(e/s)*s;return i(o,r,...n)}},xt=class{constructor(i){this._dims=0;this._source=c.fromPtArray(i),this.calc()}get max(){return this._max.clone()}get min(){return this._min.clone()}get magnitude(){return this._mag.clone()}calc(){if(!this._source)return;let i=this._source[0].length;this._dims=i;let t=new u(i),e=new u(i),r=new u(i);for(let n=0;n=n.length||!(r[s]in n));s++)t.push(n[r[s]])}else e&&(t=[].slice.call(i[0]));return t}static warn(i="error",t=void 0){if(Z.warnLevel()=="error")throw new Error(i);return Z.warnLevel()=="warn"&&console.warn(i),t}static randomInt(i,t=0){return Z.warn("Util.randomInt is deprecated. Please use `Num.randomRange`"),Math.floor(v.random()*i)+t}static split(i,t,e,r=!1,n=!0){let s=[],o=[],l=e||t,a=0;if(i.length<=0||l<=0)return[];for(;a=i.length)break;o.push(i[a+h])}a+=l,(!n||n&&o.length===t)&&s.push(o)}return s}static flatten(i,t=!0){let e=t?new c:new Array;return e.concat.apply(e,i)}static combine(i,t,e){let r=[];for(let n=0,s=i.length;n=i&&(n=t+(n-i)),r&&r(n),n}}static forRange(i,t,e=0,r=1){let n=[];for(let s=e,o=t;s=200&&e.status<400?t(e.responseText,!0):t(`Server error (${e.status}) when loading "${i}"`,!1)},e.onerror=function(){t("Unknown network error",!1)},e.send()}static download(i,t="pts_canvas_image",e="png",r=1){let n=e==="jpg"?"jpeg":e;i.element.toBlob(function(s){let o=document.createElement("a"),l=URL.createObjectURL(s);o.href=l,o.download=`${t}.${e}`,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(l)},`image/${n}`,r)}static performance(i=10){let t=Date.now(),e=[];return function(){let r=Date.now();return e.push(r-t),e.length>=i&&e.shift(),t=r,Math.floor(e.reduce((n,s)=>n+s,0)/e.length)}}static arrayCheck(i,t=2){return Array.isArray(i)&&i.length0?m.getArgs(t):[0,0];super(e)}static make(t,e=0,r=!1){let n=new Float32Array(t);if(e&&n.fill(e),r)for(let s=0,o=n.length;se)return!1;return!0}to(...t){let e=m.getArgs(t);for(let r=0,n=Math.min(this.length,e.length);rt(e,...r)}ops(t){let e=[];for(let r=0,n=t.length;rt(e,...r)}ops(t){let e=[];for(let r=0,n=t.length;re?n[t]-r[t]:r[t]-n[t])}forEachPt(t,...e){if(!this[0][t])return m.warn(`${t} is not a function of Pt`),this;for(let r=0,n=this.length;rt+e.toString()+" ","")+" ]"}},G=class extends c{constructor(...t){super(...t);this._center=new u;this._size=new u;this._topLeft=new u;this._bottomRight=new u;this._inited=!1;this.init()}static fromBoundingRect(t){let e=new G(new u(t.left||0,t.top||0),new u(t.right||0,t.bottom||0));return t.width&&t.height&&(e.size=new u(t.width,t.height)),e}static fromGroup(t){let e=m.iterToArray(t);if(e.length<2)throw new Error("Cannot create a Bound from a group that has less than 2 Pt");return new G(e[0],e[e.length-1])}init(){if(this.p1&&(this._size=this.p1.clone(),this._inited=!0),this.p1&&this.p2){let t=this.p1,e=this.p2;this.topLeft=t.$min(e),this._bottomRight=t.$max(e),this._updateSize(),this._inited=!0}}clone(){return new G(this._topLeft.clone(),this._bottomRight.clone())}_updateSize(){this._size=this._bottomRight.$subtract(this._topLeft).abs(),this._updateCenter()}_updateCenter(){this._center=this._size.$multiply(.5).add(this._topLeft)}_updatePosFromTop(){this._bottomRight=this._topLeft.$add(this._size),this._updateCenter()}_updatePosFromBottom(){this._topLeft=this._bottomRight.$subtract(this._size),this._updateCenter()}_updatePosFromCenter(){let t=this._size.$multiply(.5);this._topLeft=this._center.$subtract(t),this._bottomRight=this._center.$add(t)}get size(){return new u(this._size)}set size(t){this._size=new u(t),this._updatePosFromTop()}get center(){return new u(this._center)}set center(t){this._center=new u(t),this._updatePosFromCenter()}get topLeft(){return new u(this._topLeft)}set topLeft(t){this._topLeft=new u(t),this[0]=this._topLeft,this._updateSize()}get bottomRight(){return new u(this._bottomRight)}set bottomRight(t){this._bottomRight=new u(t),this[1]=this._bottomRight,this._updateSize()}get width(){return this._size.length>0?this._size.x:0}set width(t){this._size.x=t,this._updatePosFromTop()}get height(){return this._size.length>1?this._size.y:0}set height(t){this._size.y=t,this._updatePosFromTop()}get depth(){return this._size.length>2?this._size.z:0}set depth(t){this._size.z=t,this._updatePosFromTop()}get x(){return this.topLeft.x}get y(){return this.topLeft.y}get z(){return this.topLeft.z}get inited(){return this._inited}update(){return this._topLeft=this[0],this._bottomRight=this[1],this._updateSize(),this}};var Ct={};B(Ct,{UI:()=>j,UIButton:()=>mt,UIDragger:()=>It,UIPointerActions:()=>A,UIShape:()=>J});var J={rectangle:"rectangle",circle:"circle",polygon:"polygon",polyline:"polyline",line:"line"},A={up:"up",down:"down",move:"move",drag:"drag",uidrag:"uidrag",drop:"drop",uidrop:"uidrop",over:"over",out:"out",enter:"enter",leave:"leave",click:"click",keydown:"keydown",keyup:"keyup",contextmenu:"contextmenu",all:"all"},Q=class{constructor(i,t,e={},r){this._holds=new Map;this._group=c.fromArray(i),this._shape=t,this._id=r===void 0?`ui_${Q._counter++}`:r,this._states=e,this._actions={}}static fromRectangle(i,t,e){return new this(i,J.rectangle,t,e)}static fromCircle(i,t,e){return new this(i,J.circle,t,e)}static fromPolygon(i,t,e){return new this(i,J.polygon,t,e)}static fromUI(i,t,e){return new this(i.group,i.shape,t||i._states,e)}get id(){return this._id}set id(i){this._id=i}get group(){return this._group}set group(i){this._group=i}get shape(){return this._shape}set shape(i){this._shape=i}state(i,t){return i?t!==void 0?(this._states[i]=t,this):this._states[i]:null}on(i,t){return this._actions[i]||(this._actions[i]=[]),Q._addHandler(this._actions[i],t)}off(i,t){return this._actions[i]?t===void 0?(delete this._actions[i],!0):Q._removeHandler(this._actions[i],t):!1}listen(i,t,e){if(this._actions[i]!==void 0){if(this._within(t)||Array.from(this._holds.values()).indexOf(i)>=0)return Q._trigger(this._actions[i],this,t,i,e),!0;if(this._actions.all)return Q._trigger(this._actions.all,this,t,i,e),!0}return!1}hold(i){let t=Math.max(0,...Array.from(this._holds.keys()))+1;return this._holds.set(t,i),t}unhold(i){i!==void 0?this._holds.delete(i):this._holds.clear()}static track(i,t,e,r){for(let n=0,s=i.length;n=0&&ti.length}else return!1}},j=Q;j._counter=0;var mt=class extends j{constructor(t,e,r={},n){super(t,e,r,n);this._hoverID=-1;r.hover===void 0&&(this._states.hover=!1),r.clicks===void 0&&(this._states.clicks=0);let s=A;this.on(s.up,(o,l,a,h)=>{this.state("clicks",this._states.clicks+1)}),this.on(s.move,(o,l,a,h)=>{if(this._within(l)&&!this._states.hover){this.state("hover",!0),j._trigger(this._actions[s.enter],this,l,s.enter,h);var d=this.hold(s.move);this._hoverID=this.on(s.move,(f,w)=>{!this._within(w)&&!this.state("dragging")&&(this.state("hover",!1),j._trigger(this._actions[s.leave],this,l,s.leave,h),this.off(s.move,this._hoverID),this.unhold(d))})}})}onClick(t){return this.on(A.up,t)}offClick(t){return this.off(A.up,t)}onContextMenu(t){return this.on(A.contextmenu,t)}offContextMenu(t){return this.off(A.contextmenu,t)}onHover(t,e){var r=[void 0,void 0];return t&&(r[0]=this.on(A.enter,t)),e&&(r[1]=this.on(A.leave,e)),r}offHover(t,e){var r=[!1,!1];return(t===void 0||t>=0)&&(r[0]=this.off(A.enter,t)),(e===void 0||e>=0)&&(r[1]=this.off(A.leave,e)),r}},It=class extends mt{constructor(t,e,r={},n){super(t,e,r,n);this._draggingID=-1;this._moveHoldID=-1;this._dropHoldID=-1;this._upHoldID=-1;r.dragging===void 0&&(this._states.dragging=!1),r.moved===void 0&&(this._states.moved=!1),r.offset===void 0&&(this._states.offset=new u);let s=A;this.on(s.down,(l,a,h,p)=>{this._moveHoldID===-1&&(this.state("dragging",!0),this.state("offset",new u(a).subtract(l.group[0])),this._moveHoldID=this.hold(s.move)),this._dropHoldID===-1&&(this._dropHoldID=this.hold(s.drop)),this._upHoldID===-1&&(this._upHoldID=this.hold(s.up)),this._draggingID===-1&&(this._draggingID=this.on(s.move,(d,f)=>{this.state("dragging")&&(j._trigger(this._actions[s.uidrag],d,f,s.uidrag,p),this.state("moved",!0))}))});let o=(l,a,h,p)=>{this.state("dragging",!1),this.off(s.move,this._draggingID),this._draggingID=-1,this.unhold(this._moveHoldID),this._moveHoldID=-1,this.unhold(this._dropHoldID),this._dropHoldID=-1,this.unhold(this._upHoldID),this._upHoldID=-1,this.state("moved")&&(j._trigger(this._actions[s.uidrop],l,a,s.uidrop,p),this.state("moved",!1))};this.on(s.drop,o),this.on(s.up,o),this.on(s.out,o)}onDrag(t){return this.on(A.uidrag,t)}offDrag(t){return this.off(A.uidrag,t)}onDrop(t){return this.on(A.uidrop,t)}offDrop(t){return this.off(A.uidrop,t)}};var dt=class{constructor(){this.id="space";this.bound=new G;this._time={prev:0,diff:0,end:-1,min:0};this.players={};this.playerCount=0;this._animID=-1;this._pause=!1;this._refresh=void 0;this._pointer=new u;this._isReady=!1;this._playing=!1}refresh(i){return this._refresh=i,this}minFrameTime(i=0){this._time.min=i}add(i){let t=typeof i=="function"?{animate:i}:i,e=this.playerCount++,r=this.id+e;return this.players[r]=t,t.animateID=r,t.resize&&this.bound.inited&&t.resize(this.bound),this._refresh===void 0&&(this._refresh=!0),this}remove(i){return delete this.players[i.animateID],this}removeAll(){return this.players={},this}play(i=0){if(!(i===0&&this._animID!==-1)){if(this._animID=requestAnimationFrame(this.play.bind(this)),this._pause)return this;if(this._time.diff=i-this._time.prev,this._time.diff=0&&i>this._time.end&&(cancelAnimationFrame(this._animID),this._animID=-1,this._playing=!1)}pause(i=!1){return this._pause=i?!this._pause:!0,this}resume(){return this._pause=!1,this}stop(i=0){return this._time.end=i,this}playOnce(i=0){return this.play(),this.stop(i),this}render(i){return this._renderFunc&&this._renderFunc(i,this),this}set customRendering(i){this._renderFunc=i}get customRendering(){return this._renderFunc}get isPlaying(){return this._playing}get outerBound(){return this.bound.clone()}get innerBound(){return new G(u.make(this.size.length,0),this.size.clone())}get size(){return this.bound.size.clone()}get center(){return this.size.divide(2)}get width(){return this.bound.width}get height(){return this.bound.height}},tt=class extends dt{constructor(){super(...arguments);this._pressed=!1;this._dragged=!1;this._hasMouse=!1;this._hasTouch=!1;this._hasKeyboard=!1}get pointer(){let t=this._pointer.clone();return t.id=this._pointer.id,t}bindCanvas(t,e,r={},n){(n||this._canvas).addEventListener(t,e,r)}unbindCanvas(t,e,r={},n){(n||this._canvas).removeEventListener(t,e,r)}bindDoc(t,e,r={}){document&&document.addEventListener(t,e,r)}unbindDoc(t,e,r={}){document&&document.removeEventListener(t,e,r)}bindMouse(t=!0,e){return t?(this._mouseDown=this._mouseDown.bind(this),this._mouseUp=this._mouseUp.bind(this),this._mouseOver=this._mouseOver.bind(this),this._mouseOut=this._mouseOut.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseClick=this._mouseClick.bind(this),this._contextMenu=this._contextMenu.bind(this),this.bindCanvas("mousedown",this._mouseDown,{},e),this.bindCanvas("mouseup",this._mouseUp,{},e),this.bindCanvas("mouseover",this._mouseOver,{},e),this.bindCanvas("mouseout",this._mouseOut,{},e),this.bindCanvas("mousemove",this._mouseMove,{},e),this.bindCanvas("click",this._mouseClick,{},e),this.bindCanvas("contextmenu",this._contextMenu,{},e),this._hasMouse=!0):(this.unbindCanvas("mousedown",this._mouseDown,{},e),this.unbindCanvas("mouseup",this._mouseUp,{},e),this.unbindCanvas("mouseover",this._mouseOver,{},e),this.unbindCanvas("mouseout",this._mouseOut,{},e),this.unbindCanvas("mousemove",this._mouseMove,{},e),this.unbindCanvas("click",this._mouseClick,{},e),this.unbindCanvas("contextmenu",this._contextMenu,{},e),this._hasMouse=!1),this}bindTouch(t=!0,e=!1,r){return t?(this.bindCanvas("touchstart",this._touchStart.bind(this),{passive:e},r),this.bindCanvas("touchend",this._mouseUp.bind(this),{},r),this.bindCanvas("touchmove",this._touchMove.bind(this),{passive:e},r),this.bindCanvas("touchcancel",this._mouseOut.bind(this),{},r),this._hasTouch=!0):(this.unbindCanvas("touchstart",this._touchStart.bind(this),{passive:e},r),this.unbindCanvas("touchend",this._mouseUp.bind(this),{},r),this.unbindCanvas("touchmove",this._touchMove.bind(this),{passive:e},r),this.unbindCanvas("touchcancel",this._mouseOut.bind(this),{},r),this._hasTouch=!1),this}bindKeyboard(t=!0){return t?(this._keyDownBind=this._keyDown.bind(this),this._keyUpBind=this._keyUp.bind(this),this.bindDoc("keydown",this._keyDownBind,{}),this.bindDoc("keyup",this._keyUpBind,{}),this._hasKeyboard=!0):(this.unbindDoc("keydown",this._keyDownBind,{}),this.unbindDoc("keyup",this._keyUpBind,{}),this._hasKeyboard=!1),this}touchesToPoints(t,e="touches"){if(!t||!t[e])return[];let r=[];for(var n=0;n0,a=e.changedTouches.item(0);r=l?a.pageX-this.outerBound.x:0,n=l?a.pageY-this.outerBound.y:0,o.action&&o.action(t,r,n,e)}t&&(this._pointer.to(r,n),this._pointer.id=t)}_mouseDown(t){return this._mouseAction(A.down,t),this._pressed=!0,!1}_mouseUp(t){return this._dragged?this._mouseAction(A.drop,t):this._mouseAction(A.up,t),this._pressed=!1,this._dragged=!1,!1}_mouseMove(t){return this._mouseAction(A.move,t),this._pressed&&(this._dragged=!0,this._mouseAction(A.drag,t)),!1}_mouseOver(t){return this._mouseAction(A.over,t),!1}_mouseOut(t){return this._mouseAction(A.out,t),this._dragged&&this._mouseAction(A.drop,t),this._dragged=!1,!1}_mouseClick(t){return this._mouseAction(A.click,t),this._pressed=!1,this._dragged=!1,!1}_contextMenu(t){return this._mouseAction(A.contextmenu,t),!1}_touchMove(t){return this._mouseMove(t),t.preventDefault(),!1}_touchStart(t){return this._mouseDown(t),t.preventDefault(),!1}_keyDown(t){return this._keyboardAction(A.keydown,t),!1}_keyUp(t){return this._keyboardAction(A.keyup,t),!1}_keyboardAction(t,e){if(this.isPlaying){for(let r in this.players)if(this.players.hasOwnProperty(r)){let n=this.players[r];n.action&&n.action(t,e.shiftKey?1:0,e.altKey?1:0,e)}}}};var Dt={};B(Dt,{Font:()=>N,Form:()=>pt,VisualForm:()=>V});var pt=class{constructor(){this._ready=!1}get ready(){return this._ready}},V=class extends pt{constructor(){super(...arguments);this._filled=!0;this._stroked=!0;this._font=new N(14,"sans-serif")}get filled(){return this._filled}set filled(t){this._filled=t}get stroked(){return this._stroked}set stroked(t){this._stroked=t}get currentFont(){return this._font}_multiple(t,e,...r){if(!t)return this;for(let n=0,s=t.length;nnt});var nt=class{static textWidthEstimator(i,t=["M","n","."],e=[.06,.8,.14]){let r=t.map(i),n=new u(e).dot(r);return s=>s.length*n}static truncate(i,t,e,r=""){let n=Math.floor(t.length*Math.min(1,e/i(t)));return n0?Math.max(n,e):n}}};var $t={};B($t,{Img:()=>H});var H=class{constructor(i=!1,t,e){this._scale=1;this._loaded=!1;this._editable=i,this._space=t,this._scale=this._space?this._space.pixelScale:1,this._img=new Image,e&&(this._img.crossOrigin="Anonymous")}static load(i,t=!1,e,r){let n=new H(t,e);return n.load(i).then(s=>{r&&r(s)}),n}static loadAsync(i,t=!1,e){return lt(this,null,function*(){return yield new H(t,e).load(i)})}static loadPattern(i,t,e="repeat",r=!1){return lt(this,null,function*(){return(yield H.loadAsync(i,r,t)).pattern(e)})}static blank(i,t,e){let r=new H(!0,t),n=e||t.pixelScale;return r.initCanvas(i[0],i[1],n),r}load(i){return new Promise((t,e)=>{this._editable&&!document&&e("Cannot create html canvas element. document not found."),this._img.src=i,this._img.onload=()=>{this._editable&&(this._cv||(this._cv=document.createElement("canvas")),this._drawToScale(this._scale,this._img),this._data=this._ctx.getImageData(0,0,this._cv.width,this._cv.height)),this._loaded=!0,t(this)},this._img.onerror=r=>{e(r)}})}_drawToScale(i,t){let e=t.width,r=t.height;this.initCanvas(e,r,i),t&&this._ctx.drawImage(t,0,0,e,r,0,0,this._cv.width,this._cv.height)}initCanvas(i,t,e=1){if(!this._editable){console.error("Cannot initiate canvas because this Img is not set to be editable");return}this._cv||(this._cv=document.createElement("canvas"));let r=typeof e=="number"?[e,e]:e;this._cv.width=i*r[0],this._cv.height=t*r[1],this._ctx=this._cv.getContext("2d"),this._loaded=!0}bitmap(i){let t=i?i[0]:this._cv.width,e=i?i[1]:this._cv.height;return createImageBitmap(this._cv,0,0,t,e)}pattern(i="repeat",t=!1){if(!this._space)throw"Cannot find CanvasSpace ctx to create image pattern";return this._space.ctx.createPattern(t?this._cv:this._img,i)}sync(){this._scale!==1?this.bitmap().then(i=>{this._drawToScale(1/this._scale,i),this.load(this.toBase64())}):this._img.src=this.toBase64()}pixel(i,t=!0){let e=typeof t=="number"?t:t?this._scale:1;return H.getPixel(this._data,[i[0]*e,i[1]*e])}static getPixel(i,t){let e=new u(0,0,0,0);if(t[0]>=i.width||t[1]>=i.height)return e;let r=Math.floor(t[1])*(i.width*4)+Math.floor(t[0])*4,n=i.data;return r>=n.length-4?e:new u(n[r],n[r+1],n[r+2],n[r+3])}resize(i,t=!1){let e=t?i:[i[0]/this._img.naturalWidth,i[1]/this._img.naturalHeight];return this._drawToScale(e,this._img),this._data=this._ctx.getImageData(0,0,this._cv.width,this._cv.height),this}crop(i){let t=i.topLeft.scale(this._scale),e=i.size.scale(this._scale);return this._ctx.getImageData(t.x,t.y,e.x,e.y)}filter(i){return this._ctx.filter=i,this._ctx.drawImage(this._cv,0,0),this._ctx.filter="none",this}cleanup(){this._cv&&this._cv.remove(),this._img&&this._img.remove(),this._data=null}static fromBlob(i,t=!1,e){let r=URL.createObjectURL(i);return new H(t,e).load(r)}static imageDataToBlob(i){return new Promise(function(t,e){document||e("Cannot create html canvas element. document not found.");let r=document.createElement("canvas");r.width=i.width,r.height=i.height,r.getContext("2d").putImageData(i,0,0),r.toBlob(n=>{t(n),r.remove()})})}toBase64(){return this._cv.toDataURL()}toBlob(){return new Promise(i=>{this._cv.toBlob(t=>i(t))})}getForm(){return this._editable||console.error("Cannot get a CanvasForm because this Img is not editable"),this._ctx?new E(this._ctx):void 0}get current(){return this._editable?this._cv:this._img}get image(){return this._img}get canvas(){return this._cv}get data(){return this._data}get ctx(){return this._ctx}get loaded(){return this._loaded}get pixelScale(){return this._scale}get imageSize(){return!this._img.width||!this._img.height?this.canvasSize.$divide(this._scale):new u(this._img.width,this._img.height)}get canvasSize(){return new u(this._cv.width,this._cv.height)}get scaledMatrix(){let i=1/this._scale;return new P().scale2D([i,i])}};var at=class extends tt{constructor(t,e){super();this._pixelScale=1;this._autoResize=!0;this._bgcolor="#e1e9f0";this._offscreen=!1;this._initialResize=!1;var r=null,n=!1;if(this.id="pt",t instanceof Element)r=t,this.id="pts_existing_space";else{let s=t;s=t[0]==="#"||t[0]==="."?t:"#"+t,r=document.querySelector(s),n=!0,this.id=s.substr(1)}r?r.nodeName.toLowerCase()!="canvas"?(this._container=r,this._canvas=this._createElement("canvas",this.id+"_canvas"),this._container.appendChild(this._canvas),this._initialResize=!0):(this._canvas=r,this._container=r.parentElement,this._autoResize=!1):(this._container=this._createElement("div",this.id+"_container"),this._canvas=this._createElement("canvas",this.id),this._container.appendChild(this._canvas),document.body.appendChild(this._container),n=!1),setTimeout(this._ready.bind(this,e),100),this._ctx=this._canvas.getContext("2d")}_createElement(t="div",e){let r=document.createElement(t);return r.setAttribute("id",e),r}_ready(t){if(!this._container)throw new Error(`Cannot initiate #${this.id} element`);this._isReady=!0,this._resizeHandler(null),this.clear(this._bgcolor),this._canvas.dispatchEvent(new Event("ready"));for(let e in this.players)this.players.hasOwnProperty(e)&&this.players[e].start&&this.players[e].start(this.bound.clone(),this);this._pointer=this.center,this._initialResize=!1,t&&t(this.bound,this._canvas)}setup(t){if(this._bgcolor=t.bgcolor?t.bgcolor:"transparent",this.autoResize=t.resize!=null?t.resize:!1,t.retina!==!1){let e=window&&window.devicePixelRatio||1,r=this._ctx.webkitBackingStorePixelRatio||this._ctx.mozBackingStorePixelRatio||this._ctx.msBackingStorePixelRatio||this._ctx.oBackingStorePixelRatio||this._ctx.backingStorePixelRatio||1;this._pixelScale=Math.max(1,e/r)}return t.offscreen?(this._offscreen=!0,this._offCanvas=this._createElement("canvas",this.id+"_offscreen"),this._offCtx=this._offCanvas.getContext("2d")):this._offscreen=!1,t.pixelDensity&&(this._pixelScale=t.pixelDensity),this}set autoResize(t){window&&(this._autoResize=t,t?window.addEventListener("resize",this._resizeHandler.bind(this)):window.removeEventListener("resize",this._resizeHandler.bind(this)))}get autoResize(){return this._autoResize}resize(t,e){this.bound=t,this._canvas.width=Math.ceil(this.bound.size.x)*this._pixelScale,this._canvas.height=Math.ceil(this.bound.size.y)*this._pixelScale,this._canvas.style.width=Math.ceil(this.bound.size.x)+"px",this._canvas.style.height=Math.ceil(this.bound.size.y)+"px",this._offscreen&&(this._offCanvas.width=Math.ceil(this.bound.size.x)*this._pixelScale,this._offCanvas.height=Math.ceil(this.bound.size.y)*this._pixelScale),this._pixelScale!=1&&(this._ctx.scale(this._pixelScale,this._pixelScale),this._offscreen&&this._offCtx.scale(this._pixelScale,this._pixelScale));for(let r in this.players)if(this.players.hasOwnProperty(r)){let n=this.players[r];n.resize&&n.resize(this.bound,e)}return this.render(this._ctx),e&&!this.isPlaying&&this.playOnce(0),this}_resizeHandler(t){if(!window)return;let e=this._autoResize||this._initialResize?this._container.getBoundingClientRect():this._canvas.getBoundingClientRect();if(e){let r=G.fromBoundingRect(e);r.center=r.center.add(window.pageXOffset,window.pageYOffset),this.resize(r,t)}}set background(t){this._bgcolor=t}get background(){return this._bgcolor}get pixelScale(){return this._pixelScale}get hasOffscreen(){return this._offscreen}get offscreenCtx(){return this._offCtx}get offscreenCanvas(){return this._offCanvas}getForm(){return new E(this)}get element(){return this._canvas}get parent(){return this._container}get ready(){return this._isReady}get ctx(){return this._ctx}clear(t){t&&(this._bgcolor=t);let e=this._ctx.fillStyle,r=Math.ceil(this.pixelScale);return!this._bgcolor||this._bgcolor==="transparent"?this._ctx.clearRect(-r,-r,this._canvas.width+r,this._canvas.height+r):((this._bgcolor.indexOf("rgba")===0||this._bgcolor.length===9&&this._bgcolor.indexOf("#")===0)&&this._ctx.clearRect(-r,-r,this._canvas.width+r,this._canvas.height+r),this._ctx.fillStyle=this._bgcolor,this._ctx.fillRect(-r,-r,this._canvas.width+r,this._canvas.height+r)),this._ctx.fillStyle=e,this}clearOffscreen(t){if(this._offscreen){let e=Math.ceil(this.pixelScale);t?(this._offCtx.fillStyle=t,this._offCtx.fillRect(-e,-e,this._canvas.width+e,this._canvas.height+e)):this._offCtx.clearRect(-e,-e,this._offCanvas.width+e,this._offCanvas.height+e)}return this}playItems(t){this._isReady&&(this._ctx.save(),this._offscreen&&this._offCtx.save(),super.playItems(t),this._ctx.restore(),this._offscreen&&this._offCtx.restore(),this.render(this._ctx))}dispose(){if(window)return window.removeEventListener("resize",this._resizeHandler.bind(this)),this.stop(),this.removeAll(),this}recorder(t,e="webm",r=15e6){let n=this._canvas.captureStream(),s=new MediaRecorder(n,{mimeType:`video/${e}`,bitsPerSecond:r});return s.ondataavailable=function(o){let l=URL.createObjectURL(new Blob([o.data],{type:`video/${e}`}));if(typeof t=="function")t(l);else if(t){let a=document.createElement("a");a.href=l,a.download=`canvas_video.${e}`,a.click(),a.remove()}},s}},E=class extends V{constructor(t){super();this._style={fillStyle:"#f03",strokeStyle:"#fff",lineWidth:1,lineJoin:"bevel",lineCap:"butt",globalAlpha:1};if(!t)return this;let e=r=>{this._ctx=r,this._ctx.fillStyle=this._style.fillStyle,this._ctx.strokeStyle=this._style.strokeStyle,this._ctx.lineJoin="bevel",this._ctx.font=this._font.value,this._ready=!0};t instanceof CanvasRenderingContext2D?e(t):(this._space=t,this._space.add({start:()=>{e(this._space.ctx)}}))}get space(){return this._space}get ctx(){return this._ctx}useOffscreen(t=!0,e=!1){return e&&this._space.clearOffscreen(typeof e=="string"?e:null),this._ctx=this._space.hasOffscreen&&t?this._space.offscreenCtx:this._space.ctx,this}renderOffscreen(t=[0,0]){this._space.hasOffscreen&&this._space.ctx.drawImage(this._space.offscreenCanvas,t[0],t[1],this._space.width,this._space.height)}alpha(t){return this._ctx.globalAlpha=t,this._style.globalAlpha=t,this}fill(t){return typeof t=="boolean"?this.filled=t:(this.filled=!0,this._style.fillStyle=t,this._ctx.fillStyle=t),this}fillOnly(t){return this.stroke(!1),this.fill(t)}stroke(t,e,r,n){return typeof t=="boolean"?this.stroked=t:(this.stroked=!0,this._style.strokeStyle=t,this._ctx.strokeStyle=t,e&&(this._ctx.lineWidth=e,this._style.lineWidth=e),r&&(this._ctx.lineJoin=r,this._style.lineJoin=r),n&&(this._ctx.lineCap=n,this._style.lineCap=n)),this}strokeOnly(t,e,r,n){return this.fill(!1),this.stroke(t,e,r,n)}applyFillStroke(t=!0,e=!0,r=1){return t&&(typeof t=="string"&&this.fill(t),this._ctx.fill()),e&&(typeof e=="string"&&this.stroke(e,r),this._ctx.stroke()),this}gradient(t){let e=[];t.length<2&&t.push([.99,"#000"],[1,"#000"]);for(let r=0,n=t.length;r{let s=n?this._ctx.createRadialGradient(r[0][0],r[0][1],Math.abs(r[1][0]),n[0][0],n[0][1],Math.abs(n[1][0])):this._ctx.createLinearGradient(r[0][0],r[0][1],r[1][0],r[1][1]);for(let o=0,l=e.length;othis._ctx.measureText(e).width):void 0,this}getTextWidth(t){return this._estimateTextWidth?this._estimateTextWidth(t):this._ctx.measureText(t+" .").width}_textTruncate(t,e,r=""){return nt.truncate(this.getTextWidth.bind(this),t,e,r)}_textAlign(t,e,r,n){let s=m.iterToArray(t);if(m.arrayCheck(s)){n||(n=k.center(s));var o=s[0][0];this._ctx.textAlign=="end"||this._ctx.textAlign=="right"?o=s[1][0]:(this._ctx.textAlign=="center"||this._ctx.textAlign=="middle")&&(o=n[0]);var l=n[1];return e=="top"||e=="start"?l=s[0][1]:(e=="end"||e=="bottom")&&(l=s[1][1]),r?new u(o+r[0],l+r[1]):new u(o,l)}}reset(){for(let t in this._style)this._style.hasOwnProperty(t)&&(this._ctx[t]=this._style[t]);return this._font=new N,this._ctx.font=this._font.value,this}_paint(){this._filled&&this._ctx.fill(),this._stroked&&this._ctx.stroke()}static point(t,e,r=5,n="square"){if(e){if(!E[n])throw new Error(`${n} is not a static function of CanvasForm`);E[n](t,e,r)}}point(t,e=5,r="square"){return E.point(this._ctx,t,e,r),this._paint(),this}static circle(t,e,r=10){e&&(t.beginPath(),t.arc(e[0],e[1],r,0,L.two_pi,!1),t.closePath())}circle(t){let e=m.iterToArray(t);return E.circle(this._ctx,e[0],e[1][0]),this._paint(),this}static ellipse(t,e,r,n=0,s=0,o=L.two_pi,l=!1){!e||!r||(t.beginPath(),t.ellipse(e[0],e[1],r[0],r[1],n,s,o,l))}ellipse(t,e,r=0,n=0,s=L.two_pi,o=!1){return E.ellipse(this._ctx,t,e,r,n,s,o),this._paint(),this}static arc(t,e,r,n,s,o){e&&(t.beginPath(),t.arc(e[0],e[1],r,n,s,o))}arc(t,e,r,n,s){return E.arc(this._ctx,t,e,r,n,s),this._paint(),this}static square(t,e,r){if(!e)return;let n=e[0]-r,s=e[1]-r,o=e[0]+r,l=e[1]+r;t.beginPath(),t.moveTo(n,s),t.lineTo(n,l),t.lineTo(o,l),t.lineTo(o,s),t.closePath()}square(t,e){return E.square(this._ctx,t,e),this._paint(),this}static line(t,e){if(!m.arrayCheck(e))return;let r=0;t.beginPath();for(let n of e)n&&(r++>0?t.lineTo(n[0],n[1]):t.moveTo(n[0],n[1]))}line(t){return E.line(this._ctx,t),this._paint(),this}static polygon(t,e){m.arrayCheck(e)&&(E.line(t,e),t.closePath())}polygon(t){return E.polygon(this._ctx,t),this._paint(),this}static rect(t,e){let r=m.iterToArray(e);m.arrayCheck(r)&&(t.beginPath(),t.moveTo(r[0][0],r[0][1]),t.lineTo(r[0][0],r[1][1]),t.lineTo(r[1][0],r[1][1]),t.lineTo(r[1][0],r[0][1]),t.closePath())}rect(t){return E.rect(this._ctx,t),this._paint(),this}static image(t,e,r,n){let s=m.iterToArray(e),o;if(typeof s[0]=="number")o=s;else if(n){let l=m.iterToArray(n);o=[l[0][0],l[0][1],l[1][0]-l[0][0],l[1][1]-l[0][1],s[0][0],s[0][1],s[1][0]-s[0][0],s[1][1]-s[0][1]]}else o=[s[0][0],s[0][1],s[1][0]-s[0][0],s[1][1]-s[0][1]];r instanceof H?r.loaded&&t.drawImage(r.image,...o):t.drawImage(r,...o)}image(t,e,r){return e instanceof H?e.loaded&&E.image(this._ctx,t,e.image,r):E.image(this._ctx,t,e,r),this}static imageData(t,e,r){let n=m.iterToArray(e);typeof n[0]=="number"?t.putImageData(r,n[0],n[1]):t.putImageData(r,n[0][0],n[0][1],n[0][0],n[0][1],n[1][0],n[1][1])}imageData(t,e){return E.imageData(this._ctx,t,e),this}static text(t,e,r,n){e&&t.fillText(r,e[0],e[1],n)}text(t,e,r){return E.text(this._ctx,t,e,r),this}textBox(t,e,r="middle",n="",s=!0){s&&(this._ctx.textBaseline=r);let o=k.size(t),l=this._textTruncate(e,o[0],n);return this.text(this._textAlign(t,r),l[0]),this}paragraphBox(t,e,r=1.2,n="top",s=!0){let o=m.iterToArray(t),l=k.size(o);this._ctx.textBaseline="top";let a=this._font.size*r,h=(_,T=[],S=0)=>{if(!_||s&&S*a>l[1]-a*2)return T;if(S>1e4)throw new Error("max recursion reached (10000)");let X=this._textTruncate(_,l[0],""),yt=X[0].indexOf(` -`);if(yt>=0)return T.push(X[0].substr(0,yt)),h(_.substr(yt+1),T,S+1);let ct=X[0].lastIndexOf(" ")+1;(ct<=0||X[1]===_.length)&&(ct=void 0);let Nt=X[0].substr(0,ct);return T.push(Nt),X[1]<=0||X[1]===_.length?T:h(_.substr(ct||X[1]),T,S+1)},p=h(e),d=p.length*a,f=o;if(n=="middle"||n=="center"){let _=(l[1]-d)/2;s&&(_=Math.max(0,_)),f=new c(o[0].$add(0,_),o[1].$subtract(0,_))}else n=="bottom"?f=new c(o[0].$add(0,l[1]-d),o[1]):f=new c(o[0],o[0].$add(l[0],d));let w=k.center(f);for(let _=0,T=p.length;_Et,Delaunay:()=>st,Noise:()=>gt});var Et=class{static distributeRandom(i,t,e=2){let r=new c;for(let n=0;n1&&s.push(i.y+v.random()*i.height),e>2&&s.push(i.z+v.random()*i.depth),r.push(new u(s))}return r}static distributeLinear(i,t){let e=m.iterToArray(i),r=M.subpoints(e,t-2);return r.unshift(e[0]),r.push(e[e.length-1]),r}static gridPts(i,t,e,r=[.5,.5]){if(t===0||e===0)throw new Error("grid columns and rows cannot be 0");let n=i.size.$subtract(1).$divide(t,e),s=n.$multiply(r),o=new c;for(let l=0;l0?Math.floor(l/r):l,d=n&&n>0?l%n:l;h.initNoise(t*d,e*p),h.seed(s),o.push(h),l++}return o}static delaunay(i){return st.from(i)}},ft=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],bt=[151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,9,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180],gt=class extends u{constructor(...t){super(...t);this.perm=[];this._n=new u(.01,.01);this.perm=bt.concat(bt)}initNoise(...t){return this._n=new u(...t),this}step(t=0,e=0){return this._n.add(t,e),this}seed(t){t>0&&t<1&&(t*=65536),t=Math.floor(t),t<256&&(t|=t<<8);for(let e=0;e<255;e++){let r=e&1?bt[e]^t&255:bt[e]^t>>8&255;this.perm[e]=this.perm[e+256]=r}return this}noise2D(){let t=Math.max(0,Math.floor(this._n[0]))%255,e=Math.max(0,Math.floor(this._n[1]))%255,r=this._n[0]%255-t,n=this._n[1]%255-e,s=x.dot(ft[(t+this.perm[e])%12],[r,n,0]),o=x.dot(ft[(t+this.perm[e+1])%12],[r,n-1,0]),l=x.dot(ft[(t+1+this.perm[e])%12],[r-1,n,0]),a=x.dot(ft[(t+1+this.perm[e+1])%12],[r-1,n-1,0]),h=d=>d*d*d*(d*(d*6-15)+10),p=h(r);return v.lerp(v.lerp(s,l,p),v.lerp(o,a,p),h(n))}},st=class extends c{constructor(){super(...arguments);this._mesh=[]}delaunay(t=!0){if(this.length<3)return[];this._mesh=[];let e=this.length,r=[];for(let h=0;hthis[p][0]-this[h][0]);let n=this.slice(),s=this._superTriangle();n=n.concat(s);let o=[this._circum(e,e+1,e+2,s)],l=[],a=[];for(let h=0,p=r.length;h0&&S[0]*S[0]>T*T){l.push(_),a.push(_.triangle),o.splice(w,1);continue}S[0]*S[0]+S[1]*S[1]-T*T>L.epsilon||(f.push(_.i,_.j,_.j,_.k,_.k,_.i),o.splice(w,1))}for(st._dedupe(f),w=f.length;w>1;)o.push(this._circum(f[--w],f[--w],d,!1,n))}for(let h=0,p=o.length;h1;){let r=t[--e],n=t[--e],s=e;for(;s>1;){let o=t[--s],l=t[--s];if(n==l&&r==o||n==o&&r==l){t.splice(e,2),t.splice(s,2);break}}}return t}};var St={};B(St,{Color:()=>ut});var b=class extends u{constructor(...t){super(...t);this._mode="rgb";this._isNorm=!1}static from(...t){let e=[1,1,1,1],r=m.getArgs(t);for(let n=0,s=e.length;nt[s]||"F";t=`${n(0)}${n(0)}${n(1)}${n(1)}${n(2)}${n(2)}`}let e=1;t.length===8&&(e=t.substr(6)&&255/255,t=t.substring(0,6));let r=parseInt(t,16);return new b(r>>16,r>>8&255,r&255,e)}static rgb(...t){return b.from(...t).toMode("rgb")}static hsl(...t){return b.from(...t).toMode("hsl")}static hsb(...t){return b.from(...t).toMode("hsb")}static lab(...t){return b.from(...t).toMode("lab")}static lch(...t){return b.from(...t).toMode("lch")}static luv(...t){return b.from(...t).toMode("luv")}static xyz(...t){return b.from(...t).toMode("xyz")}static maxValues(t){return b.ranges[t].zipSlice(1).$take([0,1,2])}get hex(){return this.toString("hex")}get rgb(){return this.toString("rgb")}get rgba(){return this.toString("rgba")}clone(){let t=new b(this);return t.toMode(this._mode),t}toMode(t,e=!1){if(e){let r=this._mode.toUpperCase()+"to"+t.toUpperCase();if(b[r])this.to(b[r](this,this._isNorm,this._isNorm));else throw new Error("Cannot convert color with "+r)}return this._mode=t,this}get mode(){return this._mode}get r(){return this[0]}set r(t){this[0]=t}get g(){return this[1]}set g(t){this[1]=t}get b(){return this[2]}set b(t){this[2]=t}get h(){return this._mode=="lch"?this[2]:this[0]}set h(t){let e=this._mode=="lch"?2:0;this[e]=t}get s(){return this[1]}set s(t){this[1]=t}get l(){return this._mode=="hsl"?this[2]:this[0]}set l(t){let e=this._mode=="hsl"?2:0;this[e]=t}get a(){return this[1]}set a(t){this[1]=t}get c(){return this[1]}set c(t){this[1]=t}get u(){return this[1]}set u(t){this[1]=t}get v(){return this[2]}set v(t){this[2]=t}set alpha(t){this.length>3&&(this[3]=t)}get alpha(){return this.length>3?this[3]:1}get normalized(){return this._isNorm}set normalized(t){this._isNorm=t}normalize(t=!0){if(this._isNorm==t)return this;let e=b.ranges[this._mode];for(let r=0;r<3;r++)this[r]=t?v.mapToRange(this[r],e[r][0],e[r][1],0,1):v.mapToRange(this[r],0,1,e[r][0],e[r][1]);return this._isNorm=t,this}$normalize(t=!0){return this.clone().normalize(t)}toString(t="mode"){if(t=="hex"){let e=r=>{let n=Math.floor(r).toString(16);return n.length<2?"0"+n:n};return`#${e(this[0])}${e(this[1])}${e(this[2])}`}else return t=="rgba"?`rgba(${Math.floor(this[0])},${Math.floor(this[1])},${Math.floor(this[2])},${this.alpha})`:t=="rgb"?`rgb(${Math.floor(this[0])},${Math.floor(this[1])},${Math.floor(this[2])})`:`${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`}static RGBtoHSL(t,e=!1,r=!1){let[n,s,o]=e?t:t.$normalize(),l=Math.max(n,s,o),a=Math.min(n,s,o),h=(l+a)/2,p=h,d=h;if(l==a)h=0,p=0;else{let f=l-a;p=d>.5?f/(2-l-a):f/(l+a),h=0,l===n?h=(s-o)/f+(s(d=d<0?d+1:d>1?d-1:d,d*6<1?a+(l-a)*d*6:d*2<1?l:d*3<2?a+(l-a)*(2/3-d)*6:a),p=r?1:255;return b.rgb(p*h(n+1/3),p*h(n),p*h(n-1/3),t.alpha)}static RGBtoHSB(t,e=!1,r=!1){let[n,s,o]=e?t:t.$normalize(),l=Math.max(n,s,o),a=Math.min(n,s,o),h=l-a,p=0,d=l===0?0:h/l,f=l;return l!=a&&(l===n?p=(s-o)/h+(s.04045?Math.pow((n[o]+.055)/1.055,2.4):n[o]/12.92,r||(n[o]=n[o]*100);let s=b.xyz(n[0]*.4124564+n[1]*.3575761+n[2]*.1804375,n[0]*.2126729+n[1]*.7151522+n[2]*.072175,n[0]*.0193339+n[1]*.119192+n[2]*.9503041,t.alpha);return r?s.normalize():s}static XYZtoRGB(t,e=!1,r=!1){let[n,s,o]=e?t:t.$normalize(),l=[n*3.2406254773200533+s*-1.5372079722103187+o*-.4986285986982479,n*-.9689307147293197+s*1.8757560608852415+o*.041517523842953964,n*.055710120445510616+s*-.2040210505984867+o*1.0569959422543882];for(let h=0;h<3;h++)l[h]=l[h]>.0031308?1.055*Math.pow(l[h],1/2.4)-.055:12.92*l[h],l[h]=Math.max(0,Math.min(1,l[h])),r||(l[h]=Math.round(l[h]*255));let a=b.rgb(l[0],l[1],l[2],t.alpha);return r?a.normalize():a}static XYZtoLAB(t,e=!1,r=!1){let n=e?t.$normalize(!1):t.clone(),s=.00885645167,o=903.296296296;n.divide(b.D65);let l=p=>p>s?Math.pow(p,1/3):(o*p+16)/116,a=l(n[1]),h=b.lab(116*a-16,500*(l(n[0])-a),200*(a-l(n[2])),t.alpha);return r?h.normalize():h}static LABtoXYZ(t,e=!1,r=!1){let n=e?t.$normalize(!1):t,s=(n[0]+16)/116,o=n[1]/500+s,l=s-n[2]/200,a=.00885645167,h=903.296296296,p=b.D65,d=Math.pow(o,3),f=Math.pow(l,3),w=b.xyz(p[0]*(d>a?d:(116*o-16)/h),p[1]*(n[0]>h*a?Math.pow((n[0]+16)/116,3):n[0]/h),p[2]*(f>a?f:(116*l-16)/h),t.alpha);return r?w.normalize():w}static XYZtoLUV(t,e=!1,r=!1){let[n,s,o]=e?t.$normalize(!1):t,l=4*n/(n+15*s+3*o),a=9*s/(n+15*s+3*o);s=s/100,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116;let h=4*b.D65[0]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]),p=9*b.D65[1]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]),d=116*s-16;return b.luv(d,13*d*(l-h),13*d*(a-p),t.alpha)}static LUVtoXYZ(t,e=!1,r=!1){let[n,s,o]=e?t.$normalize(!1):t,l=(n+16)/116,a=l*l*l;l=a>.008856?a:(l-16/116)/7.787;let h=4*b.D65[0]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]),p=9*b.D65[1]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]);s=s/(13*n)+h,o=o/(13*n)+p,l=l*100;let d=-1*(9*l*s)/((s-4)*o-s*o),f=(9*l-15*o*l-o*d)/(3*o);return b.xyz(d,l,f,t.alpha)}static LABtoLCH(t,e=!1,r=!1){let n=e?t.$normalize(!1):t,s=g.toDegree(g.boundRadian(Math.atan2(n[2],n[1])));return b.lch(n[0],Math.sqrt(n[1]*n[1]+n[2]*n[2]),s,t.alpha)}static LCHtoLAB(t,e=!1,r=!1){let n=e?t.$normalize(!1):t,s=g.toRadian(n[2]);return b.lab(n[0],Math.cos(s)*n[1],Math.sin(s)*n[1],t.alpha)}},ut=b;ut.D65=new u(95.047,100,108.883,1),ut.ranges={rgb:new c(new u(0,255),new u(0,255),new u(0,255)),hsl:new c(new u(0,360),new u(0,1),new u(0,1)),hsb:new c(new u(0,360),new u(0,1),new u(0,1)),lab:new c(new u(0,100),new u(-128,127),new u(-128,127)),lch:new c(new u(0,100),new u(0,100),new u(0,360)),luv:new c(new u(0,100),new u(-134,220),new u(-140,122)),xyz:new c(new u(0,100),new u(0,100),new u(0,100))};var zt={};B(zt,{DOMSpace:()=>R,HTMLForm:()=>et,HTMLSpace:()=>F});var R=class extends tt{constructor(t,e){super();this.id="domspace";this._autoResize=!0;this._bgcolor="#e1e9f0";this._css={};var r=null,n=!1;this.id="pts",t instanceof Element?(r=t,this.id="pts_existing_space"):(r=document.querySelector(t),n=!0,this.id=t.substr(1)),r?(this._canvas=r,this._container=r.parentElement):(this._container=R.createElement("div","pts_container"),this._canvas=R.createElement("div","pts_element"),this._container.appendChild(this._canvas),document.body.appendChild(this._container),n=!1),setTimeout(this._ready.bind(this,e),50)}static createElement(t="div",e,r){let n=document.createElement(t);return e&&n.setAttribute("id",e),r&&r.appendChild&&r.appendChild(n),n}_ready(t){if(!this._container)throw new Error(`Cannot initiate #${this.id} element`);this._isReady=!0,this._resizeHandler(null),this.clear(this._bgcolor),this._canvas.dispatchEvent(new Event("ready"));for(let e in this.players)this.players.hasOwnProperty(e)&&this.players[e].start&&this.players[e].start(this.bound.clone(),this);this._pointer=this.center,this.refresh(!1),t&&t(this.bound,this._canvas)}setup(t){return t.bgcolor&&(this._bgcolor=t.bgcolor),this.autoResize=t.resize!=null?t.resize:!1,this}getForm(){return null}set autoResize(t){this._autoResize=t,t?window.addEventListener("resize",this._resizeHandler.bind(this)):(delete this._css.width,delete this._css.height,window.removeEventListener("resize",this._resizeHandler.bind(this)))}get autoResize(){return this._autoResize}resize(t,e){this.bound=t,this.styles({width:`${t.width}px`,height:`${t.height}px`},!0);for(let r in this.players)if(this.players.hasOwnProperty(r)){let n=this.players[r];n.resize&&n.resize(this.bound,e)}return this}_resizeHandler(t){let e=G.fromBoundingRect(this._container.getBoundingClientRect());this._autoResize?this.styles({width:"100%",height:"100%"},!0):this.styles({width:`${e.width}px`,height:`${e.height}px`},!0),this.resize(e,t)}get element(){return this._canvas}get parent(){return this._container}get ready(){return this._isReady}clear(t){return t&&(this.background=t),this._canvas.innerHTML="",this}set background(t){this._bgcolor=t,this._container.style.backgroundColor=this._bgcolor}get background(){return this._bgcolor}style(t,e,r=!1){return this._css[t]=e,r&&(this._canvas.style[t]=e),this}styles(t,e=!1){for(let r in t)t.hasOwnProperty(r)&&this.style(r,t[r],e);return this}static setAttr(t,e){for(let r in e)e.hasOwnProperty(r)&&t.setAttribute(r,e[r]);return t}static getInlineStyles(t){let e="";for(let r in t)t.hasOwnProperty(r)&&t[r]&&(e+=`${r}: ${t[r]}; `);return e}dispose(){return window.removeEventListener("resize",this._resizeHandler.bind(this)),this.stop(),this.removeAll(),this}},F=class extends R{getForm(){return new et(this)}static htmlElement(i,t,e,r=!0){if(!i||!i.appendChild)throw new Error("parent is not a valid DOM element");let n=document.querySelector(`#${e}`);return n||(n=document.createElement(t),n.setAttribute("id",e),r&&n.setAttribute("class",e.substring(0,e.indexOf("-"))),i.appendChild(n)),n}remove(i){return this._container.querySelectorAll("."+et.scopeID(i)).forEach(e=>{e.parentNode.removeChild(e)}),super.remove(i)}removeAll(){return this._container.innerHTML="",super.removeAll()}},$=class extends V{constructor(t){super();this._style={filled:!0,stroked:!0,background:"#f03","border-color":"#fff",color:"#000","border-width":"1px","border-radius":"0","border-style":"solid",opacity:1,position:"absolute",top:0,left:0,width:0,height:0};this._ctx={group:null,groupID:"pts",groupCount:0,currentID:"pts0",currentClass:"",style:{}};this._ready=!1;this._space=t,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID="pts_dom_"+$.groupID++,this._ctx.style=Object.assign({},this._style),this._ready=!0}})}get space(){return this._space}styleTo(t,e,r=""){if(this._ctx.style[t]===void 0)throw new Error(`${t} style property doesn't exist`);this._ctx.style[t]=`${e}${r}`}alpha(t){return this.styleTo("opacity",t),this}fill(t){return typeof t=="boolean"?(this.styleTo("filled",t),t||this.styleTo("background","transparent")):(this.styleTo("filled",!0),this.styleTo("background",t)),this}stroke(t,e,r,n){return typeof t=="boolean"?(this.styleTo("stroked",t),t||this.styleTo("border-width",0)):(this.styleTo("stroked",!0),this.styleTo("border-color",t),this.styleTo("border-width",(e||1)+"px")),this}fillText(t){return this.styleTo("color",t),this}cls(t){return typeof t=="boolean"?this._ctx.currentClass="":this._ctx.currentClass=t,this}font(t,e,r,n,s){return typeof t=="number"?(this._font.size=t,s&&(this._font.face=s),e&&(this._font.weight=e),r&&(this._font.style=r),n&&(this._font.lineHeight=n)):this._font=t,this._ctx.style.font=this._font.value,this}reset(){return this._ctx.style=Object.assign({},this._style),this._font=new N(10,"sans-serif"),this._ctx.style.font=this._font.value,this}updateScope(t,e){return this._ctx.group=e,this._ctx.groupID=t,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(t){if(!t||t.animateID==null)throw new Error("item not defined or not yet added to Space");return this.updateScope($.scopeID(t),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(t){return t.currentID||`p-${$.domID++}`}static scopeID(t){return`item-${t.animateID}`}static style(t,e){let r=[];e.filled||r.push("background: none"),e.stroked||r.push("border: none");for(let n in e)if(e.hasOwnProperty(n)&&n!="filled"&&n!="stroked"){let s=e[n];if(s){if(!e.filled&&n.indexOf("background")===0)continue;if(!e.stroked&&n.indexOf("border-width")===0)continue;r.push(`${n}: ${s}`)}}return F.setAttr(t,{style:r.join(";")})}static rectStyle(t,e,r){return t.style.left=e[0]+"px",t.style.top=e[1]+"px",t.style.width=r[0]+"px",t.style.height=r[1]+"px",t}static textStyle(t,e){return t.style.left=e[0]+"px",t.style.top=e[1]+"px",t}static point(t,e,r=5,n="square"){return n==="circle"?$.circle(t,e,r):$.square(t,e,r)}point(t,e=5,r="square"){return this.nextID(),r=="circle"&&this.styleTo("border-radius","100%"),$.point(this._ctx,t,e,r),this}static circle(t,e,r=10){let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-circle ${t.currentClass}`}),$.rectStyle(t,new u(e).$subtract(r),new u(r*2,r*2)),$.style(n,t.style),n}circle(t){return this.nextID(),this.styleTo("border-radius","100%"),$.circle(this._ctx,t[0],t[1][0]),this}static square(t,e,r){let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-square ${t.currentClass}`}),$.rectStyle(t,new u(e).$subtract(r),new u(r*2,r*2)),$.style(n,t.style),n}square(t,e){return this.nextID(),$.square(this._ctx,t,e),this}static rect(t,e){let r=m.iterToArray(e);if(!m.arrayCheck(r))return;let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-rect ${t.currentClass}`}),$.rectStyle(t,r[0],r[1]),$.style(n,t.style),n}rect(t){return this.nextID(),this.styleTo("border-radius","0"),$.rect(this._ctx,t),this}static text(t,e,r){let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-text ${t.currentClass}`}),n.textContent=r,$.textStyle(t,e),$.style(n,t.style),n}text(t,e){return this.nextID(),$.text(this._ctx,t,e),this}log(t){return this.fill("#000").stroke("#fff",.5).text([10,14],t),this}arc(t,e,r,n,s){return m.warn("arc is not implemented in HTMLForm"),this}line(t){return m.warn("line is not implemented in HTMLForm"),this}polygon(t){return m.warn("polygon is not implemented in HTMLForm"),this}},et=$;et.groupID=0,et.domID=0;var Bt={};B(Bt,{SVGForm:()=>rt,SVGSpace:()=>U});var U=class extends R{constructor(t,e){super(t,e);this._bgcolor="#999";if(this._canvas.nodeName.toLowerCase()!="svg"){let r=U.svgElement(this._canvas,"svg",`${this.id}_svg`);this._container=this._canvas,this._canvas=r}}getForm(){return new rt(this)}get element(){return this._canvas}resize(t,e){return super.resize(t,e),U.setAttr(this.element,{viewBox:`0 0 ${this.bound.width} ${this.bound.height}`,width:`${this.bound.width}`,height:`${this.bound.height}`,xmlns:"http://www.w3.org/2000/svg",version:"1.1"}),this}static svgElement(t,e,r){if(!t||!t.appendChild)throw new Error("parent is not a valid DOM element");let n=document.querySelector(`#${r}`);return n||(n=document.createElementNS("http://www.w3.org/2000/svg",e),n.setAttribute("id",r),t.appendChild(n)),n}remove(t){return this._container.querySelectorAll("."+rt.scopeID(t)).forEach(r=>{r.parentNode.removeChild(r)}),super.remove(t)}removeAll(){return this._container.innerHTML="",super.removeAll()}},I=class extends V{constructor(t){super();this._style={filled:!0,stroked:!0,fill:"#f03",stroke:"#fff","stroke-width":1,"stroke-linejoin":"bevel","stroke-linecap":"sqaure",opacity:1};this._ctx={group:null,groupID:"pts",groupCount:0,currentID:"pts0",currentClass:"",style:{}};this._ready=!1;this._space=t,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID="pts_svg_"+I.groupID++,this._ctx.style=Object.assign({},this._style),this._ready=!0}})}get space(){return this._space}styleTo(t,e){if(this._ctx.style[t]===void 0)throw new Error(`${t} style property doesn't exist`);this._ctx.style[t]=e}alpha(t){return this.styleTo("opacity",t),this}fill(t){return typeof t=="boolean"?this.styleTo("filled",t):(this.styleTo("filled",!0),this.styleTo("fill",t)),this}stroke(t,e,r,n){return typeof t=="boolean"?this.styleTo("stroked",t):(this.styleTo("stroked",!0),this.styleTo("stroke",t),e&&this.styleTo("stroke-width",e),r&&this.styleTo("stroke-linejoin",r),n&&this.styleTo("stroke-linecap",n)),this}cls(t){return typeof t=="boolean"?this._ctx.currentClass="":this._ctx.currentClass=t,this}font(t,e,r,n,s){return typeof t=="number"?(this._font.size=t,s&&(this._font.face=s),e&&(this._font.weight=e),r&&(this._font.style=r),n&&(this._font.lineHeight=n)):this._font=t,this._ctx.style.font=this._font.value,this}reset(){return this._ctx.style=Object.assign({},this._style),this._font=new N(10,"sans-serif"),this._ctx.style.font=this._font.value,this}updateScope(t,e){return this._ctx.group=e,this._ctx.groupID=t,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(t){if(!t||t.animateID==null)throw new Error("item not defined or not yet added to Space");return this.updateScope(I.scopeID(t),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(t){return t.currentID||`p-${I.domID++}`}static scopeID(t){return`item-${t.animateID}`}static style(t,e){let r=[];e.filled||r.push("fill: none"),e.stroked||r.push("stroke: none");for(let n in e)if(e.hasOwnProperty(n)&&n!="filled"&&n!="stroked"){let s=e[n];if(s){if(!e.filled&&n.indexOf("fill")===0)continue;if(!e.stroked&&n.indexOf("stroke")===0)continue;r.push(`${n}: ${s}`)}}return R.setAttr(t,{style:r.join(";")})}static point(t,e,r=5,n="square"){return n==="circle"?I.circle(t,e,r):I.square(t,e,r)}point(t,e=5,r="square"){return this.nextID(),I.point(this._ctx,t,e,r),this}static circle(t,e,r=10){let n=U.svgElement(t.group,"circle",I.getID(t));return R.setAttr(n,{cx:e[0],cy:e[1],r,class:`pts-svgform pts-circle ${t.currentClass}`}),I.style(n,t.style),n}circle(t){this.nextID();let e=m.iterToArray(t);return I.circle(this._ctx,e[0],e[1][0]),this}static arc(t,e,r,n,s,o){let l=U.svgElement(t.group,"path",I.getID(t)),a=new u(e).toAngle(n,r,!0),h=new u(e).toAngle(s,r,!0),d=g.boundAngle(s)-g.boundAngle(n)>L.pi;o&&(d=!d);let f=o?"0":"1",w=`M ${a[0]} ${a[1]} A ${r} ${r} 0 ${d?"1":"0"} ${f} ${h[0]} ${h[1]}`;return R.setAttr(l,{d:w,class:`pts-svgform pts-arc ${t.currentClass}`}),I.style(l,t.style),l}arc(t,e,r,n,s){return this.nextID(),I.arc(this._ctx,t,e,r,n,s),this}static square(t,e,r){let n=U.svgElement(t.group,"rect",I.getID(t));return R.setAttr(n,{x:e[0]-r,y:e[1]-r,width:r*2,height:r*2,class:`pts-svgform pts-square ${t.currentClass}`}),I.style(n,t.style),n}square(t,e){return this.nextID(),I.square(this._ctx,t,e),this}static line(t,e){let r=I.pointsString(e);if(r.count<2)return;if(r.count>2)return I._poly(t,r.string,!1);let n=U.svgElement(t.group,"line",I.getID(t)),s=m.iterToArray(e);return R.setAttr(n,{x1:s[0][0],y1:s[0][1],x2:s[1][0],y2:s[1][1],class:`pts-svgform pts-line ${t.currentClass}`}),I.style(n,t.style),n}line(t){return this.nextID(),I.line(this._ctx,t),this}static _poly(t,e,r=!0){let n=U.svgElement(t.group,r?"polygon":"polyline",I.getID(t));return R.setAttr(n,{points:e,class:`pts-svgform pts-polygon ${t.currentClass}`}),I.style(n,t.style),n}static pointsString(t){let e="",r=0;for(let n of t)e+=`${n[0]},${n[1]} `,r++;return{string:e,count:r}}static polygon(t,e){let r=I.pointsString(e);return I._poly(t,r.string,!0)}polygon(t){return this.nextID(),I.polygon(this._ctx,t),this}static rect(t,e){if(!m.arrayCheck(e))return;let r=U.svgElement(t.group,"rect",I.getID(t)),n=c.fromArray(e).boundingBox(),s=k.size(n);return R.setAttr(r,{x:n[0][0],y:n[0][1],width:s[0],height:s[1],class:`pts-svgform pts-rect ${t.currentClass}`}),I.style(r,t.style),r}rect(t){return this.nextID(),I.rect(this._ctx,t),this}static text(t,e,r){let n=U.svgElement(t.group,"text",I.getID(t));return R.setAttr(n,{"pointer-events":"none",x:e[0],y:e[1],dx:0,dy:0,class:`pts-svgform pts-text ${t.currentClass}`}),n.textContent=r,I.style(n,t.style),n}text(t,e){return this.nextID(),I.text(this._ctx,t,e),this}log(t){return this.fill("#000").stroke("#fff",.5).text([10,14],t),this}},rt=I;rt.groupID=0,rt.domID=0;var Rt={};B(Rt,{Body:()=>ot,Particle:()=>_t,World:()=>it});var it=class{constructor(i,t=1,e=0){this._lastTime=null;this._gravity=new u;this._friction=1;this._damping=.75;this._iterations=1;this._particles=[];this._bodies=[];this._pnames=[];this._bnames=[];return this._bound=G.fromGroup(i),this._friction=t,this._gravity=typeof e=="number"?new u(0,e):new u(e),this}get bound(){return this._bound}set bound(i){this._bound=i}get gravity(){return this._gravity}set gravity(i){this._gravity=i}get friction(){return this._friction}set friction(i){this._friction=i}get damping(){return this._damping}set damping(i){this._damping=i}get iterations(){return this._iterations}set iterations(i){this._iterations=i}get bodyCount(){return this._bodies.length}get particleCount(){return this._particles.length}body(i){let t=i;if(typeof i=="string"&&i.length>0&&(t=this._bnames.indexOf(i)),t>=0)return this._bodies[t]}particle(i){let t=i;if(typeof i=="string"&&i.length>0&&(t=this._pnames.indexOf(i)),t>=0)return this._particles[t]}bodyIndex(i){return this._bnames.indexOf(i)}particleIndex(i){return this._pnames.indexOf(i)}update(i){let t=i/1e3;this._updateParticles(t),this._updateBodies(t)}drawParticles(i){this._drawParticles=i}drawBodies(i){this._drawBodies=i}add(i,t=""){return i instanceof ot?(this._bodies.push(i),this._bnames.push(t)):(this._particles.push(i),this._pnames.push(t)),this}_index(i,t){let e=0;if(typeof t=="string"){if(e=i(t),e<0)throw new Error(`Cannot find index of ${t}. You can use particleIndex() or bodyIndex() function to check existence by name.`)}else e=t;return e}removeBody(i,t=1){let e=this._index(this.bodyIndex.bind(this),i),r=e<0?[e*-1-1,t]:[e,t];return this._bodies.splice(r[0],r[1]),this._bnames.splice(r[0],r[1]),this}removeParticle(i,t=1){let e=this._index(this.particleIndex.bind(this),i),r=e<0?[e*-1-1,t]:[e,t];return this._particles.splice(r[0],r[1]),this._pnames.splice(r[0],r[1]),this}static edgeConstraint(i,t,e,r=1,n=!1){let s=1/(i.mass||1),o=1/(t.mass||1),l=s+o,a=t.$subtract(i),h=e*e,p=n?e/a.magnitude()-1:h/(a.dot(a)+h)-.5,d=a.$multiply(p*r);return i.subtract(d.$multiply(s/l)),t.add(d.$multiply(o/l)),i}static boundConstraint(i,t,e=.75){let r=g.boundingBox(t),n=i.$min(r[1].subtract(i.radius)).$max(r[0].add(i.radius));if(n[0]===r[0][0]||n[0]===r[1][0]){let s=i.changed.$multiply(e);i.previous=n.$subtract(new u(-s[0],s[1]))}else if(n[1]===r[0][1]||n[1]===r[1][1]){let s=i.changed.$multiply(e);i.previous=n.$subtract(new u(s[0],-s[1]))}i.to(n)}integrate(i,t,e){return i.addForce(this._gravity),i.verlet(t,this._friction,e),i}_updateParticles(i){for(let t=0,e=this._particles.length;t=this.length)throw new Error("index1 is not in the Group's indices");if(e<0||e>=this.length)throw new Error("index1 is not in the Group's indices");let n=this[t].$subtract(this[e]).magnitude();return this._cs.push([t,e,n,r||this._stiff]),this}linkAll(t){let e=this.length/2;for(let r=0,n=this.length;r=n-1?0:r+1;if(this.link(r,s,t),n>4){let o=Math.floor(e/2)+1,l=r>=n-o?r%n:r+o;this.link(r,l,t)}r<=e-1&&this.link(r,Math.min(this.length-1,r+Math.floor(e)))}}linksToLines(){let t=[];for(let e=0,r=this._cs.length;eMath.abs(l[0][1]-l[1][1])?o=(n.vertex[0]-s[0]-l[0][0])/(l[1][0]-l[0][0]):o=(n.vertex[1]-s[1]-l[0][1])/(l[1][1]-l[0][1]);let a=1/(o*o+(1-o)*(1-o)),h=n.vertex.body.mass||1,p=n.edge[0].body.mass||1,d=h/(h+p),f=p/(h+p);l[0].subtract(s.$multiply(d*(1-o)*a/2)),l[1].subtract(s.$multiply(d*o*a/2)),n.vertex.add(s.$multiply(f))}}processParticle(t){let e=this,r=t,n=C.hasIntersectCircle(e,q.fromCenter(t,t.radius));if(n){let s=n.normal.$multiply(n.dist),o,l=n.edge;Math.abs(l[0][0]-l[1][0])>Math.abs(l[0][1]-l[1][1])?o=(n.vertex[0]-s[0]-l[0][0])/(l[1][0]-l[0][0]):o=(n.vertex[1]-s[1]-l[0][1])/(l[1][1]-l[0][1]);let a=1/(o*o+(1-o)*(1-o)),h=n.vertex.mass||r.mass||1,p=n.edge[0].body.mass||1,d=h/(h+p),f=p/(h+p);l[0].subtract(s.$multiply(d*(1-o)*a/2)),l[1].subtract(s.$multiply(d*o*a/2));let w=t.changed.add(s.$multiply(f));t.previous=t.$subtract(w)}}};var Ot={};B(Ot,{Sound:()=>W,Tempo:()=>ht});var ht=class{constructor(i){this._listeners={};this._listenerInc=0;this.bpm=i}static fromBeat(i){return new ht(6e4/i)}get bpm(){return this._bpm}set bpm(i){this._bpm=i,this._ms=6e4/this._bpm}get ms(){return this._ms}set ms(i){this._bpm=Math.floor(6e4/i),this._ms=6e4/this._bpm}_createID(i){let t="";return typeof i=="function"?t="_b"+this._listenerInc++:t=i.name||"_b"+this._listenerInc++,t}every(i){let t=this,e=Array.isArray(i)?i[0]:i;return{start:function(r,n=0,s){let o=s||t._createID(r);return t._listeners[o]={name:o,beats:i,period:e,index:0,offset:n,duration:-1,continuous:!1,fn:r},this},progress:function(r,n=0,s){let o=s||t._createID(r);return t._listeners[o]={name:o,beats:i,period:e,index:0,offset:n,duration:-1,continuous:!0,fn:r},this}}}track(i){for(let t in this._listeners)if(this._listeners.hasOwnProperty(t)){let e=this._listeners[t],r=e.offset?i+e.offset:i,n=e.period*this._ms,s=!1;r>e.duration+n&&(e.duration=r-r%this._ms,Array.isArray(e.beats)&&(e.index=(e.index+1)%e.beats.length,e.period=e.beats[e.index]),s=!0);let o=Math.max(0,Math.ceil(Math.floor(e.duration/this._ms)/e.period)),l=e.continuous?[o,v.clamp((r-e.duration)/n,0,1),r,s]:[o];(e.continuous||s)&&e.fn.apply(e,l)&&delete this._listeners[e.name]}}stop(i){this._listeners[i]&&delete this._listeners[i]}animate(i,t){this.track(i)}resize(i,t){}action(i,t,e,r){}},W=class{constructor(i){this._playing=!1;this._type=i,this._createAudioContext()}_createAudioContext(){let i=window.AudioContext;if(!i)throw new Error("Your browser doesn't support Web Audio. (No AudioContext)");this._ctx=i?new i:void 0}static from(i,t,e="gen",r){let n=new W(e);return n._node=i,n._ctx=t,r&&(n._stream=r),n}static load(i,t="anonymous"){return new Promise((e,r)=>{let n=new W("file");n._source=typeof i=="string"?new Audio(i):i,n._source.autoplay=!1,n._source.crossOrigin=t,n._source.addEventListener("ended",function(){n._playing=!1}),n._source.addEventListener("error",function(){r("Error loading sound")}),n._source.addEventListener("canplaythrough",function(){n._node||(n._node=n._ctx.createMediaElementSource(n._source)),e(n)})})}static loadAsBuffer(i){return new Promise((t,e)=>{let r=new XMLHttpRequest;r.open("GET",i,!0),r.responseType="arraybuffer";let n=new W("file");r.onload=function(){n._ctx.decodeAudioData(r.response,function(s){n.createBuffer(s),t(n)},s=>e("Error decoding audio"))},r.send()})}createBuffer(i){return this._node=this._ctx.createBufferSource(),i!==void 0&&(this._buffer=i),this._node.buffer=this._buffer,this._node.onended=()=>{this._playing=!1},this}static generate(i,t){return new W("gen")._gen(i,t)}_gen(i,t){this._node=this._ctx.createOscillator();let e=this._node;return e.type=i,i==="custom"?e.setPeriodicWave(t):e.frequency.value=t,this}static input(i){return lt(this,null,function*(){try{let t=new W("input");if(!t)return;let e=i||{audio:!0,video:!1};return t._stream=yield navigator.mediaDevices.getUserMedia(e),t._node=t._ctx.createMediaStreamSource(t._stream),t}catch(t){return console.error("Cannot get audio from input device."),Promise.resolve(null)}})}get ctx(){return this._ctx}get node(){return this._node}get outputNode(){return this._outputNode}get stream(){return this._stream}get source(){return this._source}get buffer(){return this._buffer}set buffer(i){this._buffer=i}get type(){return this._type}get playing(){return this._playing}get progress(){let i=0,t=0;return this._buffer?(i=this._buffer.duration,t=this._timestamp?this._ctx.currentTime-this._timestamp:0):(i=this._source.duration,t=this._source.currentTime),t/i}get playable(){return this._type==="input"?this._node!==void 0:!!this._buffer||this._source.readyState===4}get binSize(){return this.analyzer.size}get sampleRate(){return this._ctx.sampleRate}get frequency(){return this._type==="gen"?this._node.frequency.value:0}set frequency(i){this._type==="gen"&&(this._node.frequency.value=i)}connect(i){return this._node.connect(i),this}setOutputNode(i){return this._outputNode=i,this}removeOutputNode(){return this._outputNode=null,this}analyze(i=256,t=-100,e=-30,r=.8){let n=this._ctx.createAnalyser();return n.fftSize=i*2,n.minDecibels=t,n.maxDecibels=e,n.smoothingTimeConstant=r,this.analyzer={node:n,size:n.frequencyBinCount,data:new Uint8Array(n.frequencyBinCount)},this._node.connect(this.analyzer.node),this}_domain(i){return this.analyzer?(i?this.analyzer.node.getByteTimeDomainData(this.analyzer.data):this.analyzer.node.getByteFrequencyData(this.analyzer.data),this.analyzer.data):new Uint8Array(0)}_domainTo(i,t,e=[0,0],r=[0,0]){let n=i?this.timeDomain():this.freqDomain(),s=new c;for(let o=r[0],l=n.length-r[1];o0&&(this._source.currentTime=i)):this._type==="gen"&&(this._gen(this._node.type,this._node.frequency.value),this._node.start(),this.analyzer&&this._node.connect(this.analyzer.node)),(this._outputNode||this._node).connect(this._ctx.destination),this._playing=!0,this}stop(){return this._playing&&(this._outputNode||this._node).disconnect(this._ctx.destination),this._type==="file"?this._buffer?this.progress<1&&this._node.stop():this._source.pause():this._type==="gen"?this._node.stop():this._type==="input"&&this._stream.getAudioTracks().forEach(i=>i.stop()),this._playing=!1,this}toggle(){return this._playing?this.stop():this.start(),this}};globalThis.Pts=z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z({},Tt),Gt),Dt),Pt),kt),wt),Lt),Mt),St),vt),zt),Bt),At),Rt),Ct),Ot),$t);globalThis.Pts.namespace=y=>{let i=globalThis.Pts;for(let t in i)t!="namespace"&&(y[t]=i[t])};globalThis.Pts.quickStart=(y,i="#9ab")=>{if(!window)return;let t=globalThis;return globalThis.Pts.namespace(t),t.space=new at(y).setup({bgcolor:i,resize:!0,retina:!0}),t.form=t.space.getForm(),function(e=null,r=null,n=null,s=null){t.space.add({start:r,animate:e,resize:s,action:n}),t.space.bindMouse().bindTouch().play()}};})(); +(()=>{var Ht=Object.defineProperty;var Ut=Object.getOwnPropertySymbols;var jt=Object.prototype.hasOwnProperty,Vt=Object.prototype.propertyIsEnumerable;var qt=(y,i,t)=>i in y?Ht(y,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):y[i]=t,z=(y,i)=>{for(var t in i||(i={}))jt.call(i,t)&&qt(y,t,i[t]);if(Ut)for(var t of Ut(i))Vt.call(i,t)&&qt(y,t,i[t]);return y};var B=(y,i)=>{for(var t in i)Ht(y,t,{get:i[t],enumerable:!0})};var lt=(y,i,t)=>new Promise((e,r)=>{var n=l=>{try{o(t.next(l))}catch(a){r(a)}},s=l=>{try{o(t.throw(l))}catch(a){r(a)}},o=l=>l.done?e(l.value):Promise.resolve(l.value).then(n,s);o((t=t.apply(y,i)).next())});var Tt={};B(Tt,{CanvasForm:()=>E,CanvasSpace:()=>at});var Mt={};B(Mt,{MultiTouchSpace:()=>tt,Space:()=>dt});var Lt={};B(Lt,{Bound:()=>G,Group:()=>c,Pt:()=>u});var vt={};B(vt,{Const:()=>L,Util:()=>m});var kt={};B(kt,{Geom:()=>g,Num:()=>v,Range:()=>xt,Shaping:()=>K});var wt={};B(wt,{Circle:()=>U,Curve:()=>A,Line:()=>D,Polygon:()=>M,Rectangle:()=>k,Triangle:()=>O});var Pt={};B(Pt,{Mat:()=>P,Vec:()=>x});var x=class{static add(i,t){if(typeof t=="number")for(let e=0,r=i.length;eMath.max(s,o.length),0):i[0].length;for(let s=0;sm.warn("Group's length is less than "+i,y),Wt=(y,i="")=>m.warn(`Index ${i} is out of bound in Group`,y),D=class{static fromAngle(i,t,e){let r=new c(new u(i),new u(i));return r[1].toAngle(t,e,!0),r}static slope(i,t){return t[0]-i[0]===0?void 0:(t[1]-i[1])/(t[0]-i[0])}static intercept(i,t){if(t[0]-i[0]!==0){let e=(t[1]-i[1])/(t[0]-i[0]),r=i[1]-e*i[0];return{slope:e,yi:r,xi:e===0?void 0:-r/e}}}static sideOfPt2D(i,t){let e=m.iterToArray(i);return(e[1][0]-e[0][0])*(t[1]-e[0][1])-(t[0]-e[0][0])*(e[1][1]-e[0][1])}static collinear(i,t,e,r=.01){let n=new u(0,0,0).to(i).$subtract(t),s=new u(0,0,0).to(i).$subtract(e);return n.$cross(s).divide(1e3).equals(new u(0,0,0),r)}static magnitude(i){let t=m.iterToArray(i);return t.length>=2?t[1].$subtract(t[0]).magnitude():0}static magnitudeSq(i){let t=m.iterToArray(i);return t.length>=2?t[1].$subtract(t[0]).magnitudeSq():0}static perpendicularFromPt(i,t,e=!1){let r=m.iterToArray(i);if(r[0].equals(r[1]))return;let n=r[0].$subtract(r[1]),s=r[1].$subtract(t),o=s.$subtract(n.$project(s));return e?o:o.$add(t)}static distanceFromPt(i,t){let e=m.iterToArray(i),r=D.perpendicularFromPt(e,t,!0);return r?r.magnitude():e[0].$subtract(t).magnitude()}static intersectRay2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n=D.intercept(e[0],e[1]),s=D.intercept(r[0],r[1]),o=e[0],l=r[0];if(n==null){if(s==null)return;let a=-s.slope*(l[0]-o[0])+l[1];return new u(o[0],a)}else if(s==null){let a=-n.slope*(o[0]-l[0])+o[1];return new u(l[0],a)}else if(s.slope!=n.slope){let a=(n.slope*o[0]-s.slope*l[0]+l[1]-o[1])/(n.slope-s.slope),h=n.slope*(a-o[0])+o[1];return new u(a,h)}else return n.yi==s.yi?new u(o[0],o[1]):void 0}static intersectLine2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n=D.intersectRay2D(e,r);return n&&g.withinBound(n,e[0],e[1])&&g.withinBound(n,r[0],r[1])?n:void 0}static intersectLineWithRay2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n=D.intersectRay2D(e,r);return n&&g.withinBound(n,e[0],e[1])?n:void 0}static intersectPolygon2D(i,t,e=!1){let r=m.iterToArray(i),n=m.iterToArray(t),s=e?D.intersectLineWithRay2D:D.intersectLine2D,o=new c;for(let l=0,a=n.length;l0?o:void 0}static intersectLines2D(i,t,e=!1){let r=new c,n=e?D.intersectLineWithRay2D:D.intersectLine2D;for(let s of i)for(let o of t){let l=n(s,o);l&&r.push(l)}return r}static intersectGridWithRay2D(i,t){let e=m.iterToArray(i),r=D.intercept(new u(e[0]).subtract(t),new u(e[1]).subtract(t)),n=new c;return r&&r.xi&&n.push(new u(t[0]+r.xi,t[1])),r&&r.yi&&n.push(new u(t[0],t[1]+r.yi)),n}static intersectGridWithLine2D(i,t){let e=m.iterToArray(i),r=D.intersectGridWithRay2D(e,t),n=new c;for(let s=0,o=r.length;sMath.abs(t[1]/t[0])?h=o[1]<0?0:2:h=o[0]<0?3:1,D.intersectRay2D(a[h],n)}}static marker(i,t,e="arrow",r=!0){let n=m.iterToArray(i),s=r?0:1,o=r?1:0,l=n[s].$subtract(n[o]);if(l.magnitudeSq()===0)return new c;l.unit();let a=g.perpendicular(l).multiply(t[0]).add(n[o]);return e=="arrow"?(a.add(l.$multiply(t[1])),new c(n[o],a[0],a[1])):new c(a[0],a[1])}static toRect(i){let t=m.iterToArray(i);return new c(t[0].$min(t[1]),t[0].$max(t[1]))}},k=class{static from(i,t,e){return k.fromTopLeft(i,t,e)}static fromTopLeft(i,t,e){let r=typeof t=="number"?[t,e||t]:t;return new c(new u(i),new u(i).add(r))}static fromCenter(i,t,e){let r=typeof t=="number"?[t/2,(e||t)/2]:new u(t).divide(2);return new c(new u(i).subtract(r),new u(i).add(r))}static toCircle(i,t=!0){return U.fromRect(i,t)}static toSquare(i,t=!1){let e=m.iterToArray(i),r=k.size(e),n=t?r.maxValue().value:r.minValue().value;return k.fromCenter(k.center(e),n,n)}static size(i){let t=m.iterToArray(i);return t[0].$max(t[1]).subtract(t[0].$min(t[1]))}static center(i){let t=m.iterToArray(i),e=t[0].$min(t[1]),r=t[0].$max(t[1]);return e.add(r.$subtract(e).divide(2))}static corners(i){let t=m.iterToArray(i),e=t[0].$min(t[1]),r=t[0].$max(t[1]);return new c(e,new u(r.x,e.y),r,new u(e.x,r.y))}static sides(i){let[t,e,r,n]=k.corners(i);return[new c(t,e),new c(e,r),new c(r,n),new c(n,t)]}static boundingBox(i){let t=m.iterToArray(i),e=m.flatten(t,!1),r=u.make(2,Number.MAX_VALUE),n=u.make(2,Number.MIN_VALUE);for(let s=0,o=e.length;s=2)break}return new c(r,n)}static polygon(i){return k.corners(i)}static quadrants(i,t){let e=m.iterToArray(i),r=k.corners(e),n=t!=null?new u(t):k.center(e);return r.map(s=>new c(s,n).boundingBox())}static halves(i,t=.5,e=!1){let r=m.iterToArray(i),n=r[0].$min(r[1]),s=r[0].$max(r[1]),o=e?v.lerp(n[1],s[1],t):v.lerp(n[0],s[0],t);return e?[new c(n,new u(s[0],o)),new c(new u(n[0],o),s)]:[new c(n,new u(o,s[1])),new c(new u(o,n[1]),s)]}static withinBound(i,t){let e=m.iterToArray(i);return g.withinBound(t,e[0],e[1])}static hasIntersectRect2D(i,t,e=!1){let r=m.iterToArray(i),n=m.iterToArray(t);return e&&(r=g.boundingBox(r),n=g.boundingBox(n)),!(r[0][0]>n[1][0]||n[0][0]>r[1][0]||r[0][1]>n[1][1]||n[0][1]>r[1][1])}static intersectRect2D(i,t){let e=m.iterToArray(i),r=m.iterToArray(t);return k.hasIntersectRect2D(e,r)?D.intersectLines2D(k.sides(e),k.sides(r)):new c}},U=class{static fromRect(i,t=!1){let e=m.iterToArray(i),r=0,n=r=k.size(e).minValue().value/2;if(t){let s=k.size(e).maxValue().value/2;r=Math.sqrt(n*n+s*s)}else r=n;return new c(k.center(e),new u(r,r))}static fromTriangle(i,t=!1){return t?O.circumcircle(i):O.incircle(i)}static fromCenter(i,t){return new c(new u(i),new u(t,t))}static withinBound(i,t,e=0){let r=m.iterToArray(i),n=r[0].$subtract(t);return n.dot(n)+e0)for(let o=0,l=n.length;ol+a)return new c;if(o0&&s.push(a)}return m.flatten(s)}static toRect(i,t=!1){let e=m.iterToArray(i),r=e[1][0];if(t){let n=Math.sqrt(r*r)/2;return new c(e[0].$subtract(n),e[0].$add(n))}else return new c(e[0].$subtract(r),e[0].$add(r))}static toTriangle(i,t=!0){let e=m.iterToArray(i);if(t){let r=-Math.PI/2,n=Math.PI*2/3,s=new c;for(let o=0;o<3;o++)s.push(e[0].clone().toAngle(r,e[1][0],!0)),r+=n;return s}else return O.fromCenter(e[0],e[1][0])}},O=class{static fromRect(i){let t=m.iterToArray(i),e=t[0].$add(t[1]).divide(2);e.y=t[0][1];let r=t[1].clone();return r.x=t[0][0],new c(e,t[1].clone(),r)}static fromCircle(i){return U.toTriangle(i,!0)}static fromCenter(i,t){return O.fromCircle(U.fromCenter(i,t))}static medial(i){let t=m.iterToArray(i);return t.length<3?Y(new c,3):M.midpoints(t,!0)}static oppositeSide(i,t){let e=m.iterToArray(i);return e.length<3?Y(new c,3):t===0?c.fromPtArray([e[1],e[2]]):t===1?c.fromPtArray([e[0],e[2]]):c.fromPtArray([e[0],e[1]])}static altitude(i,t){let e=m.iterToArray(i),r=O.oppositeSide(e,t);return r.length>1?new c(e[t],D.perpendicularFromPt(r,e[t])):new c}static orthocenter(i){let t=m.iterToArray(i);if(t.length<3)return Y(void 0,3);let e=O.altitude(t,0),r=O.altitude(t,1);return D.intersectRay2D(e,r)}static incenter(i){let t=m.iterToArray(i);if(t.length<3)return Y(void 0,3);let e=M.bisector(t,0).add(t[0]),r=M.bisector(t,1).add(t[1]);return D.intersectRay2D(new c(t[0],e),new c(t[1],r))}static incircle(i,t){let e=m.iterToArray(i),r=t||O.incenter(e),n=M.area(e),s=M.perimeter(e,!0),o=2*n/s.total;return U.fromCenter(r,o)}static circumcenter(i){let t=m.iterToArray(i),e=O.medial(t),r=[e[0],g.perpendicular(t[0].$subtract(e[0])).p1.$add(e[0])],n=[e[1],g.perpendicular(t[1].$subtract(e[1])).p1.$add(e[1])];return D.intersectRay2D(r,n)}static circumcircle(i,t){let e=m.iterToArray(i),r=t||O.circumcenter(e),n=e[0].$subtract(r).magnitude();return U.fromCenter(r,n)}},M=class{static centroid(i){return g.centroid(i)}static rectangle(i,t,e){return k.corners(k.fromCenter(i,t,e))}static fromCenter(i,t,e){let r=new c;for(let n=0;n=e.length)throw new Error("index out of the Polygon's range");return new c(e[t],t===e.length-1?e[0]:e[t+1])}static lines(i,t=!0){let e=m.iterToArray(i);if(e.length<2)return Y(new c,2);let r=m.split(e,2,1);return t&&r.push(new c(e[e.length-1],e[0])),r.map(n=>n)}static midpoints(i,t=!1,e=.5){return M.lines(i,t).map(s=>g.interpolate(s[0],s[1],e))}static adjacentSides(i,t,e=!1){let r=m.iterToArray(i);if(r.length<2)return Y(new c,2);if(t<0||t>=r.length)return Wt(new c,t);let n=[],s=t-1;e&&s<0&&(s=r.length-1),s>=0&&n.push(new c(r[t],r[s]));let o=t+1;return e&&o>r.length-1&&(o=0),o<=r.length-1&&n.push(new c(r[t],r[o])),n}static bisector(i,t){let e=M.adjacentSides(i,t,!0);if(e.length>=2){let r=e[0][1].$subtract(e[0][0]).unit(),n=e[1][1].$subtract(e[1][0]).unit();return r.add(n).divide(2)}else return}static perimeter(i,t=!1){let e=M.lines(i,t),r=0,n=u.make(e.length,0);for(let s=0,o=e.length;sn[0]*s[1]-n[1]*s[0],r=0;for(let n=0,s=t.length;na[0]-h[0]));let r=(a,h,p)=>(h[0]-a[0])*(p[1]-a[1])-(p[0]-a[0])*(h[1]-a[1])>0,n=[],s=e.length-2,o=s+3;n[s]=e[2],n[o]=e[2],r(e[0],e[1],e[2])?(n[s+1]=e[0],n[s+2]=e[1]):(n[s+1]=e[1],n[s+2]=e[0]);for(let a=3,h=e.length;at[1]!=o[1][1]>t[1]&&t[0]<(o[1][0]-o[0][0])*(t[1]-o[0][1])/(o[1][1]-o[0][1])+o[0][0]&&(r=!r)}return r}static hasIntersectCircle(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n={which:-1,dist:0,normal:null,edge:null,vertex:null},s=r[0],o=r[1][0],l=Number.MAX_SAFE_INTEGER;for(let h=0,p=e.length;h0)return null;Math.abs(_)0)&&(n.edge=d,n.normal=f,l=Math.abs(_),n.which=h)}return n.edge?(s.$subtract(M.centroid(e)).dot(n.normal)<0&&n.normal.multiply(-1),n.dist=l,n.vertex=s,n):null}static hasIntersectPolygon(i,t){let e=m.iterToArray(i),r=m.iterToArray(t),n={which:-1,dist:0,normal:new u,edge:new c,vertex:new u},s=Number.MAX_SAFE_INTEGER;for(let f=0,w=e.length+r.length;f0)return null;Math.abs(S)r.length-1)return new c;let n=o=>on+s.x*t[o],0),r=i.reduce((n,s,o)=>n+s.y*t[o],0);if(i[0].length>2){let n=i.reduce((s,o,l)=>s+o.z*t[l],0);return new u(e,r,n)}return new u(e,r)}static catmullRom(i,t=10){let e=m.iterToArray(i);if(e.length<2)return new c;let r=new c,n=A.getSteps(t),s=A.controlPoints(e,0,!0);for(let l=0;l<=t;l++)r.push(A.catmullRomStep(n[l],s));let o=0;for(;o0){for(let a=0;a<=t;a++)r.push(A.catmullRomStep(n[a],l));o++}}return r}static catmullRomStep(i,t){let e=new c(new u(-.5,1,-.5,0),new u(1.5,-2.5,0,1),new u(-1.5,2,.5,0),new u(.5,-.5,0,0));return A._calcPt(t,P.multiply([i],e,!0)[0])}static cardinal(i,t=10,e=.5){let r=m.iterToArray(i);if(r.length<2)return new c;let n=new c,s=A.getSteps(t),o=A.controlPoints(r,0,!0);for(let a=0;a<=t;a++)n.push(A.cardinalStep(s[a],o,e));let l=0;for(;l0){for(let h=0;h<=t;h++)n.push(A.cardinalStep(s[h],a,e));l++}}return n}static cardinalStep(i,t,e=.5){let r=new c(new u(-1,2,-1,0),new u(-1,1,0,0),new u(1,-2,1,0),new u(1,-1,0,0)),n=P.multiply([i],r,!0)[0].multiply(e),s=2*i[0]-3*i[1]+1,o=-2*i[0]+3*i[1],l=A._calcPt(t,n);return l.x+=s*t[1].x+o*t[2].x,l.y+=s*t[1].y+o*t[2].y,l.length>2&&(l.z+=s*t[1].z+o*t[2].z),l}static bezier(i,t=10){let e=m.iterToArray(i);if(e.length<4)return new c;let r=new c,n=A.getSteps(t),s=0;for(;s0){for(let l=0;l<=t;l++)r.push(A.bezierStep(n[l],o));s+=3}}return r}static bezierStep(i,t){let e=new c(new u(-1,3,-3,1),new u(3,-6,3,0),new u(-3,3,0,0),new u(1,0,0,0));return A._calcPt(t,P.multiply([i],e,!0)[0])}static bspline(i,t=10,e=1){let r=m.iterToArray(i);if(r.length<2)return new c;let n=new c,s=A.getSteps(t),o=0;for(;o0){if(e!==1)for(let a=0;a<=t;a++)n.push(A.bsplineTensionStep(s[a],l,e));else for(let a=0;a<=t;a++)n.push(A.bsplineStep(s[a],l));o++}}return n}static bsplineStep(i,t){let e=new c(new u(-.16666666666666666,.5,-.5,.16666666666666666),new u(.5,-1,0,.6666666666666666),new u(-.5,.5,.5,.16666666666666666),new u(.16666666666666666,0,0,0));return A._calcPt(t,P.multiply([i],e,!0)[0])}static bsplineTensionStep(i,t,e=1){let r=new c(new u(-.16666666666666666,.5,-.5,.16666666666666666),new u(-1.5,2,0,-.3333333333333333),new u(1.5,-2.5,.5,.16666666666666666),new u(.16666666666666666,0,0,0)),n=P.multiply([i],r,!0)[0].multiply(e),s=2*i[0]-3*i[1]+1,o=-2*i[0]+3*i[1],l=A._calcPt(t,n);return l.x+=s*t[1].x+o*t[2].x,l.y+=s*t[1].y+o*t[2].y,l.length>2&&(l.z+=s*t[1].z+o*t[2].z),l}};function Xt(){var y=4022871197,i=function(t){if(t){t=t.toString();for(var e=0;e>>0,r-=y,r*=y,y=r>>>0,r-=y,y+=r*4294967296}return(y>>>0)*23283064365386963e-26}else y=4022871197};return i}function Ft(y){var i=48,t=1,e=i,r=new Array(i),n,s,o=0,l=Xt();for(n=0;n=i&&(e=0);var d=1768863*r[e]+t*23283064365386963e-26;return r[e]=d-(t=d|0)}}}var v=class{static equals(i,t,e=1e-5){return Math.abs(i-t)e?n-=r:n=Math.min(t,e)&&i<=Math.max(t,e)}static randomRange(i,t=0){let e=i>t?i-t:t-i;return i+v.random()*e}static randomPt(i,t){let e=new u(i.length),r=t?x.subtract(t.slice(),i):i,n=t?i:new u(i.length).fill(0);for(let s=0,o=e.length;s.5?2-i*2:i*2)}static mapToRange(i,t,e,r,n){if(t==e)throw new Error("[currMin, currMax] must define a range that is not zero");let s=Math.min(r,n),o=Math.max(r,n);return v.normalizeValue(i,t,e)*(o-s)+s}static seed(i){this.generator=Ft(i)}static random(){return this.generator?this.generator.random():Math.random()}},g=class{static boundAngle(i){return v.boundValue(i,0,360)}static boundRadian(i){return v.boundValue(i,0,L.two_pi)}static toRadian(i){return i*L.deg_to_rad}static toDegree(i){return i*L.rad_to_deg}static boundingBox(i){let t,e;for(let r of i)t==null?(t=r.clone(),e=r.clone()):(t=t.$min(r),e=e.$max(r));return new c(t,e)}static centroid(i){return v.average(i)}static anchor(i,t=0,e="to"){let r=e=="to"?"subtract":"add",n=0;for(let s of i)typeof t=="number"?t!==n&&s[r](i[t]):s[r](t),n++}static interpolate(i,t,e=.5){let r=Math.min(i.length,t.length),n=u.make(r);for(let s=0;s{if(s.length<2||o.length<2)throw new Error("Pt dimension cannot be less than 2");let l=s.$subtract(r),a=o.$subtract(r);if(l[0]>=0&&a[0]<0)return 1;if(l[0]<0&&a[0]>=0)return-1;if(l[0]==0&&a[0]==0)return l[1]>=0||a[1]>=0?l[1]>a[1]?1:-1:a[1]>l[1]?1:-1;let h=l.$cross2D(a);return h<0?1:h>0?-1:l[0]*l[0]+l[1]*l[1]>a[0]*a[0]+a[1]*a[1]?1:-1};return t.sort(n)}static scale(i,t,e){let r=m.iterToArray(i[0]!==void 0&&typeof i[0]=="number"?[i]:i),n=typeof t=="number"?u.make(r[0].length,t):t;e||(e=u.make(r[0].length,0));for(let s=0,o=r.length;si[Math.floor(g.boundAngle(g.toDegree(e)))]}}static sinTable(){let i=new Float64Array(360);for(let e=0;e<360;e++)i[e]=Math.sin(e*Math.PI/180);return{table:i,sin:e=>i[Math.floor(g.boundAngle(g.toDegree(e)))]}}},K=class{static linear(i,t=1){return t*i}static quadraticIn(i,t=1){return t*i*i}static quadraticOut(i,t=1){return-t*i*(i-2)}static quadraticInOut(i,t=1){let e=i*2;return i<.5?t/2*i*i*4:-t/2*((e-1)*(e-3)-1)}static cubicIn(i,t=1){return t*i*i*i}static cubicOut(i,t=1){let e=i-1;return t*(e*e*e+1)}static cubicInOut(i,t=1){let e=i*2;return i<.5?t/2*e*e*e:t/2*((e-2)*(e-2)*(e-2)+2)}static exponentialIn(i,t=1,e=.25){return t*Math.pow(i,1/e)}static exponentialOut(i,t=1,e=.25){return t*Math.pow(i,e)}static sineIn(i,t=1){return-t*Math.cos(i*L.half_pi)+t}static sineOut(i,t=1){return t*Math.sin(i*L.half_pi)}static sineInOut(i,t=1){return-t/2*(Math.cos(Math.PI*i)-1)}static cosineApprox(i,t=1){let e=i*i,r=e*e,n=r*e;return t*(4*n/9-17*r/9+22*e/9)}static circularIn(i,t=1){return-t*(Math.sqrt(1-i*i)-1)}static circularOut(i,t=1){let e=i-1;return t*Math.sqrt(1-e*e)}static circularInOut(i,t=1){let e=i*2;return i<.5?-t/2*(Math.sqrt(1-e*e)-1):t/2*(Math.sqrt(1-(e-2)*(e-2))+1)}static elasticIn(i,t=1,e=.7){let r=i-1,n=e/L.two_pi*1.5707963267948966;return t*(-Math.pow(2,10*r)*Math.sin((r-n)*L.two_pi/e))}static elasticOut(i,t=1,e=.7){let r=e/L.two_pi*1.5707963267948966;return t*(Math.pow(2,-10*i)*Math.sin((i-r)*L.two_pi/e))+t}static elasticInOut(i,t=1,e=.6){let r=i*2,n=e/L.two_pi*1.5707963267948966;return i<.5?(r-=1,t*(-.5*(Math.pow(2,10*r)*Math.sin((r-n)*L.two_pi/e)))):(r-=1,t*(.5*(Math.pow(2,-10*r)*Math.sin((r-n)*L.two_pi/e)))+t)}static bounceIn(i,t=1){return t-K.bounceOut(1-i,t)}static bounceOut(i,t=1){return i<1/2.75?t*(7.5625*i*i):i<2/2.75?(i-=1.5/2.75,t*(7.5625*i*i+.75)):i<2.5/2.75?(i-=2.25/2.75,t*(7.5625*i*i+.9375)):(i-=2.625/2.75,t*(7.5625*i*i+.984375))}static bounceInOut(i,t=1){return i<.5?K.bounceIn(i*2,t)/2:K.bounceOut(i*2-1,t)/2+t/2}static sigmoid(i,t=1,e=10){let r=e*(i-.5);return t/(1+Math.exp(-r))}static logSigmoid(i,t=1,e=.7){e=Math.max(L.epsilon,Math.min(1-L.epsilon,e)),e=1/(1-e);let r=1/(1+Math.exp((i-.5)*e*-2)),n=1/(1+Math.exp(e)),s=1/(1+Math.exp(-e));return t*(r-n)/(s-n)}static seat(i,t=1,e=.5){return i<.5?t*Math.pow(2*i,1-e)/2:t*(1-Math.pow(2*(1-i),1-e)/2)}static quadraticBezier(i,t=1,e=[.05,.95]){let r=typeof e!="number"?e[0]:e,n=typeof e!="number"?e[1]:.5,s=1-2*r;s===0&&(s=L.epsilon);let o=(Math.sqrt(r*r+s*i)-r)/s;return t*((1-2*n)*(o*o)+2*n*o)}static cubicBezier(i,t=1,e=[.1,.7],r=[.9,.2]){let n=new c(new u(0,0),new u(e),new u(r),new u(1,1));return t*A.bezierStep(new u(i*i*i,i*i,i,1),A.controlPoints(n)).y}static quadraticTarget(i,t=1,e=[.2,.35]){let r=Math.min(1-L.epsilon,Math.max(L.epsilon,e[0])),n=Math.min(1,Math.max(0,e[1])),s=(1-n)/(1-r)-n/r,o=(s*(r*r)-n)/r,l=s*(i*i)-o*i;return t*Math.min(1,Math.max(0,l))}static cliff(i,t=1,e=.5){return i>e?t:0}static step(i,t,e,r,...n){let s=1/t,o=Math.floor(e/s)*s;return i(o,r,...n)}},xt=class{constructor(i){this._dims=0;this._source=c.fromPtArray(i),this.calc()}get max(){return this._max.clone()}get min(){return this._min.clone()}get magnitude(){return this._mag.clone()}calc(){if(!this._source)return;let i=this._source[0].length;this._dims=i;let t=new u(i),e=new u(i),r=new u(i);for(let n=0;n=n.length||!(r[s]in n));s++)t.push(n[r[s]])}else e&&(t=[].slice.call(i[0]));return t}static warn(i="error",t=void 0){if(Z.warnLevel()=="error")throw new Error(i);return Z.warnLevel()=="warn"&&console.warn(i),t}static randomInt(i,t=0){return Z.warn("Util.randomInt is deprecated. Please use `Num.randomRange`"),Math.floor(v.random()*i)+t}static split(i,t,e,r=!1,n=!0){let s=[],o=[],l=e||t,a=0;if(i.length<=0||l<=0)return[];for(;a=i.length)break;o.push(i[a+h])}a+=l,(!n||n&&o.length===t)&&s.push(o)}return s}static flatten(i,t=!0){let e=t?new c:new Array;return e.concat.apply(e,i)}static combine(i,t,e){let r=[];for(let n=0,s=i.length;n=i&&(n=t+(n-i)),r&&r(n),n}}static forRange(i,t,e=0,r=1){let n=[];for(let s=e,o=t;s=200&&e.status<400?t(e.responseText,!0):t(`Server error (${e.status}) when loading "${i}"`,!1)},e.onerror=function(){t("Unknown network error",!1)},e.send()}static download(i,t="pts_canvas_image",e="png",r=1){let n=e==="jpg"?"jpeg":e;i.element.toBlob(function(s){let o=document.createElement("a"),l=URL.createObjectURL(s);o.href=l,o.download=`${t}.${e}`,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(l)},`image/${n}`,r)}static performance(i=10){let t=Date.now(),e=[];return function(){let r=Date.now();return e.push(r-t),e.length>=i&&e.shift(),t=r,Math.floor(e.reduce((n,s)=>n+s,0)/e.length)}}static arrayCheck(i,t=2){return Array.isArray(i)&&i.length0?m.getArgs(t):[0,0];super(e)}static make(t,e=0,r=!1){let n=new Float32Array(t);if(e&&n.fill(e),r)for(let s=0,o=n.length;se)return!1;return!0}to(...t){let e=m.getArgs(t);for(let r=0,n=Math.min(this.length,e.length);rt(e,...r)}ops(t){let e=[];for(let r=0,n=t.length;rt(e,...r)}ops(t){let e=[];for(let r=0,n=t.length;re?n[t]-r[t]:r[t]-n[t])}forEachPt(t,...e){if(!this[0][t])return m.warn(`${t} is not a function of Pt`),this;for(let r=0,n=this.length;rt+e.toString()+" ","")+" ]"}},G=class extends c{constructor(...t){super(...t);this._center=new u;this._size=new u;this._topLeft=new u;this._bottomRight=new u;this._inited=!1;this.init()}static fromBoundingRect(t){let e=new G(new u(t.left||0,t.top||0),new u(t.right||0,t.bottom||0));return t.width&&t.height&&(e.size=new u(t.width,t.height)),e}static fromGroup(t){let e=m.iterToArray(t);if(e.length<2)throw new Error("Cannot create a Bound from a group that has less than 2 Pt");return new G(e[0],e[e.length-1])}init(){if(this.p1&&(this._size=this.p1.clone(),this._inited=!0),this.p1&&this.p2){let t=this.p1,e=this.p2;this.topLeft=t.$min(e),this._bottomRight=t.$max(e),this._updateSize(),this._inited=!0}}clone(){return new G(this._topLeft.clone(),this._bottomRight.clone())}_updateSize(){this._size=this._bottomRight.$subtract(this._topLeft).abs(),this._updateCenter()}_updateCenter(){this._center=this._size.$multiply(.5).add(this._topLeft)}_updatePosFromTop(){this._bottomRight=this._topLeft.$add(this._size),this._updateCenter()}_updatePosFromBottom(){this._topLeft=this._bottomRight.$subtract(this._size),this._updateCenter()}_updatePosFromCenter(){let t=this._size.$multiply(.5);this._topLeft=this._center.$subtract(t),this._bottomRight=this._center.$add(t)}get size(){return new u(this._size)}set size(t){this._size=new u(t),this._updatePosFromTop()}get center(){return new u(this._center)}set center(t){this._center=new u(t),this._updatePosFromCenter()}get topLeft(){return new u(this._topLeft)}set topLeft(t){this._topLeft=new u(t),this[0]=this._topLeft,this._updateSize()}get bottomRight(){return new u(this._bottomRight)}set bottomRight(t){this._bottomRight=new u(t),this[1]=this._bottomRight,this._updateSize()}get width(){return this._size.length>0?this._size.x:0}set width(t){this._size.x=t,this._updatePosFromTop()}get height(){return this._size.length>1?this._size.y:0}set height(t){this._size.y=t,this._updatePosFromTop()}get depth(){return this._size.length>2?this._size.z:0}set depth(t){this._size.z=t,this._updatePosFromTop()}get x(){return this.topLeft.x}get y(){return this.topLeft.y}get z(){return this.topLeft.z}get inited(){return this._inited}update(){return this._topLeft=this[0],this._bottomRight=this[1],this._updateSize(),this}};var Ct={};B(Ct,{UI:()=>j,UIButton:()=>mt,UIDragger:()=>It,UIPointerActions:()=>C,UIShape:()=>J});var J={rectangle:"rectangle",circle:"circle",polygon:"polygon",polyline:"polyline",line:"line"},C={up:"up",down:"down",move:"move",drag:"drag",uidrag:"uidrag",drop:"drop",uidrop:"uidrop",over:"over",out:"out",enter:"enter",leave:"leave",click:"click",keydown:"keydown",keyup:"keyup",pointerdown:"pointerdown",pointerup:"pointerup",contextmenu:"contextmenu",all:"all"},Q=class{constructor(i,t,e={},r){this._holds=new Map;this._group=c.fromArray(i),this._shape=t,this._id=r===void 0?`ui_${Q._counter++}`:r,this._states=e,this._actions={}}static fromRectangle(i,t,e){return new this(i,J.rectangle,t,e)}static fromCircle(i,t,e){return new this(i,J.circle,t,e)}static fromPolygon(i,t,e){return new this(i,J.polygon,t,e)}static fromUI(i,t,e){return new this(i.group,i.shape,t||i._states,e)}get id(){return this._id}set id(i){this._id=i}get group(){return this._group}set group(i){this._group=i}get shape(){return this._shape}set shape(i){this._shape=i}state(i,t){return i?t!==void 0?(this._states[i]=t,this):this._states[i]:null}on(i,t){return this._actions[i]||(this._actions[i]=[]),Q._addHandler(this._actions[i],t)}off(i,t){return this._actions[i]?t===void 0?(delete this._actions[i],!0):Q._removeHandler(this._actions[i],t):!1}listen(i,t,e){if(this._actions[i]!==void 0){if(this._within(t)||Array.from(this._holds.values()).indexOf(i)>=0)return Q._trigger(this._actions[i],this,t,i,e),!0;if(this._actions.all)return Q._trigger(this._actions.all,this,t,i,e),!0}return!1}hold(i){let t=Math.max(0,...Array.from(this._holds.keys()))+1;return this._holds.set(t,i),t}unhold(i){i!==void 0?this._holds.delete(i):this._holds.clear()}static track(i,t,e,r){for(let n=0,s=i.length;n=0&&ti.length}else return!1}},j=Q;j._counter=0;var mt=class extends j{constructor(t,e,r={},n){super(t,e,r,n);this._hoverID=-1;r.hover===void 0&&(this._states.hover=!1),r.clicks===void 0&&(this._states.clicks=0);let s=C;this.on(s.up,(o,l,a,h)=>{this.state("clicks",this._states.clicks+1)}),this.on(s.move,(o,l,a,h)=>{if(this._within(l)&&!this._states.hover){this.state("hover",!0),j._trigger(this._actions[s.enter],this,l,s.enter,h);var d=this.hold(s.move);this._hoverID=this.on(s.move,(f,w)=>{!this._within(w)&&!this.state("dragging")&&(this.state("hover",!1),j._trigger(this._actions[s.leave],this,l,s.leave,h),this.off(s.move,this._hoverID),this.unhold(d))})}})}onClick(t){return this.on(C.up,t)}offClick(t){return this.off(C.up,t)}onContextMenu(t){return this.on(C.contextmenu,t)}offContextMenu(t){return this.off(C.contextmenu,t)}onHover(t,e){var r=[void 0,void 0];return t&&(r[0]=this.on(C.enter,t)),e&&(r[1]=this.on(C.leave,e)),r}offHover(t,e){var r=[!1,!1];return(t===void 0||t>=0)&&(r[0]=this.off(C.enter,t)),(e===void 0||e>=0)&&(r[1]=this.off(C.leave,e)),r}},It=class extends mt{constructor(t,e,r={},n){super(t,e,r,n);this._draggingID=-1;this._moveHoldID=-1;this._dropHoldID=-1;this._upHoldID=-1;r.dragging===void 0&&(this._states.dragging=!1),r.moved===void 0&&(this._states.moved=!1),r.offset===void 0&&(this._states.offset=new u);let s=C;this.on(s.down,(l,a,h,p)=>{this._moveHoldID===-1&&(this.state("dragging",!0),this.state("offset",new u(a).subtract(l.group[0])),this._moveHoldID=this.hold(s.move)),this._dropHoldID===-1&&(this._dropHoldID=this.hold(s.drop)),this._upHoldID===-1&&(this._upHoldID=this.hold(s.up)),this._draggingID===-1&&(this._draggingID=this.on(s.move,(d,f)=>{this.state("dragging")&&(j._trigger(this._actions[s.uidrag],d,f,s.uidrag,p),this.state("moved",!0))}))});let o=(l,a,h,p)=>{this.state("dragging",!1),this.off(s.move,this._draggingID),this._draggingID=-1,this.unhold(this._moveHoldID),this._moveHoldID=-1,this.unhold(this._dropHoldID),this._dropHoldID=-1,this.unhold(this._upHoldID),this._upHoldID=-1,this.state("moved")&&(j._trigger(this._actions[s.uidrop],l,a,s.uidrop,p),this.state("moved",!1))};this.on(s.drop,o),this.on(s.up,o),this.on(s.out,o)}onDrag(t){return this.on(C.uidrag,t)}offDrag(t){return this.off(C.uidrag,t)}onDrop(t){return this.on(C.uidrop,t)}offDrop(t){return this.off(C.uidrop,t)}};var dt=class{constructor(){this.id="space";this.bound=new G;this._time={prev:0,diff:0,end:-1,min:0};this.players={};this.playerCount=0;this._animID=-1;this._pause=!1;this._refresh=void 0;this._pointer=new u;this._isReady=!1;this._playing=!1}refresh(i){return this._refresh=i,this}minFrameTime(i=0){this._time.min=i}add(i){let t=typeof i=="function"?{animate:i}:i,e=this.playerCount++,r=t.animateID||this.id+e;return this.players[r]=t,t.animateID=r,t.resize&&this.bound.inited&&t.resize(this.bound),this._refresh===void 0&&(this._refresh=!0),this}remove(i){return delete this.players[i.animateID],this}removeAll(){return this.players={},this}play(i=0){if(!(i===0&&this._animID!==-1)){if(this._animID=requestAnimationFrame(this.play.bind(this)),this._pause)return this;if(this._time.diff=i-this._time.prev,this._time.diff=0&&i>this._time.end&&(cancelAnimationFrame(this._animID),this._animID=-1,this._playing=!1)}pause(i=!1){return this._pause=i?!this._pause:!0,this}resume(){return this._pause=!1,this}stop(i=0){return this._time.end=i,this}playOnce(i=0){return this.play(),this.stop(i),this}render(i){return this._renderFunc&&this._renderFunc(i,this),this}set customRendering(i){this._renderFunc=i}get customRendering(){return this._renderFunc}get isPlaying(){return this._playing}get outerBound(){return this.bound.clone()}get innerBound(){return new G(u.make(this.size.length,0),this.size.clone())}get size(){return this.bound.size.clone()}get center(){return this.size.divide(2)}get width(){return this.bound.width}get height(){return this.bound.height}},tt=class extends dt{constructor(){super(...arguments);this._pressed=!1;this._dragged=!1;this._hasMouse=!1;this._hasTouch=!1;this._hasKeyboard=!1}get pointer(){let t=this._pointer.clone();return t.id=this._pointer.id,t}bindCanvas(t,e,r={},n){(n||this._canvas).addEventListener(t,e,r)}unbindCanvas(t,e,r={},n){(n||this._canvas).removeEventListener(t,e,r)}bindDoc(t,e,r={}){document&&document.addEventListener(t,e,r)}unbindDoc(t,e,r={}){document&&document.removeEventListener(t,e,r)}bindMouse(t=!0,e){return t?(this._mouseDown=this._mouseDown.bind(this),this._mouseUp=this._mouseUp.bind(this),this._mouseOver=this._mouseOver.bind(this),this._mouseOut=this._mouseOut.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseClick=this._mouseClick.bind(this),this._pointerDown=this._pointerDown.bind(this),this._pointerUp=this._pointerUp.bind(this),this._contextMenu=this._contextMenu.bind(this),this.bindCanvas("mousedown",this._mouseDown,{},e),this.bindCanvas("pointerdown",this._pointerDown,{},e),this.bindCanvas("mouseup",this._mouseUp,{},e),this.bindCanvas("pointerup",this._pointerUp,{},e),this.bindCanvas("mouseover",this._mouseOver,{},e),this.bindCanvas("mouseout",this._mouseOut,{},e),this.bindCanvas("mousemove",this._mouseMove,{},e),this.bindCanvas("click",this._mouseClick,{},e),this.bindCanvas("contextmenu",this._contextMenu,{},e),this._hasMouse=!0):(this.unbindCanvas("mousedown",this._mouseDown,{},e),this.unbindCanvas("pointerdown",this._pointerDown,{},e),this.unbindCanvas("mouseup",this._mouseUp,{},e),this.unbindCanvas("pointerup",this._pointerUp,{},e),this.unbindCanvas("mouseover",this._mouseOver,{},e),this.unbindCanvas("mouseout",this._mouseOut,{},e),this.unbindCanvas("mousemove",this._mouseMove,{},e),this.unbindCanvas("click",this._mouseClick,{},e),this.unbindCanvas("contextmenu",this._contextMenu,{},e),this._hasMouse=!1),this}bindTouch(t=!0,e=!1,r){return t?(this.bindCanvas("touchstart",this._touchStart.bind(this),{passive:e},r),this.bindCanvas("touchend",this._mouseUp.bind(this),{},r),this.bindCanvas("touchmove",this._touchMove.bind(this),{passive:e},r),this.bindCanvas("touchcancel",this._mouseOut.bind(this),{},r),this._hasTouch=!0):(this.unbindCanvas("touchstart",this._touchStart.bind(this),{passive:e},r),this.unbindCanvas("touchend",this._mouseUp.bind(this),{},r),this.unbindCanvas("touchmove",this._touchMove.bind(this),{passive:e},r),this.unbindCanvas("touchcancel",this._mouseOut.bind(this),{},r),this._hasTouch=!1),this}bindKeyboard(t=!0){return t?(this._keyDownBind=this._keyDown.bind(this),this._keyUpBind=this._keyUp.bind(this),this.bindDoc("keydown",this._keyDownBind,{}),this.bindDoc("keyup",this._keyUpBind,{}),this._hasKeyboard=!0):(this.unbindDoc("keydown",this._keyDownBind,{}),this.unbindDoc("keyup",this._keyUpBind,{}),this._hasKeyboard=!1),this}touchesToPoints(t,e="touches"){if(!t||!t[e])return[];let r=[];for(var n=0;n0,a=e.changedTouches.item(0);r=l?a.pageX-this.outerBound.x:0,n=l?a.pageY-this.outerBound.y:0,o.action&&o.action(t,r,n,e)}t&&(this._pointer.to(r,n),this._pointer.id=t)}_mouseDown(t){return this._mouseAction(C.down,t),this._pressed=!0,!1}_pointerDown(t){return this._mouseAction(C.pointerdown,t),t.target instanceof Element&&t.target.setPointerCapture(t.pointerId),!1}_mouseUp(t){return this._dragged?this._mouseAction(C.drop,t):this._mouseAction(C.up,t),this._pressed=!1,this._dragged=!1,!1}_pointerUp(t){return this._mouseAction(C.pointerup,t),t.target instanceof Element&&(t.target.releasePointerCapture(t.pointerId),this._dragged&&this._mouseAction(C.drop,t),this._dragged=!1),!1}_mouseMove(t){return this._mouseAction(C.move,t),this._pressed&&(this._dragged=!0,this._mouseAction(C.drag,t)),!1}_mouseOver(t){return this._mouseAction(C.over,t),!1}_mouseOut(t){return this._mouseAction(C.out,t),this._dragged&&this._mouseAction(C.drop,t),this._dragged=!1,!1}_mouseClick(t){return this._mouseAction(C.click,t),this._pressed=!1,this._dragged=!1,!1}_contextMenu(t){return this._mouseAction(C.contextmenu,t),!1}_touchMove(t){return this._mouseMove(t),t.preventDefault(),!1}_touchStart(t){return this._mouseDown(t),t.preventDefault(),!1}_keyDown(t){return this._keyboardAction(C.keydown,t),!1}_keyUp(t){return this._keyboardAction(C.keyup,t),!1}_keyboardAction(t,e){if(this.isPlaying){for(let r in this.players)if(this.players.hasOwnProperty(r)){let n=this.players[r];n.action&&n.action(t,e.shiftKey?1:0,e.altKey?1:0,e)}}}};var Dt={};B(Dt,{Font:()=>N,Form:()=>pt,VisualForm:()=>V});var pt=class{constructor(){this._ready=!1}get ready(){return this._ready}},V=class extends pt{constructor(){super(...arguments);this._filled=!0;this._stroked=!0;this._font=new N(14,"sans-serif")}get filled(){return this._filled}set filled(t){this._filled=t}get stroked(){return this._stroked}set stroked(t){this._stroked=t}get currentFont(){return this._font}_multiple(t,e,...r){if(!t)return this;for(let n=0,s=t.length;nnt});var nt=class{static textWidthEstimator(i,t=["M","n","."],e=[.06,.8,.14]){let r=t.map(i),n=new u(e).dot(r);return s=>s.length*n}static truncate(i,t,e,r=""){let n=Math.floor(t.length*Math.min(1,e/i(t)));return n0?Math.max(n,e):n}}};var $t={};B($t,{Img:()=>q});var q=class{constructor(i=!1,t,e){this._scale=1;this._loaded=!1;this._editable=i,this._space=t,this._scale=this._space?this._space.pixelScale:1,this._img=new Image,e&&(this._img.crossOrigin="Anonymous")}static load(i,t=!1,e,r){let n=new q(t,e);return n.load(i).then(s=>{r&&r(s)}),n}static loadAsync(i,t=!1,e){return lt(this,null,function*(){return yield new q(t,e).load(i)})}static loadPattern(i,t,e="repeat",r=!1){return lt(this,null,function*(){return(yield q.loadAsync(i,r,t)).pattern(e)})}static blank(i,t,e){let r=new q(!0,t),n=e||t.pixelScale;return r.initCanvas(i[0],i[1],n),r}load(i){return new Promise((t,e)=>{this._editable&&!document&&e("Cannot create html canvas element. document not found."),this._img.src=i,this._img.onload=()=>{this._editable&&(this._cv||(this._cv=document.createElement("canvas")),this._drawToScale(this._scale,this._img),this._data=this._ctx.getImageData(0,0,this._cv.width,this._cv.height)),this._loaded=!0,t(this)},this._img.onerror=r=>{e(r)}})}_drawToScale(i,t){let e=t.width,r=t.height;this.initCanvas(e,r,i),t&&this._ctx.drawImage(t,0,0,e,r,0,0,this._cv.width,this._cv.height)}initCanvas(i,t,e=1){if(!this._editable){console.error("Cannot initiate canvas because this Img is not set to be editable");return}this._cv||(this._cv=document.createElement("canvas"));let r=typeof e=="number"?[e,e]:e;this._cv.width=i*r[0],this._cv.height=t*r[1],this._ctx=this._cv.getContext("2d"),this._loaded=!0}bitmap(i){let t=i?i[0]:this._cv.width,e=i?i[1]:this._cv.height;return createImageBitmap(this._cv,0,0,t,e)}pattern(i="repeat",t=!1){if(!this._space)throw"Cannot find CanvasSpace ctx to create image pattern";return this._space.ctx.createPattern(t?this._cv:this._img,i)}sync(){this._scale!==1?this.bitmap().then(i=>{this._drawToScale(1/this._scale,i),this.load(this.toBase64())}):this._img.src=this.toBase64()}pixel(i,t=!0){let e=typeof t=="number"?t:t?this._scale:1;return q.getPixel(this._data,[i[0]*e,i[1]*e])}static getPixel(i,t){let e=new u(0,0,0,0);if(t[0]>=i.width||t[1]>=i.height)return e;let r=Math.floor(t[1])*(i.width*4)+Math.floor(t[0])*4,n=i.data;return r>=n.length-4?e:new u(n[r],n[r+1],n[r+2],n[r+3])}resize(i,t=!1){let e=t?i:[i[0]/this._img.naturalWidth,i[1]/this._img.naturalHeight];return this._drawToScale(e,this._img),this._data=this._ctx.getImageData(0,0,this._cv.width,this._cv.height),this}crop(i){let t=i.topLeft.scale(this._scale),e=i.size.scale(this._scale);return this._ctx.getImageData(t.x,t.y,e.x,e.y)}filter(i){return this._ctx.filter=i,this._ctx.drawImage(this._cv,0,0),this._ctx.filter="none",this}cleanup(){this._cv&&this._cv.remove(),this._img&&this._img.remove(),this._data=null}static fromBlob(i,t=!1,e){let r=URL.createObjectURL(i);return new q(t,e).load(r)}static imageDataToBlob(i){return new Promise(function(t,e){document||e("Cannot create html canvas element. document not found.");let r=document.createElement("canvas");r.width=i.width,r.height=i.height,r.getContext("2d").putImageData(i,0,0),r.toBlob(n=>{t(n),r.remove()})})}toBase64(){return this._cv.toDataURL()}toBlob(){return new Promise(i=>{this._cv.toBlob(t=>i(t))})}getForm(){return this._editable||console.error("Cannot get a CanvasForm because this Img is not editable"),this._ctx?new E(this._ctx):void 0}get current(){return this._editable?this._cv:this._img}get image(){return this._img}get canvas(){return this._cv}get data(){return this._data}get ctx(){return this._ctx}get loaded(){return this._loaded}get pixelScale(){return this._scale}get imageSize(){return!this._img.width||!this._img.height?this.canvasSize.$divide(this._scale):new u(this._img.width,this._img.height)}get canvasSize(){return new u(this._cv.width,this._cv.height)}get scaledMatrix(){let i=1/this._scale;return new P().scale2D([i,i])}};var at=class extends tt{constructor(t,e){super();this._pixelScale=1;this._autoResize=!0;this._bgcolor="#e1e9f0";this._offscreen=!1;this._initialResize=!1;var r=null,n=!1;if(this.id="pt",t instanceof Element)r=t,this.id="pts_existing_space";else{let s=t;s=t[0]==="#"||t[0]==="."?t:"#"+t,r=document.querySelector(s),n=!0,this.id=s.substr(1)}r?r.nodeName.toLowerCase()!="canvas"?(this._container=r,this._canvas=this._createElement("canvas",this.id+"_canvas"),this._container.appendChild(this._canvas),this._initialResize=!0):(this._canvas=r,this._container=r.parentElement,this._autoResize=!1):(this._container=this._createElement("div",this.id+"_container"),this._canvas=this._createElement("canvas",this.id),this._container.appendChild(this._canvas),document.body.appendChild(this._container),n=!1),setTimeout(this._ready.bind(this,e),100),this._ctx=this._canvas.getContext("2d")}_createElement(t="div",e){let r=document.createElement(t);return r.setAttribute("id",e),r}_ready(t){if(!this._container)throw new Error(`Cannot initiate #${this.id} element`);this._isReady=!0,this._resizeHandler(null),this.clear(this._bgcolor),this._canvas.dispatchEvent(new Event("ready"));for(let e in this.players)this.players.hasOwnProperty(e)&&this.players[e].start&&this.players[e].start(this.bound.clone(),this);this._pointer=this.center,this._initialResize=!1,t&&t(this.bound,this._canvas)}setup(t){if(this._bgcolor=t.bgcolor?t.bgcolor:"transparent",this.autoResize=t.resize!=null?t.resize:!1,t.retina!==!1){let e=window&&window.devicePixelRatio||1,r=this._ctx.webkitBackingStorePixelRatio||this._ctx.mozBackingStorePixelRatio||this._ctx.msBackingStorePixelRatio||this._ctx.oBackingStorePixelRatio||this._ctx.backingStorePixelRatio||1;this._pixelScale=Math.max(1,e/r)}return t.offscreen?(this._offscreen=!0,this._offCanvas=this._createElement("canvas",this.id+"_offscreen"),this._offCtx=this._offCanvas.getContext("2d")):this._offscreen=!1,t.pixelDensity&&(this._pixelScale=t.pixelDensity),this}set autoResize(t){window&&(this._autoResize=t,t?window.addEventListener("resize",this._resizeHandler.bind(this)):window.removeEventListener("resize",this._resizeHandler.bind(this)))}get autoResize(){return this._autoResize}resize(t,e){this.bound=t,this._canvas.width=Math.ceil(this.bound.size.x)*this._pixelScale,this._canvas.height=Math.ceil(this.bound.size.y)*this._pixelScale,this._canvas.style.width=Math.ceil(this.bound.size.x)+"px",this._canvas.style.height=Math.ceil(this.bound.size.y)+"px",this._offscreen&&(this._offCanvas.width=Math.ceil(this.bound.size.x)*this._pixelScale,this._offCanvas.height=Math.ceil(this.bound.size.y)*this._pixelScale),this._pixelScale!=1&&(this._ctx.scale(this._pixelScale,this._pixelScale),this._offscreen&&this._offCtx.scale(this._pixelScale,this._pixelScale));for(let r in this.players)if(this.players.hasOwnProperty(r)){let n=this.players[r];n.resize&&n.resize(this.bound,e)}return this.render(this._ctx),e&&!this.isPlaying&&this.playOnce(0),this}_resizeHandler(t){if(!window)return;let e=this._autoResize||this._initialResize?this._container.getBoundingClientRect():this._canvas.getBoundingClientRect();if(e){let r=G.fromBoundingRect(e);r.center=r.center.add(window.pageXOffset,window.pageYOffset),this.resize(r,t)}}set background(t){this._bgcolor=t}get background(){return this._bgcolor}get pixelScale(){return this._pixelScale}get hasOffscreen(){return this._offscreen}get offscreenCtx(){return this._offCtx}get offscreenCanvas(){return this._offCanvas}getForm(){return new E(this)}get element(){return this._canvas}get parent(){return this._container}get ready(){return this._isReady}get ctx(){return this._ctx}clear(t){t&&(this._bgcolor=t);let e=this._ctx.fillStyle,r=Math.ceil(this.pixelScale);return!this._bgcolor||this._bgcolor==="transparent"?this._ctx.clearRect(-r,-r,this._canvas.width+r,this._canvas.height+r):((this._bgcolor.indexOf("rgba")===0||this._bgcolor.length===9&&this._bgcolor.indexOf("#")===0)&&this._ctx.clearRect(-r,-r,this._canvas.width+r,this._canvas.height+r),this._ctx.fillStyle=this._bgcolor,this._ctx.fillRect(-r,-r,this._canvas.width+r,this._canvas.height+r)),this._ctx.fillStyle=e,this}clearOffscreen(t){if(this._offscreen){let e=Math.ceil(this.pixelScale);t?(this._offCtx.fillStyle=t,this._offCtx.fillRect(-e,-e,this._canvas.width+e,this._canvas.height+e)):this._offCtx.clearRect(-e,-e,this._offCanvas.width+e,this._offCanvas.height+e)}return this}playItems(t){this._isReady&&(this._ctx.save(),this._offscreen&&this._offCtx.save(),super.playItems(t),this._ctx.restore(),this._offscreen&&this._offCtx.restore(),this.render(this._ctx))}dispose(){if(window)return window.removeEventListener("resize",this._resizeHandler.bind(this)),this.stop(),this.removeAll(),this}recorder(t,e="webm",r=15e6){let n=this._canvas.captureStream(),s=new MediaRecorder(n,{mimeType:`video/${e}`,bitsPerSecond:r});return s.ondataavailable=function(o){let l=URL.createObjectURL(new Blob([o.data],{type:`video/${e}`}));if(typeof t=="function")t(l);else if(t){let a=document.createElement("a");a.href=l,a.download=`canvas_video.${e}`,a.click(),a.remove()}},s}},E=class extends V{constructor(t){super();this._style={fillStyle:"#f03",strokeStyle:"#fff",lineWidth:1,lineJoin:"bevel",lineCap:"butt",globalAlpha:1};if(!t)return this;let e=r=>{this._ctx=r,this._ctx.fillStyle=this._style.fillStyle,this._ctx.strokeStyle=this._style.strokeStyle,this._ctx.lineJoin="bevel",this._ctx.font=this._font.value,this._ready=!0};t instanceof CanvasRenderingContext2D?e(t):(this._space=t,this._space.add({start:()=>{e(this._space.ctx)}}))}get space(){return this._space}get ctx(){return this._ctx}useOffscreen(t=!0,e=!1){return e&&this._space.clearOffscreen(typeof e=="string"?e:null),this._ctx=this._space.hasOffscreen&&t?this._space.offscreenCtx:this._space.ctx,this}renderOffscreen(t=[0,0]){this._space.hasOffscreen&&this._space.ctx.drawImage(this._space.offscreenCanvas,t[0],t[1],this._space.width,this._space.height)}alpha(t){return this._ctx.globalAlpha=t,this._style.globalAlpha=t,this}fill(t){return typeof t=="boolean"?this.filled=t:(this.filled=!0,this._style.fillStyle=t,this._ctx.fillStyle=t),this}fillOnly(t){return this.stroke(!1),this.fill(t)}stroke(t,e,r,n){return typeof t=="boolean"?this.stroked=t:(this.stroked=!0,this._style.strokeStyle=t,this._ctx.strokeStyle=t,e&&(this._ctx.lineWidth=e,this._style.lineWidth=e),r&&(this._ctx.lineJoin=r,this._style.lineJoin=r),n&&(this._ctx.lineCap=n,this._style.lineCap=n)),this}strokeOnly(t,e,r,n){return this.fill(!1),this.stroke(t,e,r,n)}applyFillStroke(t=!0,e=!0,r=1){return t&&(typeof t=="string"&&this.fill(t),this._ctx.fill()),e&&(typeof e=="string"&&this.stroke(e,r),this._ctx.stroke()),this}gradient(t){let e=[];t.length<2&&t.push([.99,"#000"],[1,"#000"]);for(let r=0,n=t.length;r{let s=n?this._ctx.createRadialGradient(r[0][0],r[0][1],Math.abs(r[1][0]),n[0][0],n[0][1],Math.abs(n[1][0])):this._ctx.createLinearGradient(r[0][0],r[0][1],r[1][0],r[1][1]);for(let o=0,l=e.length;othis._ctx.measureText(e).width):void 0,this}getTextWidth(t){return this._estimateTextWidth?this._estimateTextWidth(t):this._ctx.measureText(t+" .").width}_textTruncate(t,e,r=""){return nt.truncate(this.getTextWidth.bind(this),t,e,r)}_textAlign(t,e,r,n){let s=m.iterToArray(t);if(m.arrayCheck(s)){n||(n=k.center(s));var o=s[0][0];this._ctx.textAlign=="end"||this._ctx.textAlign=="right"?o=s[1][0]:(this._ctx.textAlign=="center"||this._ctx.textAlign=="middle")&&(o=n[0]);var l=n[1];return e=="top"||e=="start"?l=s[0][1]:(e=="end"||e=="bottom")&&(l=s[1][1]),r?new u(o+r[0],l+r[1]):new u(o,l)}}reset(){for(let t in this._style)this._style.hasOwnProperty(t)&&(this._ctx[t]=this._style[t]);return this._font=new N,this._ctx.font=this._font.value,this}_paint(){this._filled&&this._ctx.fill(),this._stroked&&this._ctx.stroke()}static point(t,e,r=5,n="square"){if(e){if(!E[n])throw new Error(`${n} is not a static function of CanvasForm`);E[n](t,e,r)}}point(t,e=5,r="square"){return E.point(this._ctx,t,e,r),this._paint(),this}static circle(t,e,r=10){e&&(t.beginPath(),t.arc(e[0],e[1],r,0,L.two_pi,!1),t.closePath())}circle(t){let e=m.iterToArray(t);return E.circle(this._ctx,e[0],e[1][0]),this._paint(),this}static ellipse(t,e,r,n=0,s=0,o=L.two_pi,l=!1){!e||!r||(t.beginPath(),t.ellipse(e[0],e[1],r[0],r[1],n,s,o,l))}ellipse(t,e,r=0,n=0,s=L.two_pi,o=!1){return E.ellipse(this._ctx,t,e,r,n,s,o),this._paint(),this}static arc(t,e,r,n,s,o){e&&(t.beginPath(),t.arc(e[0],e[1],r,n,s,o))}arc(t,e,r,n,s){return E.arc(this._ctx,t,e,r,n,s),this._paint(),this}static square(t,e,r){if(!e)return;let n=e[0]-r,s=e[1]-r,o=e[0]+r,l=e[1]+r;t.beginPath(),t.moveTo(n,s),t.lineTo(n,l),t.lineTo(o,l),t.lineTo(o,s),t.closePath()}square(t,e){return E.square(this._ctx,t,e),this._paint(),this}static line(t,e){if(!m.arrayCheck(e))return;let r=0;t.beginPath();for(let n of e)n&&(r++>0?t.lineTo(n[0],n[1]):t.moveTo(n[0],n[1]))}line(t){return E.line(this._ctx,t),this._paint(),this}static polygon(t,e){m.arrayCheck(e)&&(E.line(t,e),t.closePath())}polygon(t){return E.polygon(this._ctx,t),this._paint(),this}static rect(t,e){let r=m.iterToArray(e);m.arrayCheck(r)&&(t.beginPath(),t.moveTo(r[0][0],r[0][1]),t.lineTo(r[0][0],r[1][1]),t.lineTo(r[1][0],r[1][1]),t.lineTo(r[1][0],r[0][1]),t.closePath())}rect(t){return E.rect(this._ctx,t),this._paint(),this}static image(t,e,r,n){let s=m.iterToArray(e),o;if(typeof s[0]=="number")o=s;else if(n){let l=m.iterToArray(n);o=[l[0][0],l[0][1],l[1][0]-l[0][0],l[1][1]-l[0][1],s[0][0],s[0][1],s[1][0]-s[0][0],s[1][1]-s[0][1]]}else o=[s[0][0],s[0][1],s[1][0]-s[0][0],s[1][1]-s[0][1]];r instanceof q?r.loaded&&t.drawImage(r.image,...o):t.drawImage(r,...o)}image(t,e,r){return e instanceof q?e.loaded&&E.image(this._ctx,t,e.image,r):E.image(this._ctx,t,e,r),this}static imageData(t,e,r){let n=m.iterToArray(e);typeof n[0]=="number"?t.putImageData(r,n[0],n[1]):t.putImageData(r,n[0][0],n[0][1],n[0][0],n[0][1],n[1][0],n[1][1])}imageData(t,e){return E.imageData(this._ctx,t,e),this}static text(t,e,r,n){e&&t.fillText(r,e[0],e[1],n)}text(t,e,r){return E.text(this._ctx,t,e,r),this}textBox(t,e,r="middle",n="",s=!0){s&&(this._ctx.textBaseline=r);let o=k.size(t),l=this._textTruncate(e,o[0],n);return this.text(this._textAlign(t,r),l[0]),this}paragraphBox(t,e,r=1.2,n="top",s=!0){let o=m.iterToArray(t),l=k.size(o);this._ctx.textBaseline="top";let a=this._font.size*r,h=(_,T=[],S=0)=>{if(!_||s&&S*a>l[1]-a*2)return T;if(S>1e4)throw new Error("max recursion reached (10000)");let X=this._textTruncate(_,l[0],""),yt=X[0].indexOf(` +`);if(yt>=0)return T.push(X[0].substr(0,yt)),h(_.substr(yt+1),T,S+1);let ct=X[0].lastIndexOf(" ")+1;(ct<=0||X[1]===_.length)&&(ct=void 0);let Nt=X[0].substr(0,ct);return T.push(Nt),X[1]<=0||X[1]===_.length?T:h(_.substr(ct||X[1]),T,S+1)},p=h(e),d=p.length*a,f=o;if(n=="middle"||n=="center"){let _=(l[1]-d)/2;s&&(_=Math.max(0,_)),f=new c(o[0].$add(0,_),o[1].$subtract(0,_))}else n=="bottom"?f=new c(o[0].$add(0,l[1]-d),o[1]):f=new c(o[0],o[0].$add(l[0],d));let w=k.center(f);for(let _=0,T=p.length;_Et,Delaunay:()=>st,Noise:()=>gt});var Et=class{static distributeRandom(i,t,e=2){let r=new c;for(let n=0;n1&&s.push(i.y+v.random()*i.height),e>2&&s.push(i.z+v.random()*i.depth),r.push(new u(s))}return r}static distributeLinear(i,t){let e=m.iterToArray(i),r=D.subpoints(e,t-2);return r.unshift(e[0]),r.push(e[e.length-1]),r}static gridPts(i,t,e,r=[.5,.5]){if(t===0||e===0)throw new Error("grid columns and rows cannot be 0");let n=i.size.$subtract(1).$divide(t,e),s=n.$multiply(r),o=new c;for(let l=0;l0?Math.floor(l/r):l,d=n&&n>0?l%n:l;h.initNoise(t*d,e*p),h.seed(s),o.push(h),l++}return o}static delaunay(i){return st.from(i)}},ft=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],bt=[151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,9,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180],gt=class extends u{constructor(...t){super(...t);this.perm=[];this._n=new u(.01,.01);this.perm=bt.concat(bt)}initNoise(...t){return this._n=new u(...t),this}step(t=0,e=0){return this._n.add(t,e),this}seed(t){t>0&&t<1&&(t*=65536),t=Math.floor(t),t<256&&(t|=t<<8);for(let e=0;e<255;e++){let r=e&1?bt[e]^t&255:bt[e]^t>>8&255;this.perm[e]=this.perm[e+256]=r}return this}noise2D(){let t=Math.max(0,Math.floor(this._n[0]))%255,e=Math.max(0,Math.floor(this._n[1]))%255,r=this._n[0]%255-t,n=this._n[1]%255-e,s=x.dot(ft[(t+this.perm[e])%12],[r,n,0]),o=x.dot(ft[(t+this.perm[e+1])%12],[r,n-1,0]),l=x.dot(ft[(t+1+this.perm[e])%12],[r-1,n,0]),a=x.dot(ft[(t+1+this.perm[e+1])%12],[r-1,n-1,0]),h=d=>d*d*d*(d*(d*6-15)+10),p=h(r);return v.lerp(v.lerp(s,l,p),v.lerp(o,a,p),h(n))}},st=class extends c{constructor(){super(...arguments);this._mesh=[]}delaunay(t=!0){if(this.length<3)return[];this._mesh=[];let e=this.length,r=[];for(let h=0;hthis[p][0]-this[h][0]);let n=this.slice(),s=this._superTriangle();n=n.concat(s);let o=[this._circum(e,e+1,e+2,s)],l=[],a=[];for(let h=0,p=r.length;h0&&S[0]*S[0]>T*T){l.push(_),a.push(_.triangle),o.splice(w,1);continue}S[0]*S[0]+S[1]*S[1]-T*T>L.epsilon||(f.push(_.i,_.j,_.j,_.k,_.k,_.i),o.splice(w,1))}for(st._dedupe(f),w=f.length;w>1;)o.push(this._circum(f[--w],f[--w],d,!1,n))}for(let h=0,p=o.length;h1;){let r=t[--e],n=t[--e],s=e;for(;s>1;){let o=t[--s],l=t[--s];if(n==l&&r==o||n==o&&r==l){t.splice(e,2),t.splice(s,2);break}}}return t}};var St={};B(St,{Color:()=>ut});var b=class extends u{constructor(...t){super(...t);this._mode="rgb";this._isNorm=!1}static from(...t){let e=[1,1,1,1],r=m.getArgs(t);for(let n=0,s=e.length;nt[s]||"F";t=`${n(0)}${n(0)}${n(1)}${n(1)}${n(2)}${n(2)}`}let e=1;t.length===8&&(e=t.substr(6)&&255/255,t=t.substring(0,6));let r=parseInt(t,16);return new b(r>>16,r>>8&255,r&255,e)}static rgb(...t){return b.from(...t).toMode("rgb")}static hsl(...t){return b.from(...t).toMode("hsl")}static hsb(...t){return b.from(...t).toMode("hsb")}static lab(...t){return b.from(...t).toMode("lab")}static lch(...t){return b.from(...t).toMode("lch")}static luv(...t){return b.from(...t).toMode("luv")}static xyz(...t){return b.from(...t).toMode("xyz")}static maxValues(t){return b.ranges[t].zipSlice(1).$take([0,1,2])}get hex(){return this.toString("hex")}get rgb(){return this.toString("rgb")}get rgba(){return this.toString("rgba")}clone(){let t=new b(this);return t.toMode(this._mode),t}toMode(t,e=!1){if(e){let r=this._mode.toUpperCase()+"to"+t.toUpperCase();if(b[r])this.to(b[r](this,this._isNorm,this._isNorm));else throw new Error("Cannot convert color with "+r)}return this._mode=t,this}get mode(){return this._mode}get r(){return this[0]}set r(t){this[0]=t}get g(){return this[1]}set g(t){this[1]=t}get b(){return this[2]}set b(t){this[2]=t}get h(){return this._mode=="lch"?this[2]:this[0]}set h(t){let e=this._mode=="lch"?2:0;this[e]=t}get s(){return this[1]}set s(t){this[1]=t}get l(){return this._mode=="hsl"?this[2]:this[0]}set l(t){let e=this._mode=="hsl"?2:0;this[e]=t}get a(){return this[1]}set a(t){this[1]=t}get c(){return this[1]}set c(t){this[1]=t}get u(){return this[1]}set u(t){this[1]=t}get v(){return this[2]}set v(t){this[2]=t}set alpha(t){this.length>3&&(this[3]=t)}get alpha(){return this.length>3?this[3]:1}get normalized(){return this._isNorm}set normalized(t){this._isNorm=t}normalize(t=!0){if(this._isNorm==t)return this;let e=b.ranges[this._mode];for(let r=0;r<3;r++)this[r]=t?v.mapToRange(this[r],e[r][0],e[r][1],0,1):v.mapToRange(this[r],0,1,e[r][0],e[r][1]);return this._isNorm=t,this}$normalize(t=!0){return this.clone().normalize(t)}toString(t="mode"){if(t=="hex"){let e=r=>{let n=Math.floor(r).toString(16);return n.length<2?"0"+n:n};return`#${e(this[0])}${e(this[1])}${e(this[2])}`}else return t=="rgba"?`rgba(${Math.floor(this[0])},${Math.floor(this[1])},${Math.floor(this[2])},${this.alpha})`:t=="rgb"?`rgb(${Math.floor(this[0])},${Math.floor(this[1])},${Math.floor(this[2])})`:`${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`}static RGBtoHSL(t,e=!1,r=!1){let[n,s,o]=e?t:t.$normalize(),l=Math.max(n,s,o),a=Math.min(n,s,o),h=(l+a)/2,p=h,d=h;if(l==a)h=0,p=0;else{let f=l-a;p=d>.5?f/(2-l-a):f/(l+a),h=0,l===n?h=(s-o)/f+(s(d=d<0?d+1:d>1?d-1:d,d*6<1?a+(l-a)*d*6:d*2<1?l:d*3<2?a+(l-a)*(2/3-d)*6:a),p=r?1:255;return b.rgb(p*h(n+1/3),p*h(n),p*h(n-1/3),t.alpha)}static RGBtoHSB(t,e=!1,r=!1){let[n,s,o]=e?t:t.$normalize(),l=Math.max(n,s,o),a=Math.min(n,s,o),h=l-a,p=0,d=l===0?0:h/l,f=l;return l!=a&&(l===n?p=(s-o)/h+(s.04045?Math.pow((n[o]+.055)/1.055,2.4):n[o]/12.92,r||(n[o]=n[o]*100);let s=b.xyz(n[0]*.4124564+n[1]*.3575761+n[2]*.1804375,n[0]*.2126729+n[1]*.7151522+n[2]*.072175,n[0]*.0193339+n[1]*.119192+n[2]*.9503041,t.alpha);return r?s.normalize():s}static XYZtoRGB(t,e=!1,r=!1){let[n,s,o]=e?t:t.$normalize(),l=[n*3.2406254773200533+s*-1.5372079722103187+o*-.4986285986982479,n*-.9689307147293197+s*1.8757560608852415+o*.041517523842953964,n*.055710120445510616+s*-.2040210505984867+o*1.0569959422543882];for(let h=0;h<3;h++)l[h]=l[h]>.0031308?1.055*Math.pow(l[h],1/2.4)-.055:12.92*l[h],l[h]=Math.max(0,Math.min(1,l[h])),r||(l[h]=Math.round(l[h]*255));let a=b.rgb(l[0],l[1],l[2],t.alpha);return r?a.normalize():a}static XYZtoLAB(t,e=!1,r=!1){let n=e?t.$normalize(!1):t.clone(),s=.00885645167,o=903.296296296;n.divide(b.D65);let l=p=>p>s?Math.pow(p,1/3):(o*p+16)/116,a=l(n[1]),h=b.lab(116*a-16,500*(l(n[0])-a),200*(a-l(n[2])),t.alpha);return r?h.normalize():h}static LABtoXYZ(t,e=!1,r=!1){let n=e?t.$normalize(!1):t,s=(n[0]+16)/116,o=n[1]/500+s,l=s-n[2]/200,a=.00885645167,h=903.296296296,p=b.D65,d=Math.pow(o,3),f=Math.pow(l,3),w=b.xyz(p[0]*(d>a?d:(116*o-16)/h),p[1]*(n[0]>h*a?Math.pow((n[0]+16)/116,3):n[0]/h),p[2]*(f>a?f:(116*l-16)/h),t.alpha);return r?w.normalize():w}static XYZtoLUV(t,e=!1,r=!1){let[n,s,o]=e?t.$normalize(!1):t,l=4*n/(n+15*s+3*o),a=9*s/(n+15*s+3*o);s=s/100,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116;let h=4*b.D65[0]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]),p=9*b.D65[1]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]),d=116*s-16;return b.luv(d,13*d*(l-h),13*d*(a-p),t.alpha)}static LUVtoXYZ(t,e=!1,r=!1){let[n,s,o]=e?t.$normalize(!1):t,l=(n+16)/116,a=l*l*l;l=a>.008856?a:(l-16/116)/7.787;let h=4*b.D65[0]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]),p=9*b.D65[1]/(b.D65[0]+15*b.D65[1]+3*b.D65[2]);s=s/(13*n)+h,o=o/(13*n)+p,l=l*100;let d=-1*(9*l*s)/((s-4)*o-s*o),f=(9*l-15*o*l-o*d)/(3*o);return b.xyz(d,l,f,t.alpha)}static LABtoLCH(t,e=!1,r=!1){let n=e?t.$normalize(!1):t,s=g.toDegree(g.boundRadian(Math.atan2(n[2],n[1])));return b.lch(n[0],Math.sqrt(n[1]*n[1]+n[2]*n[2]),s,t.alpha)}static LCHtoLAB(t,e=!1,r=!1){let n=e?t.$normalize(!1):t,s=g.toRadian(n[2]);return b.lab(n[0],Math.cos(s)*n[1],Math.sin(s)*n[1],t.alpha)}},ut=b;ut.D65=new u(95.047,100,108.883,1),ut.ranges={rgb:new c(new u(0,255),new u(0,255),new u(0,255)),hsl:new c(new u(0,360),new u(0,1),new u(0,1)),hsb:new c(new u(0,360),new u(0,1),new u(0,1)),lab:new c(new u(0,100),new u(-128,127),new u(-128,127)),lch:new c(new u(0,100),new u(0,100),new u(0,360)),luv:new c(new u(0,100),new u(-134,220),new u(-140,122)),xyz:new c(new u(0,100),new u(0,100),new u(0,100))};var zt={};B(zt,{DOMSpace:()=>R,HTMLForm:()=>et,HTMLSpace:()=>F});var R=class extends tt{constructor(t,e){super();this.id="domspace";this._autoResize=!0;this._bgcolor="#e1e9f0";this._css={};var r=null,n=!1;this.id="pts",t instanceof Element?(r=t,this.id="pts_existing_space"):(r=document.querySelector(t),n=!0,this.id=t.substr(1)),r?(this._canvas=r,this._container=r.parentElement):(this._container=R.createElement("div","pts_container"),this._canvas=R.createElement("div","pts_element"),this._container.appendChild(this._canvas),document.body.appendChild(this._container),n=!1),setTimeout(this._ready.bind(this,e),50)}static createElement(t="div",e,r){let n=document.createElement(t);return e&&n.setAttribute("id",e),r&&r.appendChild&&r.appendChild(n),n}_ready(t){if(!this._container)throw new Error(`Cannot initiate #${this.id} element`);this._isReady=!0,this._resizeHandler(null),this.clear(this._bgcolor),this._canvas.dispatchEvent(new Event("ready"));for(let e in this.players)this.players.hasOwnProperty(e)&&this.players[e].start&&this.players[e].start(this.bound.clone(),this);this._pointer=this.center,this.refresh(!1),t&&t(this.bound,this._canvas)}setup(t){return t.bgcolor&&(this._bgcolor=t.bgcolor),this.autoResize=t.resize!=null?t.resize:!1,this}getForm(){return null}set autoResize(t){this._autoResize=t,t?window.addEventListener("resize",this._resizeHandler.bind(this)):(delete this._css.width,delete this._css.height,window.removeEventListener("resize",this._resizeHandler.bind(this)))}get autoResize(){return this._autoResize}resize(t,e){this.bound=t,this.styles({width:`${t.width}px`,height:`${t.height}px`},!0);for(let r in this.players)if(this.players.hasOwnProperty(r)){let n=this.players[r];n.resize&&n.resize(this.bound,e)}return this}_resizeHandler(t){let e=G.fromBoundingRect(this._container.getBoundingClientRect());this._autoResize?this.styles({width:"100%",height:"100%"},!0):this.styles({width:`${e.width}px`,height:`${e.height}px`},!0),this.resize(e,t)}get element(){return this._canvas}get parent(){return this._container}get ready(){return this._isReady}clear(t){return t&&(this.background=t),this._canvas.innerHTML="",this}set background(t){this._bgcolor=t,this._container.style.backgroundColor=this._bgcolor}get background(){return this._bgcolor}style(t,e,r=!1){return this._css[t]=e,r&&(this._canvas.style[t]=e),this}styles(t,e=!1){for(let r in t)t.hasOwnProperty(r)&&this.style(r,t[r],e);return this}static setAttr(t,e){for(let r in e)e.hasOwnProperty(r)&&t.setAttribute(r,e[r]);return t}static getInlineStyles(t){let e="";for(let r in t)t.hasOwnProperty(r)&&t[r]&&(e+=`${r}: ${t[r]}; `);return e}dispose(){return window.removeEventListener("resize",this._resizeHandler.bind(this)),this.stop(),this.removeAll(),this}},F=class extends R{getForm(){return new et(this)}static htmlElement(i,t,e,r=!0){if(!i||!i.appendChild)throw new Error("parent is not a valid DOM element");let n=document.querySelector(`#${e}`);return n||(n=document.createElement(t),n.setAttribute("id",e),r&&n.setAttribute("class",e.substring(0,e.indexOf("-"))),i.appendChild(n)),n}remove(i){return this._container.querySelectorAll("."+et.scopeID(i)).forEach(e=>{e.parentNode.removeChild(e)}),super.remove(i)}removeAll(){return this._container.innerHTML="",super.removeAll()}},$=class extends V{constructor(t){super();this._style={filled:!0,stroked:!0,background:"#f03","border-color":"#fff",color:"#000","border-width":"1px","border-radius":"0","border-style":"solid",opacity:1,position:"absolute",top:0,left:0,width:0,height:0};this._ctx={group:null,groupID:"pts",groupCount:0,currentID:"pts0",currentClass:"",style:{}};this._ready=!1;this._space=t,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID="pts_dom_"+$.groupID++,this._ctx.style=Object.assign({},this._style),this._ready=!0}})}get space(){return this._space}styleTo(t,e,r=""){if(this._ctx.style[t]===void 0)throw new Error(`${t} style property doesn't exist`);this._ctx.style[t]=`${e}${r}`}alpha(t){return this.styleTo("opacity",t),this}fill(t){return typeof t=="boolean"?(this.styleTo("filled",t),t||this.styleTo("background","transparent")):(this.styleTo("filled",!0),this.styleTo("background",t)),this}stroke(t,e,r,n){return typeof t=="boolean"?(this.styleTo("stroked",t),t||this.styleTo("border-width",0)):(this.styleTo("stroked",!0),this.styleTo("border-color",t),this.styleTo("border-width",(e||1)+"px")),this}fillText(t){return this.styleTo("color",t),this}cls(t){return typeof t=="boolean"?this._ctx.currentClass="":this._ctx.currentClass=t,this}font(t,e,r,n,s){return typeof t=="number"?(this._font.size=t,s&&(this._font.face=s),e&&(this._font.weight=e),r&&(this._font.style=r),n&&(this._font.lineHeight=n)):this._font=t,this._ctx.style.font=this._font.value,this}reset(){return this._ctx.style=Object.assign({},this._style),this._font=new N(10,"sans-serif"),this._ctx.style.font=this._font.value,this}updateScope(t,e){return this._ctx.group=e,this._ctx.groupID=t,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(t){if(!t||t.animateID==null)throw new Error("item not defined or not yet added to Space");return this.updateScope($.scopeID(t),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(t){return t.currentID||`p-${$.domID++}`}static scopeID(t){return`item-${t.animateID}`}static style(t,e){let r=[];e.filled||r.push("background: none"),e.stroked||r.push("border: none");for(let n in e)if(e.hasOwnProperty(n)&&n!="filled"&&n!="stroked"){let s=e[n];if(s){if(!e.filled&&n.indexOf("background")===0)continue;if(!e.stroked&&n.indexOf("border-width")===0)continue;r.push(`${n}: ${s}`)}}return F.setAttr(t,{style:r.join(";")})}static rectStyle(t,e,r){return t.style.left=e[0]+"px",t.style.top=e[1]+"px",t.style.width=r[0]+"px",t.style.height=r[1]+"px",t}static textStyle(t,e){return t.style.left=e[0]+"px",t.style.top=e[1]+"px",t}static point(t,e,r=5,n="square"){return n==="circle"?$.circle(t,e,r):$.square(t,e,r)}point(t,e=5,r="square"){return this.nextID(),r=="circle"&&this.styleTo("border-radius","100%"),$.point(this._ctx,t,e,r),this}static circle(t,e,r=10){let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-circle ${t.currentClass}`}),$.rectStyle(t,new u(e).$subtract(r),new u(r*2,r*2)),$.style(n,t.style),n}circle(t){return this.nextID(),this.styleTo("border-radius","100%"),$.circle(this._ctx,t[0],t[1][0]),this}static square(t,e,r){let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-square ${t.currentClass}`}),$.rectStyle(t,new u(e).$subtract(r),new u(r*2,r*2)),$.style(n,t.style),n}square(t,e){return this.nextID(),$.square(this._ctx,t,e),this}static rect(t,e){let r=m.iterToArray(e);if(!m.arrayCheck(r))return;let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-rect ${t.currentClass}`}),$.rectStyle(t,r[0],r[1]),$.style(n,t.style),n}rect(t){return this.nextID(),this.styleTo("border-radius","0"),$.rect(this._ctx,t),this}static text(t,e,r){let n=F.htmlElement(t.group,"div",$.getID(t));return F.setAttr(n,{class:`pts-form pts-text ${t.currentClass}`}),n.textContent=r,$.textStyle(t,e),$.style(n,t.style),n}text(t,e){return this.nextID(),$.text(this._ctx,t,e),this}log(t){return this.fill("#000").stroke("#fff",.5).text([10,14],t),this}arc(t,e,r,n,s){return m.warn("arc is not implemented in HTMLForm"),this}line(t){return m.warn("line is not implemented in HTMLForm"),this}polygon(t){return m.warn("polygon is not implemented in HTMLForm"),this}},et=$;et.groupID=0,et.domID=0;var Bt={};B(Bt,{SVGForm:()=>rt,SVGSpace:()=>H});var H=class extends R{constructor(t,e){super(t,e);this._bgcolor="#999";if(this._canvas.nodeName.toLowerCase()!="svg"){let r=H.svgElement(this._canvas,"svg",`${this.id}_svg`);this._container=this._canvas,this._canvas=r}}getForm(){return new rt(this)}get element(){return this._canvas}resize(t,e){return super.resize(t,e),H.setAttr(this.element,{viewBox:`0 0 ${this.bound.width} ${this.bound.height}`,width:`${this.bound.width}`,height:`${this.bound.height}`,xmlns:"http://www.w3.org/2000/svg",version:"1.1"}),this}static svgElement(t,e,r){if(!t||!t.appendChild)throw new Error("parent is not a valid DOM element");let n=document.querySelector(`#${r}`);return n||(n=document.createElementNS("http://www.w3.org/2000/svg",e),n.setAttribute("id",r),t.appendChild(n)),n}remove(t){return this._container.querySelectorAll("."+rt.scopeID(t)).forEach(r=>{r.parentNode.removeChild(r)}),super.remove(t)}removeAll(){return this._container.innerHTML="",super.removeAll()}},I=class extends V{constructor(t){super();this._style={filled:!0,stroked:!0,fill:"#f03",stroke:"#fff","stroke-width":1,"stroke-linejoin":"bevel","stroke-linecap":"sqaure",opacity:1};this._ctx={group:null,groupID:"pts",groupCount:0,currentID:"pts0",currentClass:"",style:{}};this._ready=!1;this._space=t,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID="pts_svg_"+I.groupID++,this._ctx.style=Object.assign({},this._style),this._ready=!0}})}get space(){return this._space}styleTo(t,e){if(this._ctx.style[t]===void 0)throw new Error(`${t} style property doesn't exist`);this._ctx.style[t]=e}alpha(t){return this.styleTo("opacity",t),this}fill(t){return typeof t=="boolean"?this.styleTo("filled",t):(this.styleTo("filled",!0),this.styleTo("fill",t)),this}stroke(t,e,r,n){return typeof t=="boolean"?this.styleTo("stroked",t):(this.styleTo("stroked",!0),this.styleTo("stroke",t),e&&this.styleTo("stroke-width",e),r&&this.styleTo("stroke-linejoin",r),n&&this.styleTo("stroke-linecap",n)),this}cls(t){return typeof t=="boolean"?this._ctx.currentClass="":this._ctx.currentClass=t,this}font(t,e,r,n,s){return typeof t=="number"?(this._font.size=t,s&&(this._font.face=s),e&&(this._font.weight=e),r&&(this._font.style=r),n&&(this._font.lineHeight=n)):this._font=t,this._ctx.style.font=this._font.value,this}reset(){return this._ctx.style=Object.assign({},this._style),this._font=new N(10,"sans-serif"),this._ctx.style.font=this._font.value,this}updateScope(t,e){return this._ctx.group=e,this._ctx.groupID=t,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(t){if(!t||t.animateID==null)throw new Error("item not defined or not yet added to Space");return this.updateScope(I.scopeID(t),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(t){return t.currentID||`p-${I.domID++}`}static scopeID(t){return`item-${t.animateID}`}static style(t,e){let r=[];e.filled||r.push("fill: none"),e.stroked||r.push("stroke: none");for(let n in e)if(e.hasOwnProperty(n)&&n!="filled"&&n!="stroked"){let s=e[n];if(s){if(!e.filled&&n.indexOf("fill")===0)continue;if(!e.stroked&&n.indexOf("stroke")===0)continue;r.push(`${n}: ${s}`)}}return R.setAttr(t,{style:r.join(";")})}static point(t,e,r=5,n="square"){return n==="circle"?I.circle(t,e,r):I.square(t,e,r)}point(t,e=5,r="square"){return this.nextID(),I.point(this._ctx,t,e,r),this}static circle(t,e,r=10){let n=H.svgElement(t.group,"circle",I.getID(t));return R.setAttr(n,{cx:e[0],cy:e[1],r,class:`pts-svgform pts-circle ${t.currentClass}`}),I.style(n,t.style),n}circle(t){this.nextID();let e=m.iterToArray(t);return I.circle(this._ctx,e[0],e[1][0]),this}static arc(t,e,r,n,s,o){let l=H.svgElement(t.group,"path",I.getID(t)),a=new u(e).toAngle(n,r,!0),h=new u(e).toAngle(s,r,!0),d=g.boundAngle(s)-g.boundAngle(n)>L.pi;o&&(d=!d);let f=o?"0":"1",w=`M ${a[0]} ${a[1]} A ${r} ${r} 0 ${d?"1":"0"} ${f} ${h[0]} ${h[1]}`;return R.setAttr(l,{d:w,class:`pts-svgform pts-arc ${t.currentClass}`}),I.style(l,t.style),l}arc(t,e,r,n,s){return this.nextID(),I.arc(this._ctx,t,e,r,n,s),this}static square(t,e,r){let n=H.svgElement(t.group,"rect",I.getID(t));return R.setAttr(n,{x:e[0]-r,y:e[1]-r,width:r*2,height:r*2,class:`pts-svgform pts-square ${t.currentClass}`}),I.style(n,t.style),n}square(t,e){return this.nextID(),I.square(this._ctx,t,e),this}static line(t,e){let r=I.pointsString(e);if(r.count<2)return;if(r.count>2)return I._poly(t,r.string,!1);let n=H.svgElement(t.group,"line",I.getID(t)),s=m.iterToArray(e);return R.setAttr(n,{x1:s[0][0],y1:s[0][1],x2:s[1][0],y2:s[1][1],class:`pts-svgform pts-line ${t.currentClass}`}),I.style(n,t.style),n}line(t){return this.nextID(),I.line(this._ctx,t),this}static _poly(t,e,r=!0){let n=H.svgElement(t.group,r?"polygon":"polyline",I.getID(t));return R.setAttr(n,{points:e,class:`pts-svgform pts-polygon ${t.currentClass}`}),I.style(n,t.style),n}static pointsString(t){let e="",r=0;for(let n of t)e+=`${n[0]},${n[1]} `,r++;return{string:e,count:r}}static polygon(t,e){let r=I.pointsString(e);return I._poly(t,r.string,!0)}polygon(t){return this.nextID(),I.polygon(this._ctx,t),this}static rect(t,e){if(!m.arrayCheck(e))return;let r=H.svgElement(t.group,"rect",I.getID(t)),n=c.fromArray(e).boundingBox(),s=k.size(n);return R.setAttr(r,{x:n[0][0],y:n[0][1],width:s[0],height:s[1],class:`pts-svgform pts-rect ${t.currentClass}`}),I.style(r,t.style),r}rect(t){return this.nextID(),I.rect(this._ctx,t),this}static text(t,e,r){let n=H.svgElement(t.group,"text",I.getID(t));return R.setAttr(n,{"pointer-events":"none",x:e[0],y:e[1],dx:0,dy:0,class:`pts-svgform pts-text ${t.currentClass}`}),n.textContent=r,I.style(n,t.style),n}text(t,e){return this.nextID(),I.text(this._ctx,t,e),this}log(t){return this.fill("#000").stroke("#fff",.5).text([10,14],t),this}},rt=I;rt.groupID=0,rt.domID=0;var Rt={};B(Rt,{Body:()=>ot,Particle:()=>_t,World:()=>it});var it=class{constructor(i,t=1,e=0){this._lastTime=null;this._gravity=new u;this._friction=1;this._damping=.75;this._iterations=1;this._particles=[];this._bodies=[];this._pnames=[];this._bnames=[];return this._bound=G.fromGroup(i),this._friction=t,this._gravity=typeof e=="number"?new u(0,e):new u(e),this}get bound(){return this._bound}set bound(i){this._bound=i}get gravity(){return this._gravity}set gravity(i){this._gravity=i}get friction(){return this._friction}set friction(i){this._friction=i}get damping(){return this._damping}set damping(i){this._damping=i}get iterations(){return this._iterations}set iterations(i){this._iterations=i}get bodyCount(){return this._bodies.length}get particleCount(){return this._particles.length}body(i){let t=i;if(typeof i=="string"&&i.length>0&&(t=this._bnames.indexOf(i)),t>=0)return this._bodies[t]}particle(i){let t=i;if(typeof i=="string"&&i.length>0&&(t=this._pnames.indexOf(i)),t>=0)return this._particles[t]}bodyIndex(i){return this._bnames.indexOf(i)}particleIndex(i){return this._pnames.indexOf(i)}update(i){let t=i/1e3;this._updateParticles(t),this._updateBodies(t)}drawParticles(i){this._drawParticles=i}drawBodies(i){this._drawBodies=i}add(i,t=""){return i instanceof ot?(this._bodies.push(i),this._bnames.push(t)):(this._particles.push(i),this._pnames.push(t)),this}_index(i,t){let e=0;if(typeof t=="string"){if(e=i(t),e<0)throw new Error(`Cannot find index of ${t}. You can use particleIndex() or bodyIndex() function to check existence by name.`)}else e=t;return e}removeBody(i,t=1){let e=this._index(this.bodyIndex.bind(this),i),r=e<0?[e*-1-1,t]:[e,t];return this._bodies.splice(r[0],r[1]),this._bnames.splice(r[0],r[1]),this}removeParticle(i,t=1){let e=this._index(this.particleIndex.bind(this),i),r=e<0?[e*-1-1,t]:[e,t];return this._particles.splice(r[0],r[1]),this._pnames.splice(r[0],r[1]),this}static edgeConstraint(i,t,e,r=1,n=!1){let s=1/(i.mass||1),o=1/(t.mass||1),l=s+o,a=t.$subtract(i),h=e*e,p=n?e/a.magnitude()-1:h/(a.dot(a)+h)-.5,d=a.$multiply(p*r);return i.subtract(d.$multiply(s/l)),t.add(d.$multiply(o/l)),i}static boundConstraint(i,t,e=.75){let r=g.boundingBox(t),n=i.$min(r[1].subtract(i.radius)).$max(r[0].add(i.radius));if(n[0]===r[0][0]||n[0]===r[1][0]){let s=i.changed.$multiply(e);i.previous=n.$subtract(new u(-s[0],s[1]))}else if(n[1]===r[0][1]||n[1]===r[1][1]){let s=i.changed.$multiply(e);i.previous=n.$subtract(new u(s[0],-s[1]))}i.to(n)}integrate(i,t,e){return i.addForce(this._gravity),i.verlet(t,this._friction,e),i}_updateParticles(i){for(let t=0,e=this._particles.length;t=this.length)throw new Error("index1 is not in the Group's indices");if(e<0||e>=this.length)throw new Error("index1 is not in the Group's indices");let n=this[t].$subtract(this[e]).magnitude();return this._cs.push([t,e,n,r||this._stiff]),this}linkAll(t){let e=this.length/2;for(let r=0,n=this.length;r=n-1?0:r+1;if(this.link(r,s,t),n>4){let o=Math.floor(e/2)+1,l=r>=n-o?r%n:r+o;this.link(r,l,t)}r<=e-1&&this.link(r,Math.min(this.length-1,r+Math.floor(e)))}}linksToLines(){let t=[];for(let e=0,r=this._cs.length;eMath.abs(l[0][1]-l[1][1])?o=(n.vertex[0]-s[0]-l[0][0])/(l[1][0]-l[0][0]):o=(n.vertex[1]-s[1]-l[0][1])/(l[1][1]-l[0][1]);let a=1/(o*o+(1-o)*(1-o)),h=n.vertex.body.mass||1,p=n.edge[0].body.mass||1,d=h/(h+p),f=p/(h+p);l[0].subtract(s.$multiply(d*(1-o)*a/2)),l[1].subtract(s.$multiply(d*o*a/2)),n.vertex.add(s.$multiply(f))}}processParticle(t){let e=this,r=t,n=M.hasIntersectCircle(e,U.fromCenter(t,t.radius));if(n){let s=n.normal.$multiply(n.dist),o,l=n.edge;Math.abs(l[0][0]-l[1][0])>Math.abs(l[0][1]-l[1][1])?o=(n.vertex[0]-s[0]-l[0][0])/(l[1][0]-l[0][0]):o=(n.vertex[1]-s[1]-l[0][1])/(l[1][1]-l[0][1]);let a=1/(o*o+(1-o)*(1-o)),h=n.vertex.mass||r.mass||1,p=n.edge[0].body.mass||1,d=h/(h+p),f=p/(h+p);l[0].subtract(s.$multiply(d*(1-o)*a/2)),l[1].subtract(s.$multiply(d*o*a/2));let w=t.changed.add(s.$multiply(f));t.previous=t.$subtract(w)}}};var Ot={};B(Ot,{Sound:()=>W,Tempo:()=>ht});var ht=class{constructor(i){this._listeners={};this._listenerInc=0;this.bpm=i}static fromBeat(i){return new ht(6e4/i)}get bpm(){return this._bpm}set bpm(i){this._bpm=i,this._ms=6e4/this._bpm}get ms(){return this._ms}set ms(i){this._bpm=Math.floor(6e4/i),this._ms=6e4/this._bpm}_createID(i){let t="";return typeof i=="function"?t="_b"+this._listenerInc++:t=i.name||"_b"+this._listenerInc++,t}every(i){let t=this,e=Array.isArray(i)?i[0]:i;return{start:function(r,n=0,s){let o=s||t._createID(r);return t._listeners[o]={name:o,beats:i,period:e,index:0,offset:n,duration:-1,continuous:!1,fn:r},this},progress:function(r,n=0,s){let o=s||t._createID(r);return t._listeners[o]={name:o,beats:i,period:e,index:0,offset:n,duration:-1,continuous:!0,fn:r},this}}}track(i){for(let t in this._listeners)if(this._listeners.hasOwnProperty(t)){let e=this._listeners[t],r=e.offset?i+e.offset:i,n=e.period*this._ms,s=!1;r>e.duration+n&&(e.duration=r-r%this._ms,Array.isArray(e.beats)&&(e.index=(e.index+1)%e.beats.length,e.period=e.beats[e.index]),s=!0);let o=Math.max(0,Math.ceil(Math.floor(e.duration/this._ms)/e.period)),l=e.continuous?[o,v.clamp((r-e.duration)/n,0,1),r,s]:[o];(e.continuous||s)&&e.fn.apply(e,l)&&delete this._listeners[e.name]}}stop(i){this._listeners[i]&&delete this._listeners[i]}animate(i,t){this.track(i)}resize(i,t){}action(i,t,e,r){}},W=class{constructor(i){this._playing=!1;this._type=i,this._createAudioContext()}_createAudioContext(){let i=window.AudioContext;if(!i)throw new Error("Your browser doesn't support Web Audio. (No AudioContext)");this._ctx=i?new i:void 0}static from(i,t,e="gen",r){let n=new W(e);return n._node=i,n._ctx=t,r&&(n._stream=r),n}static load(i,t="anonymous"){return new Promise((e,r)=>{let n=new W("file");n._source=typeof i=="string"?new Audio(i):i,n._source.autoplay=!1,n._source.crossOrigin=t,n._source.addEventListener("ended",function(){n._playing=!1}),n._source.addEventListener("error",function(){r("Error loading sound")}),n._source.addEventListener("canplaythrough",function(){n._node||(n._node=n._ctx.createMediaElementSource(n._source)),e(n)})})}static loadAsBuffer(i){return new Promise((t,e)=>{let r=new XMLHttpRequest;r.open("GET",i,!0),r.responseType="arraybuffer";let n=new W("file");r.onload=function(){n._ctx.decodeAudioData(r.response,function(s){n.createBuffer(s),t(n)},s=>e("Error decoding audio"))},r.send()})}createBuffer(i){return this._node=this._ctx.createBufferSource(),i!==void 0&&(this._buffer=i),this._node.buffer=this._buffer,this._node.onended=()=>{this._playing=!1},this}static generate(i,t){return new W("gen")._gen(i,t)}_gen(i,t){this._node=this._ctx.createOscillator();let e=this._node;return e.type=i,i==="custom"?e.setPeriodicWave(t):e.frequency.value=t,this}static input(i){return lt(this,null,function*(){try{let t=new W("input");if(!t)return;let e=i||{audio:!0,video:!1};return t._stream=yield navigator.mediaDevices.getUserMedia(e),t._node=t._ctx.createMediaStreamSource(t._stream),t}catch(t){return console.error("Cannot get audio from input device."),Promise.resolve(null)}})}get ctx(){return this._ctx}get node(){return this._node}get outputNode(){return this._outputNode}get stream(){return this._stream}get source(){return this._source}get buffer(){return this._buffer}set buffer(i){this._buffer=i}get type(){return this._type}get playing(){return this._playing}get progress(){let i=0,t=0;return this._buffer?(i=this._buffer.duration,t=this._timestamp?this._ctx.currentTime-this._timestamp:0):(i=this._source.duration,t=this._source.currentTime),t/i}get playable(){return this._type==="input"?this._node!==void 0:!!this._buffer||this._source.readyState===4}get binSize(){return this.analyzer.size}get sampleRate(){return this._ctx.sampleRate}get frequency(){return this._type==="gen"?this._node.frequency.value:0}set frequency(i){this._type==="gen"&&(this._node.frequency.value=i)}connect(i){return this._node.connect(i),this}setOutputNode(i){return this._outputNode=i,this}removeOutputNode(){return this._outputNode=null,this}analyze(i=256,t=-100,e=-30,r=.8){let n=this._ctx.createAnalyser();return n.fftSize=i*2,n.minDecibels=t,n.maxDecibels=e,n.smoothingTimeConstant=r,this.analyzer={node:n,size:n.frequencyBinCount,data:new Uint8Array(n.frequencyBinCount)},this._node.connect(this.analyzer.node),this}_domain(i){return this.analyzer?(i?this.analyzer.node.getByteTimeDomainData(this.analyzer.data):this.analyzer.node.getByteFrequencyData(this.analyzer.data),this.analyzer.data):new Uint8Array(0)}_domainTo(i,t,e=[0,0],r=[0,0]){let n=i?this.timeDomain():this.freqDomain(),s=new c;for(let o=r[0],l=n.length-r[1];o0&&(this._source.currentTime=i)):this._type==="gen"&&(this._gen(this._node.type,this._node.frequency.value),this._node.start(),this.analyzer&&this._node.connect(this.analyzer.node)),(this._outputNode||this._node).connect(this._ctx.destination),this._playing=!0,this}stop(){return this._playing&&(this._outputNode||this._node).disconnect(this._ctx.destination),this._type==="file"?this._buffer?this.progress<1&&this._node.stop():this._source.pause():this._type==="gen"?this._node.stop():this._type==="input"&&this._stream.getAudioTracks().forEach(i=>i.stop()),this._playing=!1,this}toggle(){return this._playing?this.stop():this.start(),this}};globalThis.Pts=z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z({},Tt),Gt),Dt),Pt),kt),wt),Lt),Mt),St),vt),zt),Bt),At),Rt),Ct),Ot),$t);globalThis.Pts.namespace=y=>{let i=globalThis.Pts;for(let t in i)t!="namespace"&&(y[t]=i[t])};globalThis.Pts.quickStart=(y,i="#9ab")=>{if(!window)return;let t=globalThis;return globalThis.Pts.namespace(t),t.space=new at(y).setup({bgcolor:i,resize:!0,retina:!0}),t.form=t.space.getForm(),function(e=null,r=null,n=null,s=null){t.space.add({start:r,animate:e,resize:s,action:n}),t.space.bindMouse().bindTouch().play()}};})(); /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */ //# sourceMappingURL=pts.min.js.map \ No newline at end of file diff --git a/dist/pts.min.js.map b/dist/pts.min.js.map index c3466eeb..9701ecca 100644 --- a/dist/pts.min.js.map +++ b/dist/pts.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/Canvas.ts","../src/Space.ts","../src/Pt.ts","../src/Util.ts","../src/Num.ts","../src/Op.ts","../src/LinearAlgebra.ts","../src/uheprng.ts","../src/UI.ts","../src/Form.ts","../src/Typography.ts","../src/Image.ts","../src/Create.ts","../src/Color.ts","../src/Dom.ts","../src/Svg.ts","../src/Physics.ts","../src/Play.ts","../src/_script.ts"],"sourcesContent":["/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\r\n\r\nimport {MultiTouchSpace} from './Space';\r\nimport {VisualForm, Font} from \"./Form\";\r\nimport {Pt, Group, Bound} from \"./Pt\";\r\nimport {Const, Util} from \"./Util\";\r\nimport {Typography as Typo} from \"./Typography\";\r\nimport { Rectangle } from './Op';\r\nimport {Img} from './Image';\r\nimport {PtLike, GroupLike, PtsCanvasRenderingContext2D, DefaultFormStyle, PtLikeIterable, PtIterable, CanvasSpaceOptions} from \"./Types\";\r\n\r\n\r\n\r\n\r\n/**\r\n* CanvasSpace is an implementation of the abstract class [`Space`](#link). It represents a space for HTML Canvas.\r\n* Learn more about the concept of Space in [this guide](../guide/Space-0500.html).\r\n*/\r\nexport class CanvasSpace extends MultiTouchSpace {\r\n \r\n protected _canvas:HTMLCanvasElement;\r\n protected _container:Element;\r\n\r\n protected _pixelScale = 1;\r\n protected _autoResize = true;\r\n protected _bgcolor = \"#e1e9f0\";\r\n protected _ctx:PtsCanvasRenderingContext2D;\r\n \r\n protected _offscreen = false;\r\n protected _offCanvas:HTMLCanvasElement;\r\n protected _offCtx:PtsCanvasRenderingContext2D;\r\n\r\n protected _initialResize = false;\r\n \r\n\r\n \r\n /**\r\n * Create a CanvasSpace which represents a HTML Canvas Space\r\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. An element can be an existing ``, or a `
` container in which a new `` will be created. If left empty, a `
` will be added to DOM. Use css to customize its appearance if needed.\r\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when canvas is appended and ready. Alternatively, a \"ready\" event will also be fired from the `` element when it's appended, which can be traced with `spaceInstance.canvas.addEventListener(\"ready\")`\r\n * @example `new CanvasSpace( \"#myElementID\" )`\r\n */\r\n constructor( elem:string|Element, callback?:Function) {\r\n super();\r\n \r\n var _selector:Element = null;\r\n var _existed = false;\r\n this.id = \"pt\";\r\n \r\n // check element or element id string\r\n if ( elem instanceof Element ) {\r\n _selector = elem;\r\n this.id = \"pts_existing_space\";\r\n } else {\r\n let id = elem;\r\n id = (elem[0] === \"#\" || elem[0] === \".\") ? elem : \"#\"+elem;\r\n _selector = document.querySelector( id );\r\n _existed = true;\r\n this.id = id.substr(1);\r\n }\r\n \r\n // if selector is not defined, create a canvas\r\n if (!_selector) { \r\n this._container = this._createElement( \"div\", this.id+\"_container\" );\r\n this._canvas = this._createElement( \"canvas\", this.id ) as HTMLCanvasElement;\r\n this._container.appendChild( this._canvas );\r\n document.body.appendChild( this._container );\r\n _existed = false;\r\n \r\n // if selector is element but not canvas, create a canvas inside it\r\n } else if (_selector.nodeName.toLowerCase() != \"canvas\") { \r\n this._container = _selector;\r\n this._canvas = this._createElement( \"canvas\", this.id+\"_canvas\" ) as HTMLCanvasElement;\r\n this._container.appendChild( this._canvas );\r\n this._initialResize = true;\r\n \r\n // if selector is an existing canvas\r\n } else {\r\n this._canvas = _selector as HTMLCanvasElement;\r\n this._container = _selector.parentElement;\r\n this._autoResize = false;\r\n }\r\n \r\n // if size is known then set it immediately\r\n // if (_existed) {\r\n // let b = this._container.getBoundingClientRect();\r\n // this.resize( Bound.fromBoundingRect(b) );\r\n // }\r\n \r\n // no mutation observer, so we set a timeout for ready event\r\n setTimeout( this._ready.bind( this, callback ), 100 );\r\n \r\n // store canvas 2d rendering context\r\n this._ctx = this._canvas.getContext('2d');\r\n \r\n }\r\n \r\n \r\n /**\r\n * Helper function to create a DOM element\r\n * @param elem element tag name\r\n * @param id element id attribute\r\n */\r\n protected _createElement( elem=\"div\", id ) {\r\n let d = document.createElement( elem );\r\n d.setAttribute(\"id\", id);\r\n return d;\r\n }\r\n \r\n \r\n /**\r\n * Handle callbacks after element is mounted in DOM\r\n * @param callback \r\n */\r\n private _ready( callback:Function ) {\r\n if (!this._container) throw new Error(`Cannot initiate #${this.id} element`);\r\n \r\n this._isReady = true;\r\n \r\n this._resizeHandler( null );\r\n\r\n this.clear( this._bgcolor );\r\n this._canvas.dispatchEvent( new Event(\"ready\") );\r\n \r\n for (let k in this.players) {\r\n if (this.players.hasOwnProperty(k)) {\r\n if (this.players[k].start) this.players[k].start( this.bound.clone(), this );\r\n }\r\n }\r\n \r\n this._pointer = this.center;\r\n this._initialResize = false; // unset\r\n \r\n if (callback) callback( this.bound, this._canvas );\r\n }\r\n \r\n \r\n /**\r\n * Set up various options for CanvasSpace. The `opt` parameter is an object with the following fields. This is usually set during instantiation, eg `new CanvasSpace(...).setup( { opt } )`\r\n * @param opt a [`CanvasSpaceOptions`](#link) object with optional settings, ie `{ bgcolor:string, resize:boolean, retina:boolean, offscreen:boolean, pixelDensity:number }`. \r\n * @example `space.setup({ bgcolor: \"#f00\", retina: true, resize: true })`\r\n */\r\n setup( opt:CanvasSpaceOptions ):this {\r\n this._bgcolor = opt.bgcolor ? opt.bgcolor : \"transparent\";\r\n \r\n this.autoResize = (opt.resize != undefined) ? opt.resize : false;\r\n \r\n if (opt.retina !== false) {\r\n let r1 = window ? window.devicePixelRatio || 1 : 1;\r\n let r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1; \r\n this._pixelScale = Math.max(1, r1/r2);\r\n }\r\n \r\n if (opt.offscreen) {\r\n this._offscreen = true;\r\n this._offCanvas = this._createElement( \"canvas\", this.id+\"_offscreen\" ) as HTMLCanvasElement;\r\n this._offCtx = this._offCanvas.getContext('2d');\r\n } else {\r\n this._offscreen = false;\r\n }\r\n\r\n if (opt.pixelDensity) {\r\n this._pixelScale = opt.pixelDensity;\r\n }\r\n \r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * Set whether the canvas element should resize when its container is resized. \r\n * @param auto a boolean value indicating if auto size is set\r\n */\r\n set autoResize( auto ) {\r\n if (!window) return;\r\n this._autoResize = auto;\r\n if (auto) {\r\n window.addEventListener( 'resize', this._resizeHandler.bind(this) );\r\n } else {\r\n window.removeEventListener( 'resize', this._resizeHandler.bind(this) );\r\n }\r\n }\r\n get autoResize(): boolean { return this._autoResize; }\r\n \r\n \r\n /**\r\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly. You can keep track of resize events with `resize: (bound ,evt)` callback in your player objects. \r\n * @param b a Bound object to resize to\r\n * @param evt Optionally pass a resize event\r\n * @see Space.add\r\n */\r\n resize( b:Bound, evt?:Event):this {\r\n \r\n this.bound = b;\r\n\r\n this._canvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;\r\n this._canvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;\r\n this._canvas.style.width = Math.ceil(this.bound.size.x) + \"px\";\r\n this._canvas.style.height = Math.ceil(this.bound.size.y) + \"px\";\r\n \r\n if (this._offscreen) {\r\n this._offCanvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;\r\n this._offCanvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;\r\n // this._offCanvas.style.width = Math.floor(this.bound.size.x) + \"px\";\r\n // this._offCanvas.style.height = Math.floor(this.bound.size.y) + \"px\";\r\n }\r\n \r\n if (this._pixelScale != 1) {\r\n this._ctx.scale( this._pixelScale, this._pixelScale );\r\n \r\n if (this._offscreen) {\r\n this._offCtx.scale( this._pixelScale, this._pixelScale );\r\n }\r\n }\r\n \r\n for (let k in this.players) {\r\n if (this.players.hasOwnProperty(k)) {\r\n let p = this.players[k];\r\n if (p.resize) p.resize( this.bound, evt);\r\n }\r\n }\r\n \r\n this.render( this._ctx );\r\n\r\n // if it's a valid resize event and space is not playing, repaint the canvas once\r\n if (evt && !this.isPlaying) this.playOnce( 0 ); \r\n \r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * Window resize handling\r\n * @param evt \r\n */\r\n protected _resizeHandler( evt:Event ) {\r\n if (!window) return;\r\n let b = (this._autoResize || this._initialResize) ? this._container.getBoundingClientRect() : this._canvas.getBoundingClientRect();\r\n\r\n if (b) {\r\n let box = Bound.fromBoundingRect(b);\r\n \r\n // Need to compute offset from window scroll. See outerBound calculation in Space's _mouseAction \r\n box.center = box.center.add( window.pageXOffset, window.pageYOffset ); \r\n this.resize( box, evt );\r\n }\r\n }\r\n \r\n\r\n /**\r\n * Set a background color for this canvas. Alternatively, you may use `clear()` function.\r\n @param bg background color as hex or rgba string\r\n */\r\n set background( bg:string ) { this._bgcolor = bg; }\r\n get background():string { return this._bgcolor; }\r\n\r\n \r\n /**\r\n * `pixelScale` property returns a number that let you determine if the screen is \"retina\" (when value >= 2)\r\n */\r\n public get pixelScale():number {\r\n return this._pixelScale;\r\n }\r\n \r\n \r\n /**\r\n * Check if an offscreen canvas is created\r\n */\r\n public get hasOffscreen():boolean {\r\n return this._offscreen;\r\n }\r\n \r\n \r\n /**\r\n * Get the rendering context of offscreen canvas (if created via `setup()`)\r\n */\r\n public get offscreenCtx():PtsCanvasRenderingContext2D { return this._offCtx; }\r\n \r\n \r\n /**\r\n * Get the offscreen canvas element\r\n */\r\n public get offscreenCanvas():HTMLCanvasElement { return this._offCanvas; }\r\n \r\n \r\n\r\n \r\n /**\r\n * Get a new `CanvasForm` for drawing\r\n * @see `CanvasForm`\r\n */\r\n public getForm():CanvasForm { return new CanvasForm(this); }\r\n \r\n \r\n /**\r\n * Get the html canvas element\r\n */\r\n get element():HTMLCanvasElement {\r\n return this._canvas;\r\n }\r\n \r\n \r\n /**\r\n * Get the parent element that contains the canvas element\r\n */\r\n get parent():Element {\r\n return this._container;\r\n }\r\n\r\n\r\n /**\r\n * A property to indicate if the Space is ready\r\n */\r\n get ready():boolean { \r\n return this._isReady; \r\n }\r\n \r\n \r\n /**\r\n * Get the rendering context of canvas\r\n * @example `form.ctx.clip()`\r\n */\r\n public get ctx():PtsCanvasRenderingContext2D { return this._ctx; }\r\n \r\n \r\n \r\n /**\r\n * Clear the canvas with its background color. Overrides Space's `clear` function.\r\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\r\n */\r\n clear( bg?:string ):this {\r\n \r\n if (bg) this._bgcolor = bg;\r\n const lastColor = this._ctx.fillStyle;\r\n const px = Math.ceil(this.pixelScale);\r\n \r\n if (!this._bgcolor || this._bgcolor === \"transparent\") {\r\n this._ctx.clearRect( -px, -px, this._canvas.width+px, this._canvas.height+px );\r\n } else { \r\n // semi-transparent bg needs to be cleared first\r\n if (this._bgcolor.indexOf(\"rgba\") === 0 || (this._bgcolor.length === 9 && this._bgcolor.indexOf(\"#\") === 0) ) { \r\n this._ctx.clearRect( -px, -px, this._canvas.width+px, this._canvas.height+px );\r\n }\r\n this._ctx.fillStyle = this._bgcolor;\r\n this._ctx.fillRect( -px, -px, this._canvas.width+px, this._canvas.height+px );\r\n }\r\n \r\n this._ctx.fillStyle = lastColor;\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * Similiar to `clear()` but clear the offscreen canvas instead\r\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\r\n */\r\n clearOffscreen( bg?:string ):this {\r\n if (this._offscreen) {\r\n const px = Math.ceil(this.pixelScale);\r\n if (bg) {\r\n this._offCtx.fillStyle = bg;\r\n this._offCtx.fillRect( -px, -px, this._canvas.width+px, this._canvas.height+px );\r\n } else {\r\n this._offCtx.clearRect( -px, -px, this._offCanvas.width+px, this._offCanvas.height+px );\r\n }\r\n }\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * Main animation function.\r\n * @param time current time\r\n */\r\n protected playItems( time: number ) {\r\n if (this._isReady) {\r\n this._ctx.save();\r\n if (this._offscreen) this._offCtx.save();\r\n super.playItems( time );\r\n this._ctx.restore();\r\n if (this._offscreen) this._offCtx.restore();\r\n this.render( this._ctx );\r\n }\r\n }\r\n \r\n \r\n /**\r\n * Dispose of browser resources held by this space and remove all players. Call this before unmounting the canvas.\r\n */\r\n dispose():this {\r\n if (!window) return;\r\n // remove event listeners\r\n window.removeEventListener( 'resize', this._resizeHandler.bind(this) );\r\n // stop animation loop\r\n this.stop();\r\n // remove players from space\r\n this.removeAll();\r\n\r\n return this;\r\n }\r\n \r\n\r\n /**\r\n * Get a [`MediaRecorder`](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder) to record the current CanvasSpace. You can then call its `start()` function to start recording, and `stop()` to either download the video file or handle the blob data in the callback function you provided.\r\n * @param downloadOrCallback Either `true` to download the video, or provide a callback function to handle the Blob data, when recording is completed.\r\n * @param filetype video format. Default is \"webm\".\r\n * @param bitrate bitrate per second\r\n * @example `let rec = space.recorder(true); rec.start(); setTimeout( () => rec.stop(), 5000); // record 5s of video and download the file`\r\n */\r\n recorder( downloadOrCallback: boolean | ((blobURL:string) => {}), filetype:string = \"webm\", bitrate:number = 15000000 ): MediaRecorder {\r\n // @ts-ignore\r\n let stream = this._canvas.captureStream();\r\n const recorder = new MediaRecorder(stream, { mimeType: `video/${filetype}`, bitsPerSecond: bitrate } );\r\n \r\n recorder.ondataavailable = function(d) {\r\n let url = URL.createObjectURL( new Blob( [d.data], { type: `video/${filetype}` } ) );\r\n\r\n if (typeof downloadOrCallback === \"function\") {\r\n downloadOrCallback( url );\r\n\r\n } else if (downloadOrCallback) {\r\n let a = document.createElement(\"a\");\r\n a.href = url;\r\n a.download = `canvas_video.${filetype}`;\r\n a.click();\r\n a.remove();\r\n }\r\n };\r\n\r\n return recorder;\r\n }\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n* CanvasForm is an implementation of abstract class [`VisualForm`](#link). It provide methods to express Pts on [`CanvasSpace`](#link). \r\n* You may extend CanvasForm to implement your own expressions for CanvasSpace.\r\n*/\r\nexport class CanvasForm extends VisualForm {\r\n \r\n protected _space:CanvasSpace;\r\n protected _ctx:CanvasRenderingContext2D; \r\n protected _estimateTextWidth:(string) => number;\r\n\r\n /** \r\n * store common styles so that they can be restored to canvas context when using multiple forms. See `reset()`.\r\n */\r\n protected _style:DefaultFormStyle = {\r\n fillStyle: \"#f03\", strokeStyle:\"#fff\", \r\n lineWidth: 1, lineJoin: \"bevel\", lineCap: \"butt\",\r\n globalAlpha: 1\r\n };\r\n \r\n \r\n /**\r\n * Create a new CanvasForm. You may also use [`CanvasSpace.getForm()`](#link) to get the default form.\r\n * @param space an instance of CanvasSpace\r\n */\r\n constructor( space?:CanvasSpace|CanvasRenderingContext2D ) {\r\n super();\r\n\r\n // allow for undefined context to support custom contexts via subclassing. \r\n if (!space) return this; \r\n \r\n const _setup = (ctx) => {\r\n this._ctx = ctx;\r\n this._ctx.fillStyle = this._style.fillStyle;\r\n this._ctx.strokeStyle = this._style.strokeStyle; \r\n this._ctx.lineJoin = \"bevel\";\r\n this._ctx.font = this._font.value;\r\n this._ready = true;\r\n };\r\n\r\n if (space instanceof CanvasRenderingContext2D) {\r\n _setup( space );\r\n } else {\r\n this._space = space;\r\n this._space.add( { start: () => {\r\n _setup( this._space.ctx );\r\n }} );\r\n }\r\n }\r\n \r\n \r\n /**\r\n * get the CanvasSpace instance that this form is associated with\r\n */\r\n get space():CanvasSpace { return this._space; }\r\n \r\n\r\n /**\r\n * Get the rendering context of canvas to perform other canvas functions.\r\n * @example `form.ctx.clip()`\r\n */\r\n get ctx():PtsCanvasRenderingContext2D { return this._ctx; }\r\n\r\n\r\n /**\r\n * Toggle whether to draw on offscreen canvas (if offscreen is set in CanvasSpace)\r\n * @param off if `true`, draw on offscreen canvas instead of the visible canvas. Default is `true`\r\n * @param clear optionally provide a valid color string to fill a bg color. see CanvasSpace's `clearOffscreen` function.\r\n */\r\n useOffscreen( off:boolean=true, clear:boolean|string=false ) {\r\n if (clear) this._space.clearOffscreen( (typeof clear == \"string\") ? clear : null );\r\n this._ctx = (this._space.hasOffscreen && off) ? this._space.offscreenCtx : this._space.ctx;\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * Render the offscreen canvas's content on the visible canvas\r\n * @param offset Optional offset on the top-left position when drawing on the visible canvas\r\n */\r\n renderOffscreen( offset:PtLike=[0,0] ) {\r\n if (this._space.hasOffscreen) {\r\n this._space.ctx.drawImage( \r\n this._space.offscreenCanvas, offset[0], offset[1], this._space.width, this._space.height );\r\n }\r\n }\r\n \r\n \r\n /**\r\n * Set current alpha value.\r\n * @example `form.alpha(0.6)`\r\n * @param a alpha value between 0 and 1\r\n */\r\n alpha( a:number ):this {\r\n this._ctx.globalAlpha = a;\r\n this._style.globalAlpha = a;\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * Set current fill style. Provide a valid color string such as `\"#FFF\"` or `\"rgba(255,0,100,0.5)\"` or `false` to specify no fill color.\r\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\r\n * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))\r\n */\r\n fill( c:string|boolean|CanvasGradient|CanvasPattern ):this {\r\n if (typeof c == \"boolean\") {\r\n this.filled = c;\r\n } else {\r\n this.filled = true;\r\n this._style.fillStyle = c;\r\n this._ctx.fillStyle = c;\r\n }\r\n return this;\r\n }\r\n \r\n /**\r\n * Set current fill style and remove stroke style.\r\n * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))\r\n */\r\n fillOnly( c:string|boolean|CanvasGradient|CanvasPattern ):this {\r\n this.stroke( false );\r\n return this.fill( c );\r\n }\r\n \r\n \r\n /**\r\n * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.\r\n * @example `form.stroke(\"#F90\")`, `form.stroke(\"rgba(0,0,0,.5\")`, `form.stroke(false)`, `form.stroke(\"#000\", 0.5, 'round', 'square')`\r\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\r\n * @param width Optional value (can be floating point) to set line width\r\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\r\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\r\n */\r\n stroke( c:string|boolean|CanvasGradient|CanvasPattern, width?:number, linejoin?:CanvasLineJoin, linecap?:CanvasLineCap ):this {\r\n if (typeof c == \"boolean\") {\r\n this.stroked = c;\r\n } else {\r\n this.stroked = true;\r\n this._style.strokeStyle = c;\r\n this._ctx.strokeStyle = c;\r\n if (width) {\r\n this._ctx.lineWidth = width;\r\n this._style.lineWidth = width;\r\n }\r\n if (linejoin) {\r\n this._ctx.lineJoin = linejoin;\r\n this._style.lineJoin = linejoin;\r\n }\r\n if (linecap) {\r\n this._ctx.lineCap = linecap;\r\n this._style.lineCap = linecap;\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Set stroke style and remove fill style.\r\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\r\n * @param width Optional value (can be floating point) to set line width\r\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\r\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\r\n */\r\n strokeOnly( c:string|boolean|CanvasGradient|CanvasPattern, width?:number, linejoin?:CanvasLineJoin, linecap?:CanvasLineCap ):this {\r\n this.fill( false );\r\n return this.stroke( c, width, linejoin, linecap );\r\n }\r\n\r\n /**\r\n * A convenient function to apply fill and/or stroke after custom drawings using canvas context (eg, `form.ctx.ellipse(...)`). \r\n * You don't need to call this function if you're using Pts' drawing functions like `form.point` or `form.rect`\r\n * @param filled apply fill when set to `true`\r\n * @param stroked apply stroke when set to `true`\r\n * @param strokeWidth optionally set a stroke width\r\n * @example `form.ctx.beginPath(); form.ctx.ellipse(...); form.applyFillStroke();`\r\n */\r\n applyFillStroke( filled:boolean|string = true, stroked:boolean|string = true, strokeWidth:number = 1 ) {\r\n if (filled) {\r\n if (typeof filled === 'string') this.fill( filled );\r\n this._ctx.fill();\r\n }\r\n\r\n if (stroked) {\r\n if (typeof stroked === 'string') this.stroke( stroked, strokeWidth );\r\n this._ctx.stroke();\r\n }\r\n\r\n return this;\r\n }\r\n \r\n\r\n /**\r\n * This function takes an array of gradient colors, and returns a function to define the areas of the gradient fill. See demo code in [CanvasForm.gradient](https://ptsjs.org/demo/?name=canvasform.textBox).\r\n * @param stops an array of gradient stops. This can be an array of colors `[\"#f00\", \"#0f0\", ...]` for evenly distributed gradient, or an array of [stop, color] like `[[0.1, \"#f00\"], [0.7, \"#0f0\"]]`\r\n * @returns a function that takes 1 or 2 `Group` as parameters. Use a single `Group` to specify a rectangular area for linear gradient, or use 2 `Groups` to specify 2 `Circles` for radial gradient.\r\n * @example `c1 = Circle.fromCenter(...); grad = form.gradient([\"#f00\", \"#00f\"]); form.fill( grad( c1, c2 ) ).circle( c1 )`\r\n */\r\n gradient( stops:[number, string][]|string[] ):((area1:GroupLike, area2?:GroupLike) => CanvasGradient) {\r\n let vals:[number, string][] = [];\r\n if (stops.length < 2) (stops as [number, string][]).push( [0.99, \"#000\"], [1,\"#000\"] );\r\n\r\n for (let i=0, len=stops.length; i {\r\n let grad = area2 \r\n ? this._ctx.createRadialGradient( area1[0][0], area1[0][1], Math.abs(area1[1][0]), area2[0][0], area2[0][1], Math.abs(area2[1][0]) )\r\n : this._ctx.createLinearGradient( area1[0][0], area1[0][1], area1[1][0], area1[1][1] );\r\n\r\n for (let i=0, len=vals.length; i this._ctx.measureText(c).width) ) : undefined;\r\n return this;\r\n }\r\n\r\n\r\n /**\r\n * Get the width of this text. It will return an actual measurement or an estimate based on [`fontWidthEstimate`](#link) setting. Default is an actual measurement using canvas context's measureText.\r\n * @param c a string of text contents\r\n */\r\n getTextWidth( c:string ):number {\r\n return (!this._estimateTextWidth) ? this._ctx.measureText(c+\" .\").width : this._estimateTextWidth( c );\r\n }\r\n\r\n\r\n /**\r\n * Truncate text to fit width.\r\n * @param str text to truncate\r\n * @param width width to fit\r\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\r\n */\r\n protected _textTruncate( str:string, width:number, tail:string=\"\" ):[string, number] {\r\n return Typo.truncate( this.getTextWidth.bind(this), str, width, tail );\r\n }\r\n\r\n\r\n /**\r\n * Align text within a rectangle box.\r\n * @param box a Group or an Iterable that defines a rectangular box\r\n * @param vertical a string that specifies the vertical alignment in the box: \"top\", \"bottom\", \"middle\", \"start\", \"end\"\r\n * @param offset Optional offset from the edge (like padding)\r\n * @param center Optional center position \r\n */\r\n protected _textAlign( box:PtLikeIterable, vertical:string, offset?:PtLike, center?:Pt ):Pt {\r\n let _box = Util.iterToArray( box );\r\n if ( !Util.arrayCheck(_box) ) return;\r\n\r\n if (!center) center = Rectangle.center( _box );\r\n\r\n var px = _box[0][0];\r\n if (this._ctx.textAlign == \"end\" || this._ctx.textAlign == \"right\") {\r\n px = _box[1][0];\r\n // @ts-ignore\r\n } else if (this._ctx.textAlign == \"center\" || this._ctx.textAlign == \"middle\") {\r\n px = center[0];\r\n }\r\n\r\n var py = center[1];\r\n if (vertical == \"top\" || vertical == \"start\") {\r\n py = _box[0][1];\r\n } else if (vertical == \"end\" || vertical == \"bottom\") {\r\n py = _box[1][1];\r\n }\r\n\r\n return (offset) ? new Pt( px+offset[0], py+offset[1] ) : new Pt(px, py);\r\n }\r\n \r\n \r\n /**\r\n * Reset the rendering context's common styles to this form's styles. This supports using multiple forms on the same canvas context.\r\n */\r\n reset():this {\r\n for (let k in this._style) {\r\n if (this._style.hasOwnProperty(k)) {\r\n this._ctx[k] = this._style[k];\r\n }\r\n }\r\n this._font = new Font();\r\n this._ctx.font = this._font.value;\r\n return this;\r\n }\r\n \r\n \r\n protected _paint() {\r\n if (this._filled) this._ctx.fill();\r\n if (this._stroked) this._ctx.stroke();\r\n }\r\n \r\n\r\n /**\r\n * A static function to draw a point.\r\n * @param ctx canvas rendering context\r\n * @param p a Pt object\r\n * @param radius radius of the point. Default is 5.\r\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\r\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\r\n */\r\n static point( ctx:CanvasRenderingContext2D, p:PtLike, radius:number=5, shape:string=\"square\" ) {\r\n if (!p) return;\r\n if (!CanvasForm[shape]) throw new Error(`${shape} is not a static function of CanvasForm`);\r\n CanvasForm[shape]( ctx, p, radius );\r\n }\r\n \r\n\r\n /**\r\n * Draws a point.\r\n * @param p a Pt object\r\n * @param radius radius of the point. Default is 5.\r\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\r\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\r\n */\r\n point( p:PtLike, radius:number=5, shape:string=\"square\" ):this {\r\n CanvasForm.point( this._ctx, p, radius, shape );\r\n this._paint();\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * A static function to draw a circle.\r\n * @param ctx canvas rendering context\r\n * @param pt center position of the circle\r\n * @param radius radius of the circle\r\n */\r\n static circle( ctx:CanvasRenderingContext2D, pt:PtLike, radius:number=10 ) {\r\n if (!pt) return;\r\n ctx.beginPath();\r\n ctx.arc( pt[0], pt[1], radius, 0, Const.two_pi, false );\r\n ctx.closePath();\r\n }\r\n \r\n \r\n /**\r\n * Draw a circle. See also [`Circle.fromCenter`](#link)\r\n * @param pts usually a Group or an Iterable with 2 Pt, but it can also take an array of two numeric arrays [ [position], [size] ]\r\n */\r\n circle( pts:PtLikeIterable ):this {\r\n let p = Util.iterToArray( pts );\r\n CanvasForm.circle( this._ctx, p[0], p[1][0] );\r\n this._paint();\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * A static function to draw an ellipse.\r\n * @param ctx canvas rendering context\r\n * @param pt center position \r\n * @param radius radius [x, y] of the ellipse\r\n * @param rotation rotation of the ellipse in radian. Default is 0.\r\n * @param startAngle start angle of the ellipse. Default is 0.\r\n * @param endAngle end angle of the ellipse. Default is 2 PI.\r\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\r\n */\r\n static ellipse( ctx:CanvasRenderingContext2D, pt:PtLike, radius:PtLike, rotation:number=0, startAngle:number=0, endAngle:number=Const.two_pi, cc:boolean=false ) {\r\n if (!pt || !radius) return;\r\n ctx.beginPath();\r\n ctx.ellipse( pt[0], pt[1], radius[0], radius[1], rotation, startAngle, endAngle, cc );\r\n }\r\n\r\n\r\n /**\r\n * Draw an ellipse.\r\n * @param pt center position \r\n * @param radius radius [x, y] of the ellipse\r\n * @param rotation rotation of the ellipse in radian. Default is 0.\r\n * @param startAngle start angle of the ellipse. Default is 0.\r\n * @param endAngle end angle of the ellipse. Default is 2 PI.\r\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\r\n */\r\n ellipse( pt:PtLike, radius:PtLike, rotation:number=0, startAngle:number=0, endAngle:number=Const.two_pi, cc:boolean=false ) {\r\n CanvasForm.ellipse( this._ctx, pt, radius, rotation, startAngle, endAngle, cc );\r\n this._paint();\r\n return this;\r\n }\r\n\r\n\r\n /**\r\n * A static function to draw an arc.\r\n * @param ctx canvas rendering context\r\n * @param pt center position \r\n * @param radius radius of the arc circle\r\n * @param startAngle start angle of the arc\r\n * @param endAngle end angle of the arc\r\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\r\n */\r\n static arc( ctx:CanvasRenderingContext2D, pt:PtLike, radius:number, startAngle:number, endAngle:number, cc?:boolean ) {\r\n if (!pt) return;\r\n ctx.beginPath();\r\n ctx.arc( pt[0], pt[1], radius, startAngle, endAngle, cc );\r\n }\r\n\r\n\r\n /**\r\n * Draw an arc.\r\n * @param pt center position\r\n * @param radius radius of the arc circle\r\n * @param startAngle start angle of the arc\r\n * @param endAngle end angle of the arc\r\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\r\n */\r\n arc( pt:PtLike, radius:number, startAngle:number, endAngle:number, cc?:boolean ):this {\r\n CanvasForm.arc( this._ctx, pt, radius, startAngle, endAngle, cc );\r\n this._paint();\r\n return this;\r\n }\r\n\r\n \r\n /**\r\n * A static function to draw a square.\r\n * @param ctx canvas rendering context\r\n * @param pt center position of the square\r\n * @param halfsize half size of the square\r\n */\r\n static square( ctx:CanvasRenderingContext2D, pt:PtLike, halfsize:number ) {\r\n if (!pt) return;\r\n let x1 = pt[0]-halfsize;\r\n let y1 = pt[1]-halfsize;\r\n let x2 = pt[0]+halfsize;\r\n let y2 = pt[1]+halfsize;\r\n \r\n // faster than using `rect`\r\n ctx.beginPath();\r\n ctx.moveTo( x1, y1 );\r\n ctx.lineTo( x1, y2 );\r\n ctx.lineTo( x2, y2 );\r\n ctx.lineTo( x2, y1 );\r\n ctx.closePath();\r\n }\r\n \r\n \r\n /**\r\n * Draw a square, given a center and its half-size.\r\n * @param pt center Pt\r\n * @param halfsize half-size\r\n */\r\n square( pt:PtLike, halfsize:number ) {\r\n CanvasForm.square( this._ctx, pt, halfsize );\r\n this._paint();\r\n return this;\r\n }\r\n\r\n \r\n /**\r\n * A static function to draw a line or polyline.\r\n * @param ctx canvas rendering context\r\n * @param pts a Group or an Iterable representing a line\r\n */\r\n static line( ctx:CanvasRenderingContext2D, pts:PtLikeIterable ) {\r\n if ( !Util.arrayCheck(pts) ) return;\r\n let i = 0;\r\n ctx.beginPath();\r\n for (let it of pts) {\r\n if (it) {\r\n if (i++ > 0) {\r\n ctx.lineTo(it[0], it[1]);\r\n } else {\r\n ctx.moveTo(it[0], it[1]);\r\n }\r\n }\r\n }\r\n }\r\n \r\n \r\n /**\r\n * Draw a line or polyline.\r\n * @param pts a Group or an Iterable representing a line\r\n */\r\n line( pts:PtLikeIterable ):this {\r\n CanvasForm.line( this._ctx, pts );\r\n this._paint();\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * A static function to draw a polygon.\r\n * @param ctx canvas rendering context\r\n * @param pts a Group or an Iterable representing a polygon\r\n */\r\n static polygon( ctx:CanvasRenderingContext2D, pts:PtLikeIterable ) {\r\n if ( !Util.arrayCheck(pts) ) return;\r\n CanvasForm.line( ctx, pts );\r\n ctx.closePath();\r\n }\r\n \r\n \r\n /**\r\n * Draw a polygon.\r\n * @param pts a Group or an Iterable representingg a polygon\r\n */\r\n polygon( pts:PtLikeIterable ):this {\r\n CanvasForm.polygon( this._ctx, pts );\r\n this._paint();\r\n return this;\r\n }\r\n \r\n \r\n /**\r\n * A static function to draw a rectangle.\r\n * @param ctx canvas rendering context\r\n * @param pts a Group or an Iterable with 2 Pt specifying the top-left and bottom-right positions.\r\n */\r\n static rect( ctx:CanvasRenderingContext2D, pts:PtLikeIterable ) {\r\n let p = Util.iterToArray( pts );\r\n if ( !Util.arrayCheck(p) ) return;\r\n ctx.beginPath();\r\n ctx.moveTo( p[0][0], p[0][1] );\r\n ctx.lineTo( p[0][0], p[1][1] );\r\n ctx.lineTo( p[1][0], p[1][1] );\r\n ctx.lineTo( p[1][0], p[0][1] );\r\n ctx.closePath();\r\n \r\n }\r\n \r\n \r\n /**\r\n * Draw a rectangle.\r\n * @param pts a Group or an Iterable with 2 Pt specifying the top-left and bottom-right positions.\r\n */\r\n rect( pts:PtLikeIterable ):this {\r\n CanvasForm.rect( this._ctx, pts );\r\n this._paint();\r\n return this;\r\n }\r\n\r\n\r\n /**\r\n * A static function to draw an image.\r\n * @param ctx canvas rendering context\r\n * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from ``, `