From abacfdf4aaf4c0868beda042f5033fbdb731d193 Mon Sep 17 00:00:00 2001 From: Miriam Zusin Date: Tue, 25 Jul 2023 10:06:25 +0300 Subject: [PATCH] https://1rosehip.atlassian.net/browse/RRS-106 --- dist/mz-react-round-slider.esm.js | 2 +- dist/mz-react-round-slider.esm.js.map | 4 +- dist/mz-react-round-slider.min.js | 2 +- dist/mz-react-round-slider.min.js.map | 4 +- src/core/index.tsx | 6 + src/example/index.tsx | 12 +- test/browser/example.min.js | 188 +++----------------------- test/browser/example.min.js.map | 8 +- 8 files changed, 38 insertions(+), 188 deletions(-) diff --git a/dist/mz-react-round-slider.esm.js b/dist/mz-react-round-slider.esm.js index 9131447..c7cebdc 100644 --- a/dist/mz-react-round-slider.esm.js +++ b/dist/mz-react-round-slider.esm.js @@ -4,5 +4,5 @@ https://github.com/mzusin/react-round-slider MIT License Copyright (c) 2023-present, Miriam Zusin */ -var xt=Object.defineProperty,vt=Object.defineProperties;var At=Object.getOwnPropertyDescriptors;var ke=Object.getOwnPropertySymbols;var It=Object.prototype.hasOwnProperty,St=Object.prototype.propertyIsEnumerable;var Re=(e,t,r)=>t in e?xt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,K=(e,t)=>{for(var r in t||(t={}))It.call(t,r)&&Re(e,r,t[r]);if(ke)for(var r of ke(t))St.call(t,r)&&Re(e,r,t[r]);return e},_e=(e,t)=>vt(e,At(t));import{useEffect as ge,useRef as Dt,useState as me}from"react";var Tt=Math.pow,w=(e,t=1/0)=>{if(t===1/0)return e;t<0&&(t=0);let r=Tt(10,t);return Math.round(e*r)/r},v=(e,t)=>(e%t+t)%t,k=(e,t,r,o,n)=>(n-o)*(e-t)/(r-t)+o;var Le=e=>!isNaN(parseFloat(e))&&isFinite(e);var we=(e,t=1/0)=>{let r=e*(180/Math.PI);return w(r,t)},_=(e,t=1/0)=>{let r=e*(Math.PI/180);return w(r,t)};var Oe=(e,t,r=1/0)=>{let o=[];for(let n=0;nOe(e,t,r);var Ct=(e,t,r=1/0)=>{let o=[];for(let n=0;nCt(e,t,r);var Ne=(e,t=1/0)=>{let r=0;for(let o=0;o{let o=Oe(e,t);return Ne(o,r)};var Et=(e,t=1/0)=>{let r=Ne(e),o=[];for(let n=0;nEt(e,t);var L=(e,t,r)=>(t=t%Math.PI*2,[e[0]+Math.cos(t)*r,e[1]+Math.sin(t)*r]);var Fe=()=>Math.random().toString(36).substring(2)+new Date().getTime().toString(36);var ne=e=>{let t=e.duration!==void 0?e.duration:1/0,r,o,n,s,a=!1,l,c=()=>{r=void 0,n=void 0,s=void 0,a=!1,o!==void 0&&window.cancelAnimationFrame(o)},g=()=>{c(),u()},m=()=>{a=!1},f=()=>{a=!0},p=P=>{r===void 0&&(r=P),n=P-r,a&&s!==P&&typeof e.callback=="function"&&e.callback(I()),n<=t?(s=P,o=window.requestAnimationFrame(p)):c()},i=(P,E)=>{g(),typeof e.resizeCallback=="function"&&e.resizeCallback(P,E)},u=()=>{r=void 0,n=void 0,s=void 0,a=!0,e.restartOnResize&&window.ResizeObserver&&l===void 0?(l=new ResizeObserver(i),l.observe(document.body,{box:"border-box"})):o=window.requestAnimationFrame(p)},D=()=>n,h=()=>a,b=()=>r,C=()=>{if(!(t===1/0||n===void 0))return n*100/t},R=()=>l,I=()=>({start:u,stop:c,pause:m,resume:f,restart:g,isAnimating:h,getElapsedTime:D,getStartTime:b,getPercent:C,getResizeObserver:R});return I()};var Ue=(e,t,r,o,n,s)=>{let a=t+r*2,l=Math.max(0,o*2-a),c=e*2+a+l,[g,m]=Mt(e,o,t,r);return{cx:g,cy:m,radius:e,size:c,thickness:t,border:r,startAngleDeg:n,endAngleDeg:s}},Mt=(e,t,r,o)=>{let n=Pt(e,t,r,o),s=w(n/2,2);return[s,s]},Pt=(e,t,r,o)=>{let n=r+o*2,s=Math.max(0,t*2-n);return e*2+n+s};var He="#efefef";var Ve="#444444";var W="#163a86",pe="#000",be="#a8a8a8";var De="#000",xe="#5daed2",$e="#97b0bb",ze="#000";var Ge="#efefef",Xe="#000";var d=(e,t)=>Le(e)?Number(e):t,A=(e,t)=>e==null?t:e,O=(e,t)=>e==null?t:e;var U=(e,t,r)=>(e>t&&(t+=360),r>=e&&r<=t||r+360>=e&&r+360<=t),Z=(e,t)=>{t0?360:o},qe=(e,t,r)=>{e>t&&(t+=360);let o=2*Math.PI*r,n=t-e,s=-(e/360)*o,a=n/360*o,l=o-a;return{strokeDasharray:[a,l].join(" "),strokeOffset:s}};var V=(e,t,r,o,n,s,a)=>{let{left:l,top:c}=e.getBoundingClientRect(),g=[t-l,r-c],m=ye(g,[o,n]),f=Math.atan2(m[1]/a,m[0]/s);return f<0&&(f+=2*Math.PI),we(f)},q=(e,t,r,o)=>{o0){let s=Math.round(n);n=e.data[s]}else n=w(n,e.round);return n},kt=(e,t,r,o)=>{let n;if(o0){let s=e.data.findIndex(a=>a===t);n=s===-1?0:s}else n=typeof t!="number"?e.min:t;return v(k(n,e.min,e.max,r,o),360)},Rt=(e,t)=>{if(!e||!e.pointers||e.pointers.length<0||!t){let o=v(d(e.pathStartAngle,0),360),n=A(e.pointerBgColor,W),s=A(e.pointerBgColorSelected,pe),a=A(e.pointerBgColorDisabled,be),l=A(e.pointerBgColorHover,s);return[{id:"0",index:0,radius:d(e.pointerRadius,10),angleDeg:o,prevAngleDeg:o,bgColor:n,bgColorSelected:s,bgColorDisabled:a,bgColorHover:l,border:d(e.pointerBorder,0),borderColor:A(e.pointerBorderColor,De),disabled:!!e.disabled}]}let r=[];for(let o=0;o{let r=Rt(e,t);return{pointers:r,maxRadius:_t(r)}},_t=e=>{if(e.length<=0)return 0;let t=-1/0;for(let r of e)t=Math.max(t,Math.max(0,r.radius+r.border/2));return t},re=(e,t,r,o,n)=>{if(!e||e.length<=0)return null;if(e.length===1)return e[0];let s=k(_(t),0,Math.PI*2,0,Math.PI),a=L([r,o],s,n),l,c=null,g=e.filter(m=>!m.disabled);for(let m of g){let f=k(_(m.angleDeg),0,Math.PI*2,0,Math.PI),p=L([r,o],f,n),i=te(a,p);(l===void 0||i{let a=k(_(r),0,Math.PI*2,0,Math.PI),l=L([o,n],a,s),c=k(_(e),0,Math.PI*2,0,Math.PI),g=L([o,n],c,s),m=k(_(t),0,Math.PI*2,0,Math.PI),f=L([o,n],m,s),p=te(l,g),i=te(l,f);return p<=i?e:t},Ze=(e,t)=>{if(!e||e.length<=0)return null;let r,o,n=null,s=null;for(let a of e){let l=Z(t,a.angleDeg);(r===void 0||lo)&&(s=a,o=l)}return n===null||s===null?null:[n,s]},ve=(e,t,r,o)=>v(e,360)===v(r,360)||v(e,360)===v(o,360)?e:t===0?0:Math.round(e/t)*t;import{useEffect as se,useState as ae,useRef as Lt,useCallback as wt}from"react";var J={outline:"none"};import{Fragment as Bt,jsx as Ae,jsxs as Nt}from"react/jsx-runtime";var Ot=(e,t,r,o,n,s,a)=>e.disabled?n:a?s:e.id===t?o:r,yt=e=>{let t=Lt(null),{pointer:r,svg:o,$svg:n,data:s,settings:a,setPointer:l,selectedPointerId:c}=e,{radius:g,angleDeg:m,bgColor:f,bgColorSelected:p,bgColorDisabled:i,bgColorHover:u,border:D,borderColor:h}=e.pointer,{cx:b,cy:C}=o,[R,I]=ae(null),[P,E]=ae(""),[H,y]=ae(W),[M,S]=ae(!1);se(()=>{y(Ot(r,c,f,p,i,u,M))},[r,c,f,p,i,u,M]),se(()=>{let x=q(s,r.angleDeg,o.startAngleDeg,o.endAngleDeg);E(x===void 0?"":x.toString())},[s,r.angleDeg,o.startAngleDeg,o.endAngleDeg]),se(()=>{let x=k(_(m),0,Math.PI*2,0,Math.PI),G=L([b,C],x,o.radius);I(G)},[m,b,C,o.radius]);let T=wt(x=>{if(!n||a.disabled||r.disabled)return;let G=x.type.indexOf("mouse")!==-1?x.clientX:x.touches[0].clientX,j=x.type.indexOf("mouse")!==-1?x.clientY:x.touches[0].clientY,B=V(n,G,j,o.cx,o.cy,o.radius,o.radius),Y;U(o.startAngleDeg,o.endAngleDeg,B)?Y=B:Y=oe(o.startAngleDeg,o.endAngleDeg,r.angleDeg,o.cx,o.cy,o.radius),l(r,Y)},[n,r,l,o.cx,o.cy,o.endAngleDeg,o.radius,o.startAngleDeg,a.disabled]),z=()=>{window.removeEventListener("mousemove",T),window.removeEventListener("mouseup",T)},F=x=>{a.disabled||r.disabled||(T(x),window.addEventListener("mousemove",T),window.addEventListener("mouseup",z))},N=x=>{if(!(a.disabled||r.disabled||a.keyboardDisabled))switch(x.key){case"ArrowLeft":{x.preventDefault(),l(r,r.angleDeg+s.arrowStepAngleDeg);break}case"ArrowRight":{x.preventDefault(),l(r,r.angleDeg-s.arrowStepAngleDeg);break}case"ArrowUp":{x.preventDefault(),l(r,r.angleDeg-s.arrowStepAngleDeg);break}case"ArrowDown":{x.preventDefault(),l(r,r.angleDeg+s.arrowStepAngleDeg);break}}};se(()=>{let x=t.current,G=B=>{a.disabled||r.disabled||(B.preventDefault(),B.stopPropagation(),T(B))},j=B=>{if(a.disabled||r.disabled||a.mousewheelDisabled||document.activeElement!==x)return;B.stopPropagation(),B.preventDefault();let Y=B.deltaY<0,he;Y?he=r.angleDeg+s.arrowStepAngleDeg:he=r.angleDeg-s.arrowStepAngleDeg,l(r,he)};return x==null||x.addEventListener("touchmove",G,{passive:!1}),document.addEventListener("wheel",j,{passive:!1}),()=>{x==null||x.removeEventListener("touchmove",G),document.removeEventListener("wheel",j)}},[R,T,s.arrowStepAngleDeg,r,l,a.disabled,a.mousewheelDisabled]);let de=()=>{S(!0)},fe=()=>{S(!1)};return Ae(Bt,{children:R&&Nt("g",{ref:t,transform:`translate(${R[0]-g/2}, ${R[1]-g/2})`,role:"slider","aria-disabled":r.disabled?!0:void 0,"aria-valuenow":r.angleDeg,"aria-valuetext":P,"aria-label":r.ariaLabel,"data-type":"pointer",className:`mz-round-slider-pointer ${r.disabled?"mz-round-slider-pointer-disabled":""}`,"data-angle":r.angleDeg,"data-id":r.id,"data-index":r.index,onMouseDown:F,onKeyDown:N,onMouseOver:de,onMouseOut:fe,tabIndex:0,cursor:r.disabled?"default":"pointer",style:J,children:[!a.pointerSVG&&Ae("circle",{cx:g/2,cy:g/2,r:g,fill:H,strokeWidth:D,stroke:h,style:{transition:"0.3s fill"}}),a.pointerSVG&&Ae("g",{children:a.pointerSVG})]})})},Qe=yt;import{Fragment as Ut,jsx as Je}from"react/jsx-runtime";var Ft=e=>{let{pointers:t,settings:r,svg:o,$svg:n,data:s,setPointer:a,selectedPointerId:l}=e;return Je(Ut,{children:t.pointers.map(c=>Je(Qe,{pointer:c,svg:o,settings:r,$svg:n,data:s,setPointer:a,selectedPointerId:l},c.id))})},je=Ft;var tt=e=>{let t=d(e.min,0),r=d(e.max,100),o=d(e.step,1),n=d(e.arrowStep,1),s=d(e.round,0),a=e.data||[];if(a.length>0){let p=a.findIndex(u=>u===t),i=a.findIndex(u=>u===r);t=p===-1?0:p,r=i===-1?a.length:i}else t>r&&(t=r+100);let l=d(e.pathStartAngle,0),c=d(e.pathEndAngle,360),g=v(l,360)===v(c,360),m=o*360/(r-t),f=n*360/(r-t);return{min:t,max:r,round:s,data:a,stepAngleDeg:m,arrowStepAngleDeg:f,isClosedShape:g}};import{useCallback as Gt,useEffect as Ie,useRef as le,useState as ue}from"react";var nt=(e,t,r,o,n,s)=>{if(!e.pointers||e.pointers.length<=0)return null;let a={radius:t,cx:r,cy:o,startAngleDeg:n,endAngleDeg:n,strokeDasharray:[0,0],strokeOffset:0};e.pointers.length===1?(a.startAngleDeg=n,a.endAngleDeg=e.pointers[0].angleDeg):(a.startAngleDeg=e.pointers[0].angleDeg,a.endAngleDeg=e.pointers[e.pointers.length-1].angleDeg);let l=Z(n,s);a.startAngleDeg>a.endAngleDeg&&(a.endAngleDeg+=360);let c=Z(a.startAngleDeg,a.endAngleDeg);c>l&&(c=360-c,[a.startAngleDeg,a.endAngleDeg]=[a.endAngleDeg,a.startAngleDeg]);let m=2*Math.PI*t,f=-(a.startAngleDeg/360)*m,p=c/360*m,i=m-p;return a.strokeDasharray=[p,i],a.strokeOffset=f,a};var ie=(e,t,r,o)=>{let n=e.getPercent();n<0&&(n=0),n>100&&(n=100);let s=t%360,a=r%360;if(ss){let c=(a-s+360)%360;return v(t+n*c/100,360)}else{let c=(s-a+360)%360;return v(t-n*c/100,360)}};import{Fragment as Yt,jsx as rt}from"react/jsx-runtime";var Xt=(e,t,r,o,n)=>{if(e)return A(t,$e);let s=A(r,xe);return o?A(n,s):s},qt=e=>{let{settings:t,pointers:r,$svg:o,svg:n,data:s,setPointer:a}=e,[l,c]=ue(null),[g,m]=ue(null),[f,p]=ue(xe),[i,u]=ue(!1),D=le(),h=le(null),b=le(0),C=le(0);Ie(()=>{p(Xt(t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,i,t.connectionBgColorHover))},[t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,t.connectionBgColorHover,i]),Ie(()=>{c(nt(r,n.radius,n.cx,n.cy,n.startAngleDeg,n.endAngleDeg))},[r,n.radius,n.cx,n.cy,n.startAngleDeg,n.endAngleDeg]);let R=M=>{if(!o||t.disabled||g&&g.isAnimating())return;let S=V(o,M.clientX,M.clientY,n.cx,n.cy,n.radius,n.radius),T=re(r.pointers,S,n.cx,n.cy,n.radius);T&&(t.animateOnClick?(h.current=T,b.current=T.angleDeg,C.current=S,g==null||g.start()):a(T,S))},I=Gt(M=>{if(!o||t.disabled||!t.rangeDragging)return;let S=Ze(r.pointers,n.startAngleDeg);if(!S)return;let[T,z]=S,F=V(o,M.clientX,M.clientY,n.cx,n.cy,n.radius,n.radius);if(D.current===void 0){D.current=F;return}let N=F-D.current;N===0||Math.abs(N){window.removeEventListener("mousemove",I),window.removeEventListener("mouseup",I),D.current=void 0},E=M=>{!t.rangeDragging||t.disabled||r.pointers.length<=1||(I(M),window.addEventListener("mousemove",I),window.addEventListener("mouseup",P))};Ie(()=>{if(g&&g.stop(),!t.animateOnClick){m(null);return}let M=ne({callback:S=>{if(!h.current)return;let T=ie(S,b.current,C.current,n.startAngleDeg);a(h.current,T)},duration:d(t.animationDuration,200)});m(M)},[t.animateOnClick,t.animationDuration]);let H=()=>{u(!0)},y=()=>{u(!1)};return rt(Yt,{children:!O(t.hideConnection,!1)&&l&&rt("circle",{"data-type":"connection",className:"mz-round-slider-connection",cx:l.cx,cy:l.cy,r:l.radius,strokeDasharray:l.strokeDasharray.join(" "),strokeDashoffset:l.strokeOffset,stroke:f,strokeWidth:n.thickness+1,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:t.disabled?"default":"pointer",onClick:R,onMouseDown:E,onMouseOver:H,onMouseOut:y,style:{transition:"0.2s stroke"}})})},ot=qt;import{useEffect as Wt,useState as Zt}from"react";import{Fragment as Jt,jsx as st}from"react/jsx-runtime";var Qt=e=>{let{settings:t,pointers:r,svg:o,data:n}=e,{cx:s,cy:a}=o,[l,c]=Zt("");Wt(()=>{let m=r.pointers.map(i=>q(n,i.angleDeg,o.startAngleDeg,o.endAngleDeg));m.sort((i,u)=>i.toString().localeCompare(u.toString(),"en",{numeric:!0}));let f=m.map(i=>`${t.textPrefix||""}${i}${t.textSuffix||""}`),p=A(t.textBetween," ");c(f.join(p))},[n,r.pointers,o.startAngleDeg,o.endAngleDeg,t.textPrefix,t.textSuffix,t.textBetween]);let g=O(t.hideText,!1);return st(Jt,{children:!g&&st("text",{"data-type":"text",className:"mz-round-slider-text",x:s+d(t.textOffsetX,0),y:a+d(t.textOffsetY,0),fill:A(t.textColor,ze),fontSize:d(t.textFontSize,16),fontFamily:t.textFontFamily,style:{userSelect:"none",whiteSpace:"pre"},textAnchor:"middle",children:l})})},at=Qt;import{useEffect as ut,useState as ct,Fragment as sn}from"react";var it=(e,t)=>{let r=d(e.ticksCount,0);r||(t.data&&t.data.length>0?r=t.data.length:r=t.max);let o=d(e.ticksHeight,10);return{ticksCount:r,enableTicks:O(e.enableTicks,!1),ticksWidth:d(e.ticksWidth,3),ticksHeight:o,longerTicksHeight:d(e.longerTicksHeight,o*2),ticksDistanceToPanel:d(e.ticksDistanceToPanel,0),tickValuesDistance:d(e.tickValuesDistance,15),ticksColor:A(e.ticksColor,Ge),tickValuesColor:A(e.tickValuesColor,Xe),tickValuesFontSize:d(e.tickValuesFontSize,12),ticksGroupSize:d(e.ticksGroupSize,10),longerTickValuesOnly:O(e.longerTickValuesOnly,!0),showTickValues:O(e.showTickValues,!0)}},lt=(e,t,r,o,n,s)=>{let a=[],l=Math.abs(o-r),c=t===0?0:l/t,g=t;s.isClosedShape||g++;for(let m=0;m0){let T=Math.round(S);S=s.data[T]}else S=w(S,s.round);E=(S!=null?S:"").toString()}let H=0,y=0,M=E!==void 0;if(M){let S=d(h+e.tickValuesDistance,h*1.5),T=ee(b,S);H=i+T[0],y=u+T[1]}a.push({x:i,y:u,x1:I,y1:P,textX:H,textY:y,isLonger:D,tickValue:E,showText:M})}return a};import{Fragment as ln,jsx as Te,jsxs as gt}from"react/jsx-runtime";var an=e=>{let{settings:t,svg:r,data:o}=e,[n,s]=ct(null),[a,l]=ct([]);return ut(()=>{s(it(t,o))},[t,o]),ut(()=>{if(!n)return;let c=r.endAngleDeg;c{let{x:m,y:f,x1:p,y1:i,textX:u,textY:D,showText:h}=c;return gt(sn,{children:[Te("line",{x1:m,y1:f,x2:p,y2:i,strokeWidth:n.ticksWidth,stroke:n.ticksColor,"data-type":"tick",className:"mz-round-slider-tick"}),h&>("text",{"data-type":"tick-text",className:"mz-round-slider-tick-text",x:u,y:D,textAnchor:"middle",dominantBaseline:"middle",fill:n.tickValuesColor,fontSize:n.tickValuesFontSize,fontFamily:t.tickValuesFontFamily,style:{userSelect:"none",whiteSpace:"pre"},children:[t.tickValuesPrefix,c.tickValue,t.tickValuesSuffix]})]},g)})})})},mt=an;import{useEffect as pt,useState as Ee,useRef as Me}from"react";import{useEffect as dt,useState as ce}from"react";import{Fragment as cn,jsx as Ce,jsxs as ft}from"react/jsx-runtime";var un=e=>{let{svg:t,maskId:r,settings:o,circle:n}=e,[s,a]=ce([0,0]),[l,c]=ce([0,0]),[g,m]=ce(0),[f,p]=ce(!1);return dt(()=>{if(v(t.startAngleDeg,360)===v(t.endAngleDeg,360)){p(!0);return}p(O(o.pathInnerBgFull,!1))},[o.pathInnerBgFull,t.startAngleDeg,t.endAngleDeg]),dt(()=>{let i=k(t.startAngleDeg,0,Math.PI*2,0,Math.PI);a(L([t.cx,t.cy],_(i),t.radius));let u=k(t.endAngleDeg,0,Math.PI*2,0,Math.PI);c(L([t.cx,t.cy],_(u),t.radius));let D=t.endAngleDeg-t.startAngleDeg<=180?1:0;m(D)},[t.cx,t.cy,t.endAngleDeg,t.radius,t.startAngleDeg]),ft(cn,{children:[!f&&ft("mask",{id:r,children:[Ce("path",{fill:"black",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 1 ${g} 0 ${l[0]} ${l[1]}`}),Ce("path",{fill:"white",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 0 ${g===1?0:1} 1 ${l[0]} ${l[1]}`})]}),Ce("circle",{strokeDasharray:n.strokeDasharray,strokeDashoffset:n.strokeOffset,cx:t.cx,cy:t.cy,r:t.radius,stroke:"transparent",strokeWidth:t.thickness,fill:o.pathInnerBgColor,shapeRendering:"geometricPrecision",strokeLinecap:"round","data-type":"path-inner",className:"mz-round-slider-path-inner",mask:f?"":`url(#${r})`})]})},ht=un;import{jsx as Pe,jsxs as mn}from"react/jsx-runtime";var gn=e=>{let{settings:t,pointers:r,$svg:o,svg:n,setPointer:s}=e,[a,l]=Ee(null),[c]=Ee(Fe()),[g,m]=Ee({strokeDasharray:"0 1000000",strokeOffset:0}),f=Me(null),p=Me(0),i=Me(0);pt(()=>{m(qe(n.startAngleDeg,n.endAngleDeg,n.radius))},[n.startAngleDeg,n.endAngleDeg,n.radius]);let u=D=>{if(!o||t.disabled||a&&a.isAnimating())return;let h=V(o,D.clientX,D.clientY,n.cx,n.cy,n.radius,n.radius),b=re(r.pointers,h,n.cx,n.cy,n.radius);b&&(t.animateOnClick?(f.current=b,p.current=b.angleDeg,i.current=h,a==null||a.start()):s(b,h))};return pt(()=>{if(a&&a.stop(),!t.animateOnClick){l(null);return}let D=ne({callback:h=>{if(!f.current)return;let b=ie(h,p.current,i.current,n.startAngleDeg);s(f.current,b)},duration:d(t.animationDuration,200)});l(D)},[t.animateOnClick,t.animationDuration]),mn("g",{onClick:u,children:[t.pathInnerBgColor&&Pe(ht,{maskId:c,settings:t,svg:n,circle:g}),n.border>0&&Pe("circle",{strokeDasharray:g.strokeDasharray,strokeDashoffset:g.strokeOffset,cx:n.cx,cy:n.cy,r:n.radius,stroke:A(t.pathBorderColor,Ve),strokeWidth:n.thickness+n.border*2,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path-border",className:"mz-round-slider-path-border"}),Pe("circle",{strokeDasharray:g.strokeDasharray,strokeDashoffset:g.strokeOffset,cx:n.cx,cy:n.cy,r:n.radius,stroke:A(t.pathBgColor,He),strokeWidth:n.thickness,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path",className:"mz-round-slider-path"})]})},bt=gn;import{Fragment as bn,jsx as $,jsxs as pn}from"react/jsx-runtime";var To=e=>{let[t,r]=me(null),[o,n]=me(null),[s,a]=me(null),[l,c]=me(""),g=Dt(null),m=Dt(null);ge(()=>{let i=tt(e);JSON.stringify(t)!==JSON.stringify(i)&&r(i)},[t,e]),ge(()=>{a(We(e,t))},[e.pointerRadius,e.pathStartAngle,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pointers,e.pointerRadius,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pathStartAngle,e.pathEndAngle,t]),ge(()=>{if(!s)return;let i=d(e.pathStartAngle,0),u=d(e.pathEndAngle,360);u<=i&&(u+=360),n(Ue(d(e.pathRadius,150),d(e.pathThickness,5),d(e.pathBorder,0),s.maxRadius,i,u))},[e.pathRadius,e.pathThickness,e.pathBorder,e.pathStartAngle,e.pathEndAngle,s]),ge(()=>{let i=u=>{u.target.closest('[data-type="pointer"]')||c("")};return document.addEventListener("mousedown",i),()=>{document.removeEventListener("mousedown",i)}},[]);let f=(i,u)=>{if(e.disabled||!s.pointers||!i||i.disabled)return;if(u=ve(u,t.stepAngleDeg,o.startAngleDeg,o.endAngleDeg),t.isClosedShape&&v(u,360)===v(o.endAngleDeg,360)&&(u=o.startAngleDeg),i.angleDeg===u){p(i,u,!1);return}if(!e.pointersOverlap){let h,b;if(t.isClosedShape){let C=v(i.index-1,s.pointers.length),R=v(i.index+1,s.pointers.length),I=s.pointers[C],P=s.pointers[R];if(h=I.angleDeg,b=P.angleDeg,s.pointers.length===2&&h===b){let E=h;if(g.current===null)g.current=u;else{let y=E-150,M=E-.001;y<0&&(y+=360),M<0&&(M+=360);let S=U(E+.001,E+150,u),T=U(y,M,g.current),z=S&&T,F=E-150,N=E-.001;F<0&&(F+=360),N<0&&(N+=360);let de=U(F,N,u),fe=U(E+.001,E+150,g.current);if(z||de&&fe){p(i,E,!0);return}u!==E&&(g.current=u)}}}else h=i.index===0?o.startAngleDeg:s.pointers[i.index-1].angleDeg,b=i.index===s.pointers.length-1?o.endAngleDeg:s.pointers[i.index+1].angleDeg;b<=h&&(b+=360),U(h,b,u)||(u=oe(h,b,u,o.cx,o.cy,o.radius))}p(i,u,i.angleDeg!==u)},p=(i,u,D)=>{var b;if(D){let C=K({},s);if(C.pointers=[...s.pointers],C.pointers[i.index].prevAngleDeg=C.pointers[i.index].angleDeg,C.pointers[i.index].angleDeg=u,s.pointers=C.pointers,a(C),typeof e.onChange=="function"){let R=C.pointers.map(I=>{let P=q(t,I.angleDeg,o.startAngleDeg,o.endAngleDeg);return{radius:I.radius,value:P,bgColor:I.bgColor,bgColorSelected:I.bgColorSelected,bgColorDisabled:I.bgColorDisabled,border:I.border,borderColor:I.borderColor,disabled:I.disabled,ariaLabel:I.ariaLabel}});e.onChange(R)}}c(i.id);let h=(b=m.current)==null?void 0:b.querySelector(`[data-id="${i.id}"]`);h&&h.focus()};return $(bn,{children:o&&pn("svg",{ref:m,xmlns:"http://www.w3.org/2000/svg",width:o.size,height:o.size,tabIndex:0,focusable:!0,"aria-disabled":e.disabled?!0:void 0,style:e.svgBgColor?_e(K({},J),{backgroundColor:e.svgBgColor}):J,className:`mz-round-slider ${e.disabled?"mz-round-slider-disabled":""}`,children:[e.SvgDefs&&$("defs",{children:e.SvgDefs}),$(bt,{settings:e,pointers:s,svg:o,$svg:m.current,setPointer:f}),$(mt,{settings:e,svg:o,data:t}),$(ot,{settings:e,pointers:s,svg:o,$svg:m.current,data:t,setPointer:f}),$(je,{settings:e,pointers:s,svg:o,$svg:m.current,data:t,setPointer:f,selectedPointerId:l}),$(at,{settings:e,pointers:s,svg:o,data:t})]})})};export{To as RoundSlider}; +var xt=Object.defineProperty,vt=Object.defineProperties;var At=Object.getOwnPropertyDescriptors;var ke=Object.getOwnPropertySymbols;var It=Object.prototype.hasOwnProperty,St=Object.prototype.propertyIsEnumerable;var Re=(e,t,r)=>t in e?xt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,K=(e,t)=>{for(var r in t||(t={}))It.call(t,r)&&Re(e,r,t[r]);if(ke)for(var r of ke(t))St.call(t,r)&&Re(e,r,t[r]);return e},_e=(e,t)=>vt(e,At(t));import{useEffect as ge,useRef as Dt,useState as me}from"react";var Tt=Math.pow,w=(e,t=1/0)=>{if(t===1/0)return e;t<0&&(t=0);let r=Tt(10,t);return Math.round(e*r)/r},D=(e,t)=>(e%t+t)%t,k=(e,t,r,o,n)=>(n-o)*(e-t)/(r-t)+o;var Le=e=>!isNaN(parseFloat(e))&&isFinite(e);var we=(e,t=1/0)=>{let r=e*(180/Math.PI);return w(r,t)},_=(e,t=1/0)=>{let r=e*(Math.PI/180);return w(r,t)};var Oe=(e,t,r=1/0)=>{let o=[];for(let n=0;nOe(e,t,r);var Ct=(e,t,r=1/0)=>{let o=[];for(let n=0;nCt(e,t,r);var Ne=(e,t=1/0)=>{let r=0;for(let o=0;o{let o=Oe(e,t);return Ne(o,r)};var Et=(e,t=1/0)=>{let r=Ne(e),o=[];for(let n=0;nEt(e,t);var L=(e,t,r)=>(t=t%Math.PI*2,[e[0]+Math.cos(t)*r,e[1]+Math.sin(t)*r]);var Fe=()=>Math.random().toString(36).substring(2)+new Date().getTime().toString(36);var ne=e=>{let t=e.duration!==void 0?e.duration:1/0,r,o,n,s,a=!1,l,c=()=>{r=void 0,n=void 0,s=void 0,a=!1,o!==void 0&&window.cancelAnimationFrame(o)},g=()=>{c(),u()},m=()=>{a=!1},h=()=>{a=!0},p=P=>{r===void 0&&(r=P),n=P-r,a&&s!==P&&typeof e.callback=="function"&&e.callback(I()),n<=t?(s=P,o=window.requestAnimationFrame(p)):c()},i=(P,E)=>{g(),typeof e.resizeCallback=="function"&&e.resizeCallback(P,E)},u=()=>{r=void 0,n=void 0,s=void 0,a=!0,e.restartOnResize&&window.ResizeObserver&&l===void 0?(l=new ResizeObserver(i),l.observe(document.body,{box:"border-box"})):o=window.requestAnimationFrame(p)},x=()=>n,d=()=>a,b=()=>r,C=()=>{if(!(t===1/0||n===void 0))return n*100/t},R=()=>l,I=()=>({start:u,stop:c,pause:m,resume:h,restart:g,isAnimating:d,getElapsedTime:x,getStartTime:b,getPercent:C,getResizeObserver:R});return I()};var Ue=(e,t,r,o,n,s)=>{let a=t+r*2,l=Math.max(0,o*2-a),c=e*2+a+l,[g,m]=Mt(e,o,t,r);return{cx:g,cy:m,radius:e,size:c,thickness:t,border:r,startAngleDeg:n,endAngleDeg:s}},Mt=(e,t,r,o)=>{let n=Pt(e,t,r,o),s=w(n/2,2);return[s,s]},Pt=(e,t,r,o)=>{let n=r+o*2,s=Math.max(0,t*2-n);return e*2+n+s};var He="#efefef";var Ve="#444444";var W="#163a86",pe="#000",be="#a8a8a8";var De="#000",xe="#5daed2",$e="#97b0bb",ze="#000";var Ge="#efefef",Xe="#000";var f=(e,t)=>Le(e)?Number(e):t,A=(e,t)=>e==null?t:e,O=(e,t)=>e==null?t:e;var U=(e,t,r)=>(e>t&&(t+=360),r>=e&&r<=t||r+360>=e&&r+360<=t),Z=(e,t)=>{t0?360:o},qe=(e,t,r)=>{e>t&&(t+=360);let o=2*Math.PI*r,n=t-e,s=-(e/360)*o,a=n/360*o,l=o-a;return{strokeDasharray:[a,l].join(" "),strokeOffset:s}};var V=(e,t,r,o,n,s,a)=>{let{left:l,top:c}=e.getBoundingClientRect(),g=[t-l,r-c],m=ye(g,[o,n]),h=Math.atan2(m[1]/a,m[0]/s);return h<0&&(h+=2*Math.PI),we(h)},q=(e,t,r,o)=>{o0){let s=Math.round(n);n=e.data[s]}else n=w(n,e.round);return n},kt=(e,t,r,o)=>{let n;if(o0){let s=e.data.findIndex(a=>a===t);n=s===-1?0:s}else n=typeof t!="number"?e.min:t;return D(k(n,e.min,e.max,r,o),360)},Rt=(e,t)=>{if(!e||!e.pointers||e.pointers.length<0||!t){let o=D(f(e.pathStartAngle,0),360),n=A(e.pointerBgColor,W),s=A(e.pointerBgColorSelected,pe),a=A(e.pointerBgColorDisabled,be),l=A(e.pointerBgColorHover,s);return[{id:"0",index:0,radius:f(e.pointerRadius,10),angleDeg:o,prevAngleDeg:o,bgColor:n,bgColorSelected:s,bgColorDisabled:a,bgColorHover:l,border:f(e.pointerBorder,0),borderColor:A(e.pointerBorderColor,De),disabled:!!e.disabled}]}let r=[];for(let o=0;o{let r=Rt(e,t);return{pointers:r,maxRadius:_t(r)}},_t=e=>{if(e.length<=0)return 0;let t=-1/0;for(let r of e)t=Math.max(t,Math.max(0,r.radius+r.border/2));return t},re=(e,t,r,o,n)=>{if(!e||e.length<=0)return null;if(e.length===1)return e[0];let s=k(_(t),0,Math.PI*2,0,Math.PI),a=L([r,o],s,n),l,c=null,g=e.filter(m=>!m.disabled);for(let m of g){let h=k(_(m.angleDeg),0,Math.PI*2,0,Math.PI),p=L([r,o],h,n),i=te(a,p);(l===void 0||i{let a=k(_(r),0,Math.PI*2,0,Math.PI),l=L([o,n],a,s),c=k(_(e),0,Math.PI*2,0,Math.PI),g=L([o,n],c,s),m=k(_(t),0,Math.PI*2,0,Math.PI),h=L([o,n],m,s),p=te(l,g),i=te(l,h);return p<=i?e:t},Ze=(e,t)=>{if(!e||e.length<=0)return null;let r,o,n=null,s=null;for(let a of e){let l=Z(t,a.angleDeg);(r===void 0||lo)&&(s=a,o=l)}return n===null||s===null?null:[n,s]},ve=(e,t,r,o)=>D(e,360)===D(r,360)||D(e,360)===D(o,360)?e:t===0?0:Math.round(e/t)*t;import{useEffect as se,useState as ae,useRef as Lt,useCallback as wt}from"react";var J={outline:"none"};import{Fragment as Bt,jsx as Ae,jsxs as Nt}from"react/jsx-runtime";var Ot=(e,t,r,o,n,s,a)=>e.disabled?n:a?s:e.id===t?o:r,yt=e=>{let t=Lt(null),{pointer:r,svg:o,$svg:n,data:s,settings:a,setPointer:l,selectedPointerId:c}=e,{radius:g,angleDeg:m,bgColor:h,bgColorSelected:p,bgColorDisabled:i,bgColorHover:u,border:x,borderColor:d}=e.pointer,{cx:b,cy:C}=o,[R,I]=ae(null),[P,E]=ae(""),[H,y]=ae(W),[M,S]=ae(!1);se(()=>{y(Ot(r,c,h,p,i,u,M))},[r,c,h,p,i,u,M]),se(()=>{let v=q(s,r.angleDeg,o.startAngleDeg,o.endAngleDeg);E(v===void 0?"":v.toString())},[s,r.angleDeg,o.startAngleDeg,o.endAngleDeg]),se(()=>{let v=k(_(m),0,Math.PI*2,0,Math.PI),G=L([b,C],v,o.radius);I(G)},[m,b,C,o.radius]);let T=wt(v=>{if(!n||a.disabled||r.disabled)return;let G=v.type.indexOf("mouse")!==-1?v.clientX:v.touches[0].clientX,j=v.type.indexOf("mouse")!==-1?v.clientY:v.touches[0].clientY,B=V(n,G,j,o.cx,o.cy,o.radius,o.radius),Y;U(o.startAngleDeg,o.endAngleDeg,B)?Y=B:Y=oe(o.startAngleDeg,o.endAngleDeg,r.angleDeg,o.cx,o.cy,o.radius),l(r,Y)},[n,r,l,o.cx,o.cy,o.endAngleDeg,o.radius,o.startAngleDeg,a.disabled]),z=()=>{window.removeEventListener("mousemove",T),window.removeEventListener("mouseup",T)},F=v=>{a.disabled||r.disabled||(T(v),window.addEventListener("mousemove",T),window.addEventListener("mouseup",z))},N=v=>{if(!(a.disabled||r.disabled||a.keyboardDisabled))switch(v.key){case"ArrowLeft":{v.preventDefault(),l(r,r.angleDeg+s.arrowStepAngleDeg);break}case"ArrowRight":{v.preventDefault(),l(r,r.angleDeg-s.arrowStepAngleDeg);break}case"ArrowUp":{v.preventDefault(),l(r,r.angleDeg-s.arrowStepAngleDeg);break}case"ArrowDown":{v.preventDefault(),l(r,r.angleDeg+s.arrowStepAngleDeg);break}}};se(()=>{let v=t.current,G=B=>{a.disabled||r.disabled||(B.preventDefault(),B.stopPropagation(),T(B))},j=B=>{if(a.disabled||r.disabled||a.mousewheelDisabled||document.activeElement!==v)return;B.stopPropagation(),B.preventDefault();let Y=B.deltaY<0,he;Y?he=r.angleDeg+s.arrowStepAngleDeg:he=r.angleDeg-s.arrowStepAngleDeg,l(r,he)};return v==null||v.addEventListener("touchmove",G,{passive:!1}),document.addEventListener("wheel",j,{passive:!1}),()=>{v==null||v.removeEventListener("touchmove",G),document.removeEventListener("wheel",j)}},[R,T,s.arrowStepAngleDeg,r,l,a.disabled,a.mousewheelDisabled]);let de=()=>{S(!0)},fe=()=>{S(!1)};return Ae(Bt,{children:R&&Nt("g",{ref:t,transform:`translate(${R[0]-g/2}, ${R[1]-g/2})`,role:"slider","aria-disabled":r.disabled?!0:void 0,"aria-valuenow":r.angleDeg,"aria-valuetext":P,"aria-label":r.ariaLabel,"data-type":"pointer",className:`mz-round-slider-pointer ${r.disabled?"mz-round-slider-pointer-disabled":""}`,"data-angle":r.angleDeg,"data-id":r.id,"data-index":r.index,onMouseDown:F,onKeyDown:N,onMouseOver:de,onMouseOut:fe,tabIndex:0,cursor:r.disabled?"default":"pointer",style:J,children:[!a.pointerSVG&&Ae("circle",{cx:g/2,cy:g/2,r:g,fill:H,strokeWidth:x,stroke:d,style:{transition:"0.3s fill"}}),a.pointerSVG&&Ae("g",{children:a.pointerSVG})]})})},Qe=yt;import{Fragment as Ut,jsx as Je}from"react/jsx-runtime";var Ft=e=>{let{pointers:t,settings:r,svg:o,$svg:n,data:s,setPointer:a,selectedPointerId:l}=e;return Je(Ut,{children:t.pointers.map(c=>Je(Qe,{pointer:c,svg:o,settings:r,$svg:n,data:s,setPointer:a,selectedPointerId:l},c.id))})},je=Ft;var tt=e=>{let t=f(e.min,0),r=f(e.max,100),o=f(e.step,1),n=f(e.arrowStep,1),s=f(e.round,0),a=e.data||[];if(a.length>0){let p=a.findIndex(u=>u===t),i=a.findIndex(u=>u===r);t=p===-1?0:p,r=i===-1?a.length:i}else t>r&&(t=r+100);let l=f(e.pathStartAngle,0),c=f(e.pathEndAngle,360),g=D(l,360)===D(c,360),m=o*360/(r-t),h=n*360/(r-t);return{min:t,max:r,round:s,data:a,stepAngleDeg:m,arrowStepAngleDeg:h,isClosedShape:g}};import{useCallback as Gt,useEffect as Ie,useRef as le,useState as ue}from"react";var nt=(e,t,r,o,n,s)=>{if(!e.pointers||e.pointers.length<=0)return null;let a={radius:t,cx:r,cy:o,startAngleDeg:n,endAngleDeg:n,strokeDasharray:[0,0],strokeOffset:0};e.pointers.length===1?(a.startAngleDeg=n,a.endAngleDeg=e.pointers[0].angleDeg):(a.startAngleDeg=e.pointers[0].angleDeg,a.endAngleDeg=e.pointers[e.pointers.length-1].angleDeg);let l=Z(n,s);a.startAngleDeg>a.endAngleDeg&&(a.endAngleDeg+=360);let c=Z(a.startAngleDeg,a.endAngleDeg);c>l&&(c=360-c,[a.startAngleDeg,a.endAngleDeg]=[a.endAngleDeg,a.startAngleDeg]);let m=2*Math.PI*t,h=-(a.startAngleDeg/360)*m,p=c/360*m,i=m-p;return a.strokeDasharray=[p,i],a.strokeOffset=h,a};var ie=(e,t,r,o)=>{let n=e.getPercent();n<0&&(n=0),n>100&&(n=100);let s=t%360,a=r%360;if(ss){let c=(a-s+360)%360;return D(t+n*c/100,360)}else{let c=(s-a+360)%360;return D(t-n*c/100,360)}};import{Fragment as Yt,jsx as rt}from"react/jsx-runtime";var Xt=(e,t,r,o,n)=>{if(e)return A(t,$e);let s=A(r,xe);return o?A(n,s):s},qt=e=>{let{settings:t,pointers:r,$svg:o,svg:n,data:s,setPointer:a}=e,[l,c]=ue(null),[g,m]=ue(null),[h,p]=ue(xe),[i,u]=ue(!1),x=le(),d=le(null),b=le(0),C=le(0);Ie(()=>{p(Xt(t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,i,t.connectionBgColorHover))},[t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,t.connectionBgColorHover,i]),Ie(()=>{c(nt(r,n.radius,n.cx,n.cy,n.startAngleDeg,n.endAngleDeg))},[r,n.radius,n.cx,n.cy,n.startAngleDeg,n.endAngleDeg]);let R=M=>{if(!o||t.disabled||g&&g.isAnimating())return;let S=V(o,M.clientX,M.clientY,n.cx,n.cy,n.radius,n.radius),T=re(r.pointers,S,n.cx,n.cy,n.radius);T&&(t.animateOnClick?(d.current=T,b.current=T.angleDeg,C.current=S,g==null||g.start()):a(T,S))},I=Gt(M=>{if(!o||t.disabled||!t.rangeDragging)return;let S=Ze(r.pointers,n.startAngleDeg);if(!S)return;let[T,z]=S,F=V(o,M.clientX,M.clientY,n.cx,n.cy,n.radius,n.radius);if(x.current===void 0){x.current=F;return}let N=F-x.current;N===0||Math.abs(N){window.removeEventListener("mousemove",I),window.removeEventListener("mouseup",I),x.current=void 0},E=M=>{!t.rangeDragging||t.disabled||r.pointers.length<=1||(I(M),window.addEventListener("mousemove",I),window.addEventListener("mouseup",P))};Ie(()=>{if(g&&g.stop(),!t.animateOnClick){m(null);return}let M=ne({callback:S=>{if(!d.current)return;let T=ie(S,b.current,C.current,n.startAngleDeg);a(d.current,T)},duration:f(t.animationDuration,200)});m(M)},[t.animateOnClick,t.animationDuration]);let H=()=>{u(!0)},y=()=>{u(!1)};return rt(Yt,{children:!O(t.hideConnection,!1)&&l&&rt("circle",{"data-type":"connection",className:"mz-round-slider-connection",cx:l.cx,cy:l.cy,r:l.radius,strokeDasharray:l.strokeDasharray.join(" "),strokeDashoffset:l.strokeOffset,stroke:h,strokeWidth:n.thickness+1,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:t.disabled?"default":"pointer",onClick:R,onMouseDown:E,onMouseOver:H,onMouseOut:y,style:{transition:"0.2s stroke"}})})},ot=qt;import{useEffect as Wt,useState as Zt}from"react";import{Fragment as Jt,jsx as st}from"react/jsx-runtime";var Qt=e=>{let{settings:t,pointers:r,svg:o,data:n}=e,{cx:s,cy:a}=o,[l,c]=Zt("");Wt(()=>{let m=r.pointers.map(i=>q(n,i.angleDeg,o.startAngleDeg,o.endAngleDeg));m.sort((i,u)=>i.toString().localeCompare(u.toString(),"en",{numeric:!0}));let h=m.map(i=>`${t.textPrefix||""}${i}${t.textSuffix||""}`),p=A(t.textBetween," ");c(h.join(p))},[n,r.pointers,o.startAngleDeg,o.endAngleDeg,t.textPrefix,t.textSuffix,t.textBetween]);let g=O(t.hideText,!1);return st(Jt,{children:!g&&st("text",{"data-type":"text",className:"mz-round-slider-text",x:s+f(t.textOffsetX,0),y:a+f(t.textOffsetY,0),fill:A(t.textColor,ze),fontSize:f(t.textFontSize,16),fontFamily:t.textFontFamily,style:{userSelect:"none",whiteSpace:"pre"},textAnchor:"middle",children:l})})},at=Qt;import{useEffect as ut,useState as ct,Fragment as sn}from"react";var it=(e,t)=>{let r=f(e.ticksCount,0);r||(t.data&&t.data.length>0?r=t.data.length:r=t.max);let o=f(e.ticksHeight,10);return{ticksCount:r,enableTicks:O(e.enableTicks,!1),ticksWidth:f(e.ticksWidth,3),ticksHeight:o,longerTicksHeight:f(e.longerTicksHeight,o*2),ticksDistanceToPanel:f(e.ticksDistanceToPanel,0),tickValuesDistance:f(e.tickValuesDistance,15),ticksColor:A(e.ticksColor,Ge),tickValuesColor:A(e.tickValuesColor,Xe),tickValuesFontSize:f(e.tickValuesFontSize,12),ticksGroupSize:f(e.ticksGroupSize,10),longerTickValuesOnly:O(e.longerTickValuesOnly,!0),showTickValues:O(e.showTickValues,!0)}},lt=(e,t,r,o,n,s)=>{let a=[],l=Math.abs(o-r),c=t===0?0:l/t,g=t;s.isClosedShape||g++;for(let m=0;m0){let T=Math.round(S);S=s.data[T]}else S=w(S,s.round);E=(S!=null?S:"").toString()}let H=0,y=0,M=E!==void 0;if(M){let S=f(d+e.tickValuesDistance,d*1.5),T=ee(b,S);H=i+T[0],y=u+T[1]}a.push({x:i,y:u,x1:I,y1:P,textX:H,textY:y,isLonger:x,tickValue:E,showText:M})}return a};import{Fragment as ln,jsx as Te,jsxs as gt}from"react/jsx-runtime";var an=e=>{let{settings:t,svg:r,data:o}=e,[n,s]=ct(null),[a,l]=ct([]);return ut(()=>{s(it(t,o))},[t,o]),ut(()=>{if(!n)return;let c=r.endAngleDeg;c{let{x:m,y:h,x1:p,y1:i,textX:u,textY:x,showText:d}=c;return gt(sn,{children:[Te("line",{x1:m,y1:h,x2:p,y2:i,strokeWidth:n.ticksWidth,stroke:n.ticksColor,"data-type":"tick",className:"mz-round-slider-tick"}),d&>("text",{"data-type":"tick-text",className:"mz-round-slider-tick-text",x:u,y:x,textAnchor:"middle",dominantBaseline:"middle",fill:n.tickValuesColor,fontSize:n.tickValuesFontSize,fontFamily:t.tickValuesFontFamily,style:{userSelect:"none",whiteSpace:"pre"},children:[t.tickValuesPrefix,c.tickValue,t.tickValuesSuffix]})]},g)})})})},mt=an;import{useEffect as pt,useState as Ee,useRef as Me}from"react";import{useEffect as dt,useState as ce}from"react";import{Fragment as cn,jsx as Ce,jsxs as ft}from"react/jsx-runtime";var un=e=>{let{svg:t,maskId:r,settings:o,circle:n}=e,[s,a]=ce([0,0]),[l,c]=ce([0,0]),[g,m]=ce(0),[h,p]=ce(!1);return dt(()=>{if(D(t.startAngleDeg,360)===D(t.endAngleDeg,360)){p(!0);return}p(O(o.pathInnerBgFull,!1))},[o.pathInnerBgFull,t.startAngleDeg,t.endAngleDeg]),dt(()=>{let i=k(t.startAngleDeg,0,Math.PI*2,0,Math.PI);a(L([t.cx,t.cy],_(i),t.radius));let u=k(t.endAngleDeg,0,Math.PI*2,0,Math.PI);c(L([t.cx,t.cy],_(u),t.radius));let x=t.endAngleDeg-t.startAngleDeg<=180?1:0;m(x)},[t.cx,t.cy,t.endAngleDeg,t.radius,t.startAngleDeg]),ft(cn,{children:[!h&&ft("mask",{id:r,children:[Ce("path",{fill:"black",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 1 ${g} 0 ${l[0]} ${l[1]}`}),Ce("path",{fill:"white",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 0 ${g===1?0:1} 1 ${l[0]} ${l[1]}`})]}),Ce("circle",{strokeDasharray:n.strokeDasharray,strokeDashoffset:n.strokeOffset,cx:t.cx,cy:t.cy,r:t.radius,stroke:"transparent",strokeWidth:t.thickness,fill:o.pathInnerBgColor,shapeRendering:"geometricPrecision",strokeLinecap:"round","data-type":"path-inner",className:"mz-round-slider-path-inner",mask:h?"":`url(#${r})`})]})},ht=un;import{jsx as Pe,jsxs as mn}from"react/jsx-runtime";var gn=e=>{let{settings:t,pointers:r,$svg:o,svg:n,setPointer:s}=e,[a,l]=Ee(null),[c]=Ee(Fe()),[g,m]=Ee({strokeDasharray:"0 1000000",strokeOffset:0}),h=Me(null),p=Me(0),i=Me(0);pt(()=>{m(qe(n.startAngleDeg,n.endAngleDeg,n.radius))},[n.startAngleDeg,n.endAngleDeg,n.radius]);let u=x=>{if(!o||t.disabled||a&&a.isAnimating())return;let d=V(o,x.clientX,x.clientY,n.cx,n.cy,n.radius,n.radius),b=re(r.pointers,d,n.cx,n.cy,n.radius);b&&(t.animateOnClick?(h.current=b,p.current=b.angleDeg,i.current=d,a==null||a.start()):s(b,d))};return pt(()=>{if(a&&a.stop(),!t.animateOnClick){l(null);return}let x=ne({callback:d=>{if(!h.current)return;let b=ie(d,p.current,i.current,n.startAngleDeg);s(h.current,b)},duration:f(t.animationDuration,200)});l(x)},[t.animateOnClick,t.animationDuration]),mn("g",{onClick:u,children:[t.pathInnerBgColor&&Pe(ht,{maskId:c,settings:t,svg:n,circle:g}),n.border>0&&Pe("circle",{strokeDasharray:g.strokeDasharray,strokeDashoffset:g.strokeOffset,cx:n.cx,cy:n.cy,r:n.radius,stroke:A(t.pathBorderColor,Ve),strokeWidth:n.thickness+n.border*2,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path-border",className:"mz-round-slider-path-border"}),Pe("circle",{strokeDasharray:g.strokeDasharray,strokeDashoffset:g.strokeOffset,cx:n.cx,cy:n.cy,r:n.radius,stroke:A(t.pathBgColor,He),strokeWidth:n.thickness,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path",className:"mz-round-slider-path"})]})},bt=gn;import{Fragment as bn,jsx as $,jsxs as pn}from"react/jsx-runtime";var To=e=>{let[t,r]=me(null),[o,n]=me(null),[s,a]=me(null),[l,c]=me(""),g=Dt(null),m=Dt(null);ge(()=>{let i=tt(e);JSON.stringify(t)!==JSON.stringify(i)&&r(i)},[t,e]),ge(()=>{a(We(e,t))},[e.pointerRadius,e.pathStartAngle,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pointers,e.pointerRadius,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pathStartAngle,e.pathEndAngle,t]),ge(()=>{if(!s)return;let i=f(e.pathStartAngle,0),u=f(e.pathEndAngle,360);u<=i&&(u+=360),n(Ue(f(e.pathRadius,150),f(e.pathThickness,5),f(e.pathBorder,0),s.maxRadius,i,u))},[e.pathRadius,e.pathThickness,e.pathBorder,e.pathStartAngle,e.pathEndAngle,s]),ge(()=>{let i=u=>{u.target.closest('[data-type="pointer"]')||c("")};return document.addEventListener("mousedown",i),()=>{document.removeEventListener("mousedown",i)}},[]);let h=(i,u)=>{if(e.disabled||!s.pointers||!i||i.disabled)return;if(u=ve(u,t.stepAngleDeg,o.startAngleDeg,o.endAngleDeg),t.isClosedShape&&D(u,360)===D(o.endAngleDeg,360)&&(u=o.startAngleDeg),i.angleDeg===u){p(i,u,!1);return}if(!e.pointersOverlap){let d,b;if(t.isClosedShape){let C=D(i.index-1,s.pointers.length),R=D(i.index+1,s.pointers.length),I=s.pointers[C],P=s.pointers[R];if(d=I.angleDeg,b=P.angleDeg,s.pointers.length===2&&d===b){let E=d;if(g.current===null)g.current=u;else{let y=E-150,M=E-.001;y<0&&(y+=360),M<0&&(M+=360);let S=U(E+.001,E+150,u),T=U(y,M,g.current),z=S&&T,F=E-150,N=E-.001;F<0&&(F+=360),N<0&&(N+=360);let de=U(F,N,u),fe=U(E+.001,E+150,g.current);if(z||de&&fe){p(i,E,!0);return}u!==E&&(g.current=u)}}}else d=i.index===0?o.startAngleDeg:s.pointers[i.index-1].angleDeg,b=i.index===s.pointers.length-1?o.endAngleDeg:s.pointers[i.index+1].angleDeg;b<=d?b+=360:D(d,360)<=D(b,360)&&(d=D(d,360),b=D(b,360)),U(d,b,u)||(u=oe(d,b,u,o.cx,o.cy,o.radius))}p(i,u,i.angleDeg!==u)},p=(i,u,x)=>{var b;if(x){let C=K({},s);if(C.pointers=[...s.pointers],C.pointers[i.index].prevAngleDeg=C.pointers[i.index].angleDeg,C.pointers[i.index].angleDeg=u,s.pointers=C.pointers,a(C),typeof e.onChange=="function"){let R=C.pointers.map(I=>{let P=q(t,I.angleDeg,o.startAngleDeg,o.endAngleDeg);return{radius:I.radius,value:P,bgColor:I.bgColor,bgColorSelected:I.bgColorSelected,bgColorDisabled:I.bgColorDisabled,border:I.border,borderColor:I.borderColor,disabled:I.disabled,ariaLabel:I.ariaLabel}});e.onChange(R)}}c(i.id);let d=(b=m.current)==null?void 0:b.querySelector(`[data-id="${i.id}"]`);d&&d.focus()};return $(bn,{children:o&&pn("svg",{ref:m,xmlns:"http://www.w3.org/2000/svg",width:o.size,height:o.size,tabIndex:0,focusable:!0,"aria-disabled":e.disabled?!0:void 0,style:e.svgBgColor?_e(K({},J),{backgroundColor:e.svgBgColor}):J,className:`mz-round-slider ${e.disabled?"mz-round-slider-disabled":""}`,children:[e.SvgDefs&&$("defs",{children:e.SvgDefs}),$(bt,{settings:e,pointers:s,svg:o,$svg:m.current,setPointer:h}),$(mt,{settings:e,svg:o,data:t}),$(ot,{settings:e,pointers:s,svg:o,$svg:m.current,data:t,setPointer:h}),$(je,{settings:e,pointers:s,svg:o,$svg:m.current,data:t,setPointer:h,selectedPointerId:l}),$(at,{settings:e,pointers:s,svg:o,data:t})]})})};export{To as RoundSlider}; //# sourceMappingURL=mz-react-round-slider.esm.js.map diff --git a/dist/mz-react-round-slider.esm.js.map b/dist/mz-react-round-slider.esm.js.map index 1821211..d2975fd 100644 --- a/dist/mz-react-round-slider.esm.js.map +++ b/dist/mz-react-round-slider.esm.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/core/index.tsx", "../node_modules/mz-math/src/main/format.ts", "../node_modules/mz-math/src/main/other.ts", "../node_modules/mz-math/src/main/angle.ts", "../node_modules/mz-math/src/main/linear-algebra/vector.ts", "../node_modules/mz-math/src/main/linear-algebra/matrix.ts", "../node_modules/mz-math/src/main/linear-algebra/matrix-transformations.ts", "../node_modules/mz-math/src/main/random.ts", "../node_modules/mz-math/src/main/convert.ts", "../node_modules/mz-math/src/main/derivative.ts", "../node_modules/mz-math/src/main/equations/linear-equations.ts", "../node_modules/mz-math/src/main/equations/quadratic-equations.ts", "../node_modules/mz-math/src/main/bezier-curves/bezier-curve.ts", "../node_modules/mz-math/src/main/path-movement.ts", "../node_modules/mz-math/src/main/color.ts", "../node_modules/mz-math/src/main/id.ts", "../node_modules/mz-math/src/main/collision-detection.ts", "../node_modules/mz-math/src/main/animation.ts", "../node_modules/mz-math/src/main/circle-ellipse.ts", "../src/core/domain/svg-provider.ts", "../src/core/domain/defaults-provider.ts", "../src/core/domain/common-provider.ts", "../src/core/domain/circle-provider.ts", "../src/core/domain/pointers-provider.ts", "../src/core/ui/Pointer.tsx", "../src/core/domain/style-provider.ts", "../src/core/ui/Pointers.tsx", "../src/core/domain/data-provider.ts", "../src/core/ui/Connection.tsx", "../src/core/domain/connection-provider.ts", "../src/core/domain/animation-provider.ts", "../src/core/ui/Text.tsx", "../src/core/ui/Ticks.tsx", "../src/core/domain/ticks-provider.ts", "../src/core/ui/Circle.tsx", "../src/core/ui/InnerCircle.tsx"], - "sourcesContent": ["import { useEffect, useRef, useState } from 'react';\nimport { getSvg, ISvg } from './domain/svg-provider';\nimport { angle2value, getClosestEdge, getPointers, IPointer, IPointers, roundToStep } from './domain/pointers-provider';\nimport { ISettings, ISettingsPointer } from './domain/settings-provider';\nimport { getNumber } from './domain/common-provider';\nimport {\n DEFAULT_PATH_BORDER, DEFAULT_PATH_END_ANGLE, DEFAULT_PATH_RADIUS, DEFAULT_PATH_START_ANGLE,\n DEFAULT_PATH_THICKNESS\n} from './domain/defaults-provider';\nimport Pointers from './ui/Pointers';\nimport { getData, IData } from './domain/data-provider';\nimport Connection from './ui/Connection';\nimport Text from './ui/Text';\nimport Ticks from './ui/Ticks';\nimport Circle from './ui/Circle';\nimport { mod } from 'mz-math';\nimport { isAngleInArc } from './domain/circle-provider';\nimport { outlineNoneStyle } from './domain/style-provider';\n\nexport const RoundSlider = (props: ISettings) => {\n\n const [ data, setData ] = useState(null);\n const [ svg, setSvg ] = useState(null);\n const [ pointers, setPointers ] = useState(null);\n const [ selectedPointerId, setSelectedPointerId ] = useState('');\n\n const prevAngleDegRef = useRef(null);\n const svgRef = useRef(null);\n\n useEffect(() => {\n const _data = getData(props);\n const hasChanged = JSON.stringify(data) !== JSON.stringify(_data);\n if(!hasChanged) return;\n\n setData(_data);\n }, [\n data,\n props\n ]);\n\n useEffect(() => {\n setPointers(getPointers(props, data));\n },\n // eslint-disable-next-line\n [\n props.pointerRadius,\n props.pathStartAngle,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pointers,\n props.pointerRadius,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pathStartAngle,\n props.pathEndAngle,\n data,\n ]);\n\n useEffect(() => {\n if(!pointers) return;\n\n const pathStartAngle = getNumber(props.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n let pathEndAngle = getNumber(props.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n\n if(pathEndAngle <= pathStartAngle) {\n pathEndAngle += 360;\n }\n\n setSvg(getSvg(\n getNumber(props.pathRadius, DEFAULT_PATH_RADIUS),\n getNumber(props.pathThickness, DEFAULT_PATH_THICKNESS),\n getNumber(props.pathBorder, DEFAULT_PATH_BORDER),\n pointers.maxRadius,\n pathStartAngle,\n pathEndAngle,\n ));\n }, [\n props.pathRadius,\n props.pathThickness,\n props.pathBorder,\n props.pathStartAngle,\n props.pathEndAngle,\n pointers,\n ]);\n\n useEffect(() => {\n const clearSelectedPointer = (evt: MouseEvent) => {\n const $target = evt.target as HTMLElement;\n const $pointer = $target.closest('[data-type=\"pointer\"]');\n if($pointer) return;\n\n setSelectedPointerId('');\n };\n\n document.addEventListener('mousedown', clearSelectedPointer);\n\n return () => {\n document.removeEventListener('mousedown', clearSelectedPointer);\n };\n }, []);\n\n const setPointersCallback = (pointer: IPointer, newAngleDeg: number) => {\n if(props.disabled || !pointers.pointers || !pointer || pointer.disabled) return;\n\n newAngleDeg = roundToStep(newAngleDeg, data.stepAngleDeg, svg.startAngleDeg, svg.endAngleDeg);\n if(data.isClosedShape && mod(newAngleDeg, 360) === mod(svg.endAngleDeg, 360)){\n newAngleDeg = svg.startAngleDeg;\n }\n\n if(pointer.angleDeg === newAngleDeg){\n updatePointer(pointer, newAngleDeg, false);\n return;\n }\n\n const handleOverlap = !props.pointersOverlap;\n if(handleOverlap) {\n\n let prevAngle, nextAngle;\n\n if(data.isClosedShape) {\n const prevIndex = mod(pointer.index - 1, pointers.pointers.length);\n const nextIndex = mod(pointer.index + 1, pointers.pointers.length);\n\n const prevPointer = pointers.pointers[prevIndex];\n const nextPointer = pointers.pointers[nextIndex];\n\n prevAngle = prevPointer.angleDeg;\n nextAngle = nextPointer.angleDeg;\n\n if(pointers.pointers.length === 2 && (prevAngle === nextAngle)) {\n\n const splitPointDeg = prevAngle; // === nextAngle\n\n if(prevAngleDegRef.current === null) {\n prevAngleDegRef.current = newAngleDeg;\n }\n else{\n // Clockwise: new angle in (splitPointDeg, splitPointDeg + 90]\n // Clockwise: prev angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: new angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: prev angle in (splitPointDeg, splitPointDeg + 90]\n\n const SAFE_ANGLE = 150;\n\n let t1 = splitPointDeg - SAFE_ANGLE;\n let t2 = splitPointDeg - 0.001;\n\n if(t1 < 0) t1 += 360;\n if(t2 < 0) t2 += 360;\n\n const clockwiseNew = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, newAngleDeg);\n const clockwisePrev = isAngleInArc(t1, t2, prevAngleDegRef.current);\n const clockwise = clockwiseNew && clockwisePrev;\n\n let t3 = splitPointDeg - SAFE_ANGLE;\n let t4 = splitPointDeg - 0.001;\n\n if(t3 < 0) t3 += 360;\n if(t4 < 0) t4 += 360;\n\n const counterClockwiseNew = isAngleInArc(t3, t4, newAngleDeg);\n const counterClockwisePrev = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, prevAngleDegRef.current);\n const counterClockwise = counterClockwiseNew && counterClockwisePrev;\n\n if(clockwise || counterClockwise) {\n updatePointer(pointer, splitPointDeg, true);\n return;\n }\n\n if(newAngleDeg !== splitPointDeg) {\n prevAngleDegRef.current = newAngleDeg;\n }\n }\n }\n }\n else{\n prevAngle = pointer.index === 0 ? svg.startAngleDeg : pointers.pointers[pointer.index - 1].angleDeg;\n nextAngle = pointer.index === pointers.pointers.length - 1 ? svg.endAngleDeg : pointers.pointers[pointer.index + 1].angleDeg;\n }\n\n if(nextAngle <= prevAngle) {\n nextAngle += 360;\n }\n\n if(!isAngleInArc(prevAngle, nextAngle, newAngleDeg)){\n newAngleDeg = getClosestEdge(\n prevAngle,\n nextAngle,\n newAngleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n }\n\n updatePointer(pointer, newAngleDeg, pointer.angleDeg !== newAngleDeg);\n };\n\n const updatePointer = (pointer: IPointer, newAngleDeg: number, angleChanged: boolean) => {\n\n if(angleChanged) {\n const _pointers = { ...pointers };\n _pointers.pointers = [...pointers.pointers];\n _pointers.pointers[pointer.index].prevAngleDeg = _pointers.pointers[pointer.index].angleDeg;\n _pointers.pointers[pointer.index].angleDeg = newAngleDeg;\n pointers.pointers = _pointers.pointers;\n\n setPointers(_pointers);\n\n if(typeof props.onChange === 'function') {\n\n const updatedPointers: ISettingsPointer[] = _pointers.pointers.map(pointer => {\n\n const val = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n\n return {\n radius: pointer.radius,\n value: val,\n bgColor: pointer.bgColor,\n bgColorSelected: pointer.bgColorSelected,\n bgColorDisabled: pointer.bgColorDisabled,\n border: pointer.border,\n borderColor: pointer.borderColor,\n disabled: pointer.disabled,\n ariaLabel: pointer.ariaLabel,\n };\n });\n\n props.onChange(updatedPointers);\n }\n }\n\n setSelectedPointerId(pointer.id);\n\n const $pointer = svgRef.current?.querySelector(`[data-id=\"${ pointer.id }\"]`) as HTMLElement;\n if($pointer) {\n $pointer.focus();\n }\n };\n\n return (\n <>\n {\n svg &&\n \n\n {\n (props.SvgDefs) &&\n \n { props.SvgDefs }\n \n }\n\n \n\n \n\n \n\n \n\n \n \n }\n \n )\n};", "export const setDecimalPlaces = (num: number, decimalPlaces: number | undefined = Infinity) => {\n if(decimalPlaces === Infinity) return num;\n\n if(decimalPlaces < 0){\n decimalPlaces = 0;\n }\n\n const coefficient = 10 ** decimalPlaces;\n return Math.round(num * coefficient) / coefficient;\n};", "import { Vector2 } from '../types';\nimport { setDecimalPlaces } from './format';\n\nexport const mod = (n: number, m: number) => {\n return ((n % m) + m) % m;\n};\n\n/**\n * Convert range [a, b] to [c, d].\n * f(x) = (d - c) * (x - a) / (b - a) + c\n */\nexport const convertRange = (x: number, a: number, b: number, c: number, d: number) => {\n return (d - c) * (x - a) / (b - a) + c;\n};\n\n/**\n * Check if 2 ranges [a,b] and [c,d] overlap.\n */\nexport const doRangesOverlap = (a: number, b: number, c: number, d: number) => {\n return Math.max(a, c) <= Math.min(b, d) ;\n};\n\n// eslint-disable-next-line\nexport const isNumber = (value: any) => {\n return !isNaN(parseFloat(value)) && isFinite(value);\n};\n\n/**\n * Convert polar coordinates to cartesian coordinates.\n */\nexport const polarToCartesian = (center: Vector2, radii: Vector2, angleInRad: number, decimalPlaces = Infinity) : Vector2 => {\n const [cx, cy] = center;\n const [rx, ry] = radii;\n\n return [\n setDecimalPlaces(cx + (rx * Math.cos(angleInRad)), decimalPlaces),\n setDecimalPlaces(cy + (ry * Math.sin(angleInRad)), decimalPlaces),\n ];\n};", "import { Vector, Vector2, Vector3 } from '../types';\nimport { setDecimalPlaces } from './format';\nimport { v2Length, vNormalize, vDotProduct, vSub } from './linear-algebra/vector';\nimport { mod } from './other';\n\nexport const getV2Angle = (v2: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1], v2[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleInEllipse = (v2: Vector2, radii: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1]/radii[1], v2[0]/radii[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const setV2Angle = (v2: Vector2, newAngleRad: number, decimalPlaces = Infinity): Vector2 => {\n const length = v2Length(v2);\n return [\n setDecimalPlaces(Math.cos(newAngleRad) * length, decimalPlaces),\n setDecimalPlaces(Math.sin(newAngleRad) * length, decimalPlaces),\n ];\n};\n\nexport const radiansToDegrees = (radians: number, decimalPlaces = Infinity) => {\n const res = radians * (180 / Math.PI);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\nexport const degreesToRadians = (degrees: number, decimalPlaces = Infinity) => {\n const res = degrees * (Math.PI / 180);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\n/**\n * Returns the range [0, Math.PI]\n * A = Math.acos( dot(v1, v2)/(v1.length()*v2.length()) );\n */\nexport const getVNAngleBetween = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n const unitVector1 = vNormalize(vector1);\n const unitVector2 = vNormalize(vector2);\n const dotProduct = vDotProduct(unitVector1, unitVector2);\n const angle = Math.acos(dotProduct);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleBetween = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) : number => {\n // return getVNAngleBetween(vector1, vector2, decimalPlaces);\n const diff = vSub(vector1, vector2);\n const angle = Math.atan2(diff[1], diff[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV3AngleBetween = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return getVNAngleBetween(vector1, vector2, decimalPlaces);\n};\n\nexport const isAngleBetween = (angleDegrees: number, startAngleDegrees: number, endAngleDegrees: number) : boolean => {\n const distance = getAnglesSub(startAngleDegrees, endAngleDegrees);\n const distance1 = getAnglesSub(startAngleDegrees, angleDegrees);\n const distance2 = getAnglesSub(endAngleDegrees, angleDegrees);\n const totalDistance = distance1 + distance2;\n\n // Use a small threshold for floating point errors\n return Math.abs(totalDistance - distance) <= 0.001;\n}\n\nexport const isClockwise = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n return angle2Deg >= angle1Deg;\n};\n\n/**\n * Shortest distance (angular) between two angles.\n */\nexport const getAnglesSub = (angleDegrees1: number, angleDegrees2: number, decimalPlaces = Infinity) : number => {\n const angleDistance = Math.abs(mod(angleDegrees1, 360) - mod(angleDegrees2, 360));\n return setDecimalPlaces(angleDistance <= 180 ? angleDistance : 360 - angleDistance, decimalPlaces);\n};\n\nexport const getAnglesDistance = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0, decimalPlaces = Infinity) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n if(isClockwise(angle1Deg, angle2Deg, startAngleDeg)) {\n return setDecimalPlaces((angle2Deg - angle1Deg + 360) % 360, decimalPlaces);\n }\n else{\n return setDecimalPlaces((angle1Deg - angle2Deg + 360) % 360, decimalPlaces);\n }\n};\n\nexport const percentToAngle = (percent: number, startAngleDeg: number, endAngleDeg: number, circleStartAngle = 0) => {\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n const distance = getAnglesDistance(startAngleDeg, endAngleDeg, circleStartAngle);\n\n const clockwise = isClockwise(startAngleDeg, endAngleDeg, circleStartAngle);\n if(clockwise) {\n return mod(circleStartAngle + (percent * distance / 100), 360);\n }\n else {\n return mod(circleStartAngle - (percent * distance / 100), 360);\n }\n};", "import { Vector, Vector2, Vector3, Vector4 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { getV2Angle, setV2Angle } from '../angle';\n\n// ------------ SUM ------------------------\n\nexport const vSum = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSum(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sum = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSum(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ SUB ------------------------\n\nexport const vSub = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSub(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sub = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSub(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ MUL SCALAR ------------------------\n\nexport const vMulScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n const vector: Vector = [];\n\n for(let i=0; i {\n return vMulScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3MulScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vMulScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ DIVIDE ------------------------\n\nexport const vDivideScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vDivideScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3DivideScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vDivideScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ LENGTH ------------------------\n\nexport const vLength = (vector: Vector, decimalPlaces = Infinity) => {\n let sum = 0;\n\n for(let i=0; i {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v3Length = (vector: Vector3, decimalPlaces = Infinity) => {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v2SetLength = (v2: Vector2, newLength: number, decimalPlaces = Infinity): Vector2 => {\n const angle = getV2Angle(v2);\n return [\n setDecimalPlaces(Math.cos(angle) * newLength, decimalPlaces),\n setDecimalPlaces(Math.sin(angle) * newLength, decimalPlaces),\n ];\n};\n\n// ----------- DISTANCE ------------------------\n\nexport const vDistance = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v2Distance = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v3Distance = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\n// ------------ NORMALIZE ------------------------\n\n/**\n * Normalization creates a unit vector, which is a vector of length 1.\n */\nexport const vNormalize = (v: Vector, decimalPlaces = Infinity) : Vector => {\n const length = vLength(v);\n const unitVector: Vector = [];\n\n for(let i=0; i {\n return vNormalize(v2, decimalPlaces) as Vector2;\n};\n\nexport const v3Normalize = (v3: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vNormalize(v3, decimalPlaces) as Vector3;\n};\n\n// ------------ DOT PRODUCT ------------------------\n\nexport const vDotProduct = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n let sum = 0;\n\n for(let i=0; i {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\nexport const v3DotProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\n// ------------ CROSS PRODUCT ------------------------\n\n/**\n * Cross product is possible on 3D vectors only.\n * The cross product a \u00D7 b is defined as a vector c that is perpendicular (orthogonal) to both a and b.\n */\nexport const v3CrossProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity): Vector3 => {\n return [\n setDecimalPlaces(vector1[1] * vector2[2] - vector1[2] * vector2[1], decimalPlaces),\n setDecimalPlaces(vector1[2] * vector2[0] - vector1[0] * vector2[2], decimalPlaces),\n setDecimalPlaces(vector1[0] * vector2[1] - vector1[1] * vector2[0], decimalPlaces),\n ];\n};\n\n// --------------- INIT VECTOR HELPER -----------------\n\nexport const v2 = (defaultValue = 0): Vector2 => {\n return [defaultValue, defaultValue];\n};\n\nexport const v3 = (defaultValue = 0): Vector3 => {\n return [defaultValue, defaultValue, defaultValue];\n};\n\nexport const v4 = (defaultValue = 0): Vector4 => {\n return [defaultValue, defaultValue, defaultValue, defaultValue];\n};\n\nexport const vN = (N: number, defaultValue = 0): Vector => {\n\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n const vector: Vector = [];\n for(let i=0; i {\n let vector: Vector2 = [0, 0];\n vector = v2SetLength(vector, distance);\n return setV2Angle(vector, angleRad);\n};\n\n// --------------- EQUALITY -------------------------\n\nexport const vEqual = (vector1: Vector, vector2: Vector): boolean => {\n if(vector1.length !== vector2.length) return false;\n\n for(let i=0; i {\n const sub = v2Sub(vector2, vector1);\n return [\n -setDecimalPlaces(sub[1], decimalPlaces),\n setDecimalPlaces(sub[0], decimalPlaces)\n ];\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector, Vector2, Vector3 } from '../../types';\nimport { vMulScalar, vSum, vSub, vDotProduct, vN, vEqual, vDivideScalar } from './vector';\n\n// --------------- SUM ----------------------\n\nexport const mSum = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sum = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- SUB ----------------------\n\nexport const mSub = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sub = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- MUL SCALAR ----------------------\n\nexport const mMulScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vMulScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2MulScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mMulScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3MulScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mMulScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n// --------------- DIVIDE SCALAR ----------------------\n\nexport const mDivideScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vDivideScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2DivideScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mDivideScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3DivideScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mDivideScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n\n// --------------- TRANSPOSE ----------------------\n\nexport const mTranspose = (m: Matrix): Matrix => {\n\n const vectorsCount = m.length;\n if(vectorsCount <= 0) return m;\n\n const vectorLength = m[0].length;\n if(vectorLength <= 0) return m;\n\n const matrix: Matrix = [];\n for(let i=0; i {\n return mTranspose(m2);\n};\n\nexport const m3Transpose = (m3: Matrix3): Matrix => {\n return mTranspose(m3);\n};\n\n// ----------------- RESET ----------------------\n\nexport const mReset = (m: Matrix, defaultValue = 0): Matrix => {\n\n if(m.length <= 0) return [];\n\n const res: Matrix = [];\n\n for(let i=0; i {\n return mReset(m2, defaultValue) as Matrix2;\n};\n\nexport const m3Reset = (m3: Matrix3, defaultValue = 0): Matrix3 => {\n return mReset(m3, defaultValue) as Matrix3;\n};\n\n// --------------- MATRIX INIT HELPERS -----------------\n\nexport const m2x2 = (defaultValue = 0): Matrix2 => {\n return [\n [defaultValue, defaultValue],\n [defaultValue, defaultValue],\n ];\n};\n\nexport const m3x3 = (defaultValue = 0): Matrix3 => {\n return [\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const m4x4 = (defaultValue = 0): Matrix4 => {\n return [\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const mNxM = (N: number, M: number, defaultValue = 0): Matrix => {\n if(N <= 0 || M <= 0){\n throw new Error('M and N must be positive numbers.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return [\n [1, 0],\n [0, 1],\n ];\n};\n\nexport const identity3 = (): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\nexport const identity4 = (): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Identity Matrix (I).\n * M x I = I x M = M for any matrix M.\n * Identity Matrix is a special case of scale matrix.\n */\nexport const identityN = (N: number): Matrix => {\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n if(N === 0) return [];\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mDeepCopy(m2) as Matrix2;\n};\n\nexport const m3DeepCopy = (m3: Matrix3): Matrix3 => {\n return mDeepCopy(m3) as Matrix3;\n};\n\n// -------------- APPEND / PREPEND ROW OR COLUMN ---------------\n\nexport const mAppendCol = (m: Matrix, col: Vector): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n const copy = mDeepCopy(m);\n copy.push(row);\n return copy;\n};\n\nexport const m2AppendRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.push(row);\n return copy;\n};\n\nexport const m3AppendRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.push(row);\n return copy;\n};\n\nexport const mPrependRow = (m: Matrix, row: Vector) : Matrix => {\n const copy = mDeepCopy(m);\n copy.unshift(row);\n return copy;\n};\n\nexport const m2PrependRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.unshift(row);\n return copy;\n};\n\nexport const m3PrependRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.unshift(row);\n return copy;\n};\n\n// ------------ DELETE ROW OR COLUMN ----------------------------\n\nexport const mDelLastRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.pop();\n return copy;\n};\n\nexport const mDelFirstRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.shift();\n return copy;\n};\n\nexport const mDelLastColumn = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const size = m[0].length;\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n\n const matrix: Matrix = [];\n for(let i=0; i {\n\n if(matrix.length < 0) return [];\n\n if(matrix[0].length !== vector.length){\n throw new Error('The number of columns in the matrix must be equal to the length of the vector.');\n }\n\n const res: Vector = [];\n\n for(let i=0; i {\n if(matrix1.length !== matrix2.length) return false;\n\n for(let i=0; i returns matrix N (m-1 x m-1)\n * The matrix must be square.\n */\nconst mMinorHelper = (m: Matrix, row: number, col: number) => {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // prepare the matrix without provided row and column\n const matrix = mMinorHelper(m, row, col);\n\n // calculate the matrix determinant\n return mDeterminant(matrix);\n};\n\n/**\n * Calculate determinant for NxN matrix.\n * Matrix should be square.\n */\nexport const mDeterminant = (matrix: Matrix): number => {\n const size = matrix.length;\n if(size === 0) return 1;\n\n if(size !== matrix[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return matrix[0][0];\n if(size === 2) return m2Determinant(matrix as Matrix2);\n\n let d = 0;\n\n for(let i=0; i {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return m2[0][0] * m2[1][1] - m2[1][0] * m2[0][1];\n};\n\n/**\n * Calculate determinant for 3x3 matrix.\n * Matrix should be square.\n */\nexport const m3Determinant = (m3: Matrix3): number => {\n if(m3.length !== m3[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return mDeterminant(m3);\n};\n\n// ------------------ INVERSE -----------------------\n\nexport const m2Adjugate = (m2: Matrix2): Matrix2|null => {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return [\n [m2[1][1], -m2[0][1]],\n [-m2[1][0], m2[0][0]],\n ];\n};\n\nexport const m3Adjugate = (m3: Matrix3) : Matrix3|null => {\n return mAdjugate(m3) as (Matrix3|null);\n};\n\n/**\n * Adjugate is a transpose of a cofactor matrix\n */\nexport const mAdjugate = (m: Matrix): Matrix|null => {\n\n const size = m.length;\n if(size <= 0) return null;\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return m;\n\n if(size === 2) return m2Adjugate(m as Matrix2);\n\n // build a cofactor matrix ----------------\n const cofactors: Matrix = [];\n\n for(let i=0; i {\n if(m.length > 0 && m.length !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = mDeterminant(m);\n return d === 0;\n};\n\n/**\n * Square matrix A (nxn) is invertible is there is another square matrix B (nxn) so AxB = BxA = I\n * For A (2x2) matrix, the inverse is:\n * (1 / (determinant(A))) * adj(A)\n */\nexport const m2Inverse = (m2: Matrix2, decimalPlaces = Infinity): (Matrix2 | null) => {\n if(m2.length > 0 && m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = m2Determinant(m2);\n if(d === 0) return null;\n\n const adj = m2Adjugate(m2);\n if(adj === null) return null;\n\n return m2DivideScalar(adj, d, decimalPlaces);\n};\n\nexport const m3Inverse = (m3: Matrix3, decimalPlaces = Infinity): (Matrix3 | null) => {\n return mInverse(m3, decimalPlaces) as (Matrix3|null);\n};\n\nexport const mInverse = (m: Matrix, decimalPlaces = Infinity): (Matrix | null) => {\n const size = m.length;\n\n if(size > 0 && size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // find a determinant ----------------------\n const d = mDeterminant(m);\n\n // find an Adjugate - a transpose of a cofactor matrix\n const adj = mAdjugate(m);\n if(adj === null) return null;\n\n return mDivideScalar(adj, d, decimalPlaces);\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector2, Vector3, Vector4 } from '../../types';\nimport { v2Normalize, v3MulScalar, v3Normalize } from './vector';\nimport { mMulVector, mMul } from './matrix';\nimport { setDecimalPlaces } from '../format';\n\n/*\nAny 2D affine transformation can be decomposed\ninto a rotation, followed by a scaling, followed by a\nshearing, and followed by a translation.\n---------------------------------------------------------\nAffine matrix = translation x shearing x scaling x rotation\n */\n\n// ----------------- CSS -------------------------------------\n\n/**\n * Matrix 2D in non-homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2ToCSS = (m: Matrix2) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, 0, 0)`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2hToCSS = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, ${ tx }, ${ ty })`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m2hToCSS3d = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix3d(${ a }, ${ b }, 0, 0, ${ c }, ${ d }, 0, 0, 0, 0, 1, 0, ${ tx }, ${ ty }, 0, 1)`;\n};\n\n/**\n * Matrix 3D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m3hToCSS3d = (m: Matrix4) : string => {\n\n return `matrix3d(\n ${ m[0][0] }, ${ m[0][1] }, ${ m[0][2] }, ${ m[0][3] },\n ${ m[1][0] }, ${ m[1][1] }, ${ m[1][2] }, ${ m[1][3] },\n ${ m[2][0] }, ${ m[2][1] }, ${ m[2][2] }, ${ m[2][3] },\n ${ m[3][0] }, ${ m[3][1] }, ${ m[3][2] }, ${ m[3][3] }\n )`;\n};\n\n// ---------------- TRANSLATION MATRICES ----------------------\n\nexport const m2Translation = (position: Vector2, decimalPlaces = Infinity): Matrix2 => {\n\n return [\n [1, 0],\n [0, 1],\n [setDecimalPlaces(position[0], decimalPlaces), setDecimalPlaces(position[1], decimalPlaces)],\n ];\n};\n\nexport const m3Translation = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n [\n setDecimalPlaces(position[0], decimalPlaces),\n setDecimalPlaces(position[1], decimalPlaces),\n setDecimalPlaces(position[2], decimalPlaces)\n ],\n ];\n};\n\n/**\n * 2D Translation matrix in homogeneous coordinates.\n */\nexport const m2TranslationH = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1],\n ];\n};\n\n/**\n * 3D Translation matrix in homogeneous coordinates.\n */\nexport const m3TranslationH = (position: Vector4, decimalPlaces = Infinity): Matrix4 => {\n\n return [\n [1, 0, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, 0, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1, setDecimalPlaces(position[2], decimalPlaces)],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- ROTATION MATRICES -------------------------\n\n/**\n * Rotation of an angle about the origin.\n */\nexport const m2Rotation = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix2 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin],\n [sin, cos],\n ] :\n [\n [cos, sin],\n [-sin, cos],\n ];\n};\n\n/**\n * Rotation of an angle about the origin in homogeneous coordinates (clockwise).\n */\nexport const m2RotationH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ]:\n [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation of an angle \"angleRad\" around the given point (transformOrigin) in homogeneous coordinates (clockwise).\n * result_vector = TranslationMatrix(x, y) * RotationMatrix() * TranslationMatrix(-x, -y) * position_vector\n */\nexport const m2RotationAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const rotation = m2RotationH(angleRad, isClockwise, decimalPlaces);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, rotation);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2RotateAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n position: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2RotationAroundPointH(angleRad, transformOrigin, isClockwise, decimalPlaces);\n return mMulVector(mat3h, position) as Vector3;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2Rotate = (angleRad: number, vector: Vector2, isClockwise = true, decimalPlaces = Infinity): Vector2 => {\n const unitVector = v2Normalize(vector);\n return mMulVector(m2Rotation(angleRad, isClockwise, decimalPlaces), unitVector) as Vector2;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2RotateH = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m2RotationH(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the X axis (clockwise).\n */\nexport const m3RotationX = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0],\n [0, cos, -sin],\n [0, sin, cos],\n ] :\n [\n [1, 0, 0],\n [0, cos, sin],\n [0, -sin, cos],\n ];\n};\n\n/**\n * Rotation around the X axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationXH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0, 0],\n [0, cos, -sin, 0],\n [0, sin, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [1, 0, 0, 0],\n [0, cos, sin, 0],\n [0, -sin, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateX = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationX(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Y axis (clockwise).\n */\nexport const m3RotationY = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin],\n [0, 1, 0],\n [-sin, 0, cos],\n ] :\n [\n [cos, 0, -sin],\n [0, 1, 0],\n [sin, 0, cos],\n ];\n};\n\n/**\n * Rotation around the Y axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationYH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin, 0],\n [0, 1, 0, 0],\n [-sin, 0, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [cos, 0, -sin, 0],\n [0, 1, 0, 0],\n [sin, 0, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateY = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationY(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Z axis (clockwise).\n */\nexport const m3RotationZ = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ] : [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation around the Z axis (clockwise)- in homogeneous coordinates\n */\nexport const m3RotationZH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0, 0],\n [sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ] : [\n [cos, sin, 0, 0],\n [-sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateZ = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationZ(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n// ---------------- SCALE MATRICES -------------\n\n/**\n * Get matrix for arbitrary scaling pivot point.\n * result_vector = TranslationMatrix(x, y) * ScaleMatrix() * TranslationMatrix(-x, -y) * scale_vector\n */\nexport const m2ScaleAtPointHMatrix = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const scale = m2ScaleH(scaleVector);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, scale);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2ScaleAtPointH = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n point: Vector3,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2ScaleAtPointHMatrix(scaleVector, transformOrigin, decimalPlaces);\n return mMulVector(mat3h, point) as Vector3;\n};\n\nexport const m2Scale = (scaleVector: Vector2): Matrix2 => {\n return [\n [scaleVector[0], 0],\n [0, scaleVector[1]],\n ];\n};\n\nexport const v2Scale = (scaleVector: Vector2, vector: Vector2): Vector2 => {\n return mMulVector(m2Scale(scaleVector), vector) as Vector2;\n};\n\n/**\n * homogeneous coordinates\n */\nexport const m2ScaleH = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, 1],\n ];\n};\n\nexport const m3Scale = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, scaleVector[2]],\n ];\n};\n\nexport const m3ScaleH = (scaleVector: Vector4): Matrix4 => {\n return [\n [scaleVector[0], 0, 0, 0],\n [0, scaleVector[1], 0, 0],\n [0, 0, scaleVector[2], 0],\n [0, 0, 0, 1]\n ];\n};\n\nexport const v3Scale = (scaleVector: Vector3, vector: Vector3): Vector3 => {\n return mMulVector(m3Scale(scaleVector), vector) as Vector3;\n};\n\n/**\n * Stretch, parallel to the x-axis.\n */\nexport const m2ScaleX = (scale: number): Matrix2 => {\n return [\n [scale, 0],\n [0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the x-axis - homogeneous coordinates\n */\nexport const m2ScaleXH = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleX = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleXH = (scale: number): Matrix4 => {\n return [\n [scale, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleY = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleYH = (scale: number): Matrix => {\n return [\n [1, 0, 0, 0],\n [0, scale, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZ = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, scale],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZH = (scale: number): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, scale, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis.\n */\nexport const m2ScaleY = (scale: number): Matrix2 => {\n return [\n [1, 0],\n [0, scale],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis - homogeneous coordinates\n */\nexport const m2ScaleYH = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n// ---------------- REFLECTION MATRICES -------------------------\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOrigin = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOriginH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection about the origin in non-homogeneous coordinates\n */\nexport const m3ReflectionOrigin = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection about the origin in homogeneous coordinates\n */\nexport const m3ReflectionOriginH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection about y=-x\n */\nexport const m2ReflectionYmX = (): Matrix2 => {\n\n return [\n [0, -1],\n [-1, 0],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionX = (): Matrix2 => {\n\n return [\n [1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionXH = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection in the y-axis.\n */\nexport const m2ReflectionY = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, 1],\n ];\n};\n\nexport const m2ReflectionYH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionYZ = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in homogeneous coordinates\n */\nexport const m3ReflectionYZH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXZ = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in homogeneous coordinates\n */\nexport const m3ReflectionXZH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXY = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in homogeneous coordinates\n */\nexport const m3ReflectionXYH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- SHEARING MATRICES -------------------------\n\n\n/**\n * Shearing in y-axis, with x-axis fixed with (0,1) moving to (factor, 1)\n */\nexport const m2ShearingY = (factor: number): Matrix2 => {\n\n return [\n [1, factor],\n [0, 1],\n ];\n};\n\n/**\n * Shearing in x-axis, with y-axis fixed with (1,0) moving to (1, factor)\n */\nexport const m2ShearingX = (factor: number): Matrix2 => {\n\n return [\n [1, 0],\n [factor, 1],\n ];\n};", "import { setDecimalPlaces } from './format';\n\n/**\n * Returns a random number in the [min,max] range.\n */\nexport const getRandom = (min: number, max: number, decimalPlaces = Infinity): number => {\n return setDecimalPlaces(Math.random() * (max - min) + min, decimalPlaces);\n};\n\n/**\n * Returns a random integer number in the [min,max] range.\n */\nexport const getRandomInt = (min: number, max: number): number => {\n return Math.floor(Math.random() * (max - min + 1) + min);\n};\n\nexport const getRandomBoolean = () => Math.random() < 0.5;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const getRandomItemFromArray = (array: any[]) => {\n const randomIndex = getRandomInt(0, array.length - 1);\n return array[randomIndex];\n};", "export const stringToNumber = (value: string|undefined|null|number, defaultNumber: number) => {\n if(value === undefined || value === null) return defaultNumber;\n const res = Number(value) ?? defaultNumber;\n return isNaN(res) ? defaultNumber : res;\n};", "import { setDecimalPlaces } from './format';\nimport { Vector2, Vector3 } from '../types';\n\n/**\n * u(x) and v(x) are functions ---------->\n *\n * dx(u + v) = dx(u) + dx(v)\n * dx(u - v) = dx(u) - dx(v)\n * dx(u * v) = dx(u) * v + u * dx(v)\n * dx(u / v) = (dx(u) * v - u * dx(v)) / (v ^ 2), when v(x) != 0\n */\n\n// ------------------ Derivatives of Polynomial ---------------------------\n\n/**\n * y = 3x+2\n * dxPolynomial(10, [[3, 1], [2, 0]])\n */\nexport const dxPolynomial = (x: number, polynomial: number[][], decimalPlaces = Infinity) => {\n let res = 0;\n\n for(const part of polynomial){\n if(part.length !== 2) return NaN;\n\n const coeff = part[0];\n const power = part[1];\n res += coeff * power * Math.pow(x, power - 1);\n }\n\n return setDecimalPlaces(res, decimalPlaces);\n}\n\n// ---------------------- Bezier Curves ---------------------------\n\n/**\n * Derivative of Bezier Curve is another Bezier Curve.\n * t must min in range [0, 1]\n */\nexport const dxV2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n // The derivative: P1 * (2t-2) + (2*P3-4*P2) * t + 2 * P2\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\nexport const dxV2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n\n// ----------------- Derivatives of trigonometry functions ---------------------------\n\nexport const dxSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(Math.cos(x), decimalPlaces);\n};\n\nexport const dxCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-Math.sin(x), decimalPlaces);\n};\n\nexport const dxTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.cos(x) ** 2), decimalPlaces);\n};\n\n/**\n * x != Math.PI * n, where n is an integer\n */\nexport const dxCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sin(x) ** 2), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\nexport const dxArcTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (1 + x ** 2), decimalPlaces);\n};\n\nexport const dxArcCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (1 + x ** 2), decimalPlaces);\n};\n", "import { Matrix, Matrix2, Matrix3, Vector, Vector2, Vector3 } from '../../types';\nimport { m2Inverse, m3Inverse, mInverse, mMulVector, mDelLastColumn, mGetLastColumn } from '../linear-algebra/matrix';\nimport { setDecimalPlaces } from '../format';\nimport { v2Sub } from '../linear-algebra/vector';\n\n/**\n * Linear equation\n * ax + b = c\n * x = (c - b) / a; a != 0\n */\nexport const linearEquation = (equation: Vector3, decimalPlaces = Infinity) : number => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n\n const diff = c - b;\n\n if(a === 0 && diff === 0) return Infinity; // any number is a solution\n if(a === 0) return NaN; // no solution\n\n return setDecimalPlaces(diff / a, decimalPlaces);\n};\n\n/**\n * System of 2 linear equations.\n * [x, y] = inverse(Matrix of equation parameters) x (vector of equation results)\n * ---------------\n * 3x + 2y = 7\n * -6x + 6y = 6\n */\nexport const linearEquationSystem2 = (equation1: Vector3, equation2: Vector3, decimalPlaces = Infinity) : Vector2 | null => {\n const equationParams: Matrix2 = [\n [equation1[0], equation1[1]],\n [equation2[0], equation2[1]],\n ];\n\n const inversed = m2Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector2 = [\n equation1[2],\n equation2[2]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector2;\n};\n\n/**\n * System of 3 linear equations.\n * ---------------------------------------\n * 3x + 2y + 5z = 7\n * -6x + 6y + 6z = 6\n * 2x + 7y - z = 4\n */\nexport const linearEquationSystem3 = (\n equation1: Vector,\n equation2: Vector,\n equation3: Vector,\n decimalPlaces = Infinity) : Vector3 | null => {\n const equationParams: Matrix3 = [\n [equation1[0], equation1[1], equation1[2]],\n [equation2[0], equation2[1], equation2[2]],\n [equation3[0], equation3[1], equation3[2]],\n ];\n\n const inversed = m3Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector3 = [\n equation1[3],\n equation2[3],\n equation3[3]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector3;\n};\n\n/**\n * System of N linear equations.\n */\nexport const linearEquationSystemN = (equations: Matrix, decimalPlaces = Infinity) : Vector | null => {\n if(equations.length <= 0) return null;\n\n const equationParams = mDelLastColumn(equations);\n\n const inversed = mInverse(equationParams);\n if(inversed === null) return null; // no results\n\n // the last column of the equations matrix\n const equationResults = mGetLastColumn(equations);\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector;\n};\n\n/**\n * Calculate the equation of a line given two points in a 2D space.\n * y = ax + b\n * y - y1 = m(x - x1)\n * m = (y2 - y1) / (x2 - x1)\n */\nexport const getLinearEquationBy2Points = (point1: Vector2, point2: Vector2) : {\n slope: number|undefined,\n yIntercept: number|undefined,\n xIntercept: number|undefined,\n formula: string,\n} => {\n const [deltaX, deltaY] = v2Sub(point2, point1);\n const [x, y] = point1;\n\n if(deltaX === 0) {\n return {\n slope: undefined,\n xIntercept: x,\n yIntercept: undefined,\n formula: `x = ${ x }`,\n };\n }\n\n const m = deltaY / deltaX;\n const b = y - m * x;\n let formula = '';\n\n if(m === 0) {\n formula = `y = ${ b }`;\n }\n else{\n formula = `y = ${ m === 1 ? '' : m }x`;\n\n if(b !== 0) {\n formula += ` ${ b < 0 ? '-' : '+' } ${ Math.abs(b) }`;\n }\n }\n\n return {\n slope: m,\n xIntercept: undefined,\n yIntercept: b,\n formula,\n };\n};", "import { Vector } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { linearEquation } from './linear-equations';\nimport { isNumber } from '../other';\n\n/**\n * Quadratic Equation.\n * ax^2 + bx + c = d\n */\nexport const quadraticEquation = (equation: Vector, decimalPlaces = Infinity) : Vector => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n const d = equation[3];\n\n if(a === 0){\n // it's a linear equation -------------------------------------------\n const res = linearEquation([b, c, d], decimalPlaces);\n if(isNumber(res)) return [res];\n return [];\n }\n\n const diff = c - d;\n\n const discriminant = b * b - (4 * a * diff);\n\n if(discriminant < 0){\n return []; // no results\n }\n\n if(discriminant === 0){\n return [ setDecimalPlaces(-b / (2 * a), decimalPlaces) ]; // 1 result\n }\n\n // if(determinant > 0) ---> 2 results\n const t1 = 2 * a;\n const t2 = Math.sqrt(discriminant);\n\n return [\n setDecimalPlaces((-b + t2) / t1, decimalPlaces),\n setDecimalPlaces((-b - t2) / t1, decimalPlaces),\n ];\n};", "import { IBBox, Vector, Vector2, Vector3 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport {\n dxV2CubicBezierCurve,\n dxV2QuadraticBezierCurve,\n dxV3CubicBezierCurve,\n dxV3QuadraticBezierCurve\n} from '../derivative';\nimport { v2Normalize, v3Normalize } from '../linear-algebra/vector';\nimport { linearEquation } from '../equations/linear-equations';\nimport { quadraticEquation } from '../equations/quadratic-equations';\nimport { isNumber } from '../other';\n\n/**\n * B\u00E9zier Curves\n * quadratic: y = P1 * (1-t)\u00B2 + P2 * 2 * (1-t)t + P3 * t\u00B2\n * t in range [0, 1]\n */\n\n// -------------------- GET POINT ON CURVE --------------------------\n\n/**\n * Get a point on a quadratic B\u00E9zier curve as a function of time.\n */\nexport const v2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n/**\n * Get a point on a cubic B\u00E9zier curve as a function of time.\n */\nexport const v2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n// -------------------- TANGENT --------------------------\n\n/**\n * Tangent indicates the direction of travel at specific points along the B\u00E9zier curve,\n * and is literally just the first derivative of our curve.\n */\nexport const v2QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\nexport const v2CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\n// -------------------- NORMAL --------------------------\n\n/**\n * Normal is a vector that runs at a right angle to the direction of the curve, and is typically of length 1.\n * To find it, we take the normalised tangent vector, and then rotate it by a 90 degrees.\n */\nexport const v2QuadraticBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2QuadraticBezierCurveTangent(t, startControlPoint, centerControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\nexport const v2CubicBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2CubicBezierCurveTangent(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\n// -------------------- EXTREMA --------------------------\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2QuadraticBezierCurveExtrema = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector => {\n\n /*\n (-2 * (1 - t)) * startControlPoint[0] + (2 - 4 * t) * centerControlPoint[0] + (2 * t) * endControlPoint[0]\n 2 * t * startControlPoint[0] - 4 * t * centerControlPoint[0] + 2 * t * endControlPoint[0] - 2 * startControlPoint[0] + 2 * centerControlPoint[0]\n t * (2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0]) + (- 2 * startControlPoint[0] + 2 * centerControlPoint[0])\n */\n\n const a1 = 2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0];\n const b1 = -2 * startControlPoint[0] + 2 * centerControlPoint[0];\n const equation1: Vector3 = [a1, b1, 0];\n const res1 = linearEquation(equation1, decimalPlaces);\n\n const a2 = 2 * startControlPoint[1] - 4 * centerControlPoint[1] + 2 * endControlPoint[1];\n const b2 = -2 * startControlPoint[1] + 2 * centerControlPoint[1];\n const equation2: Vector3 = [a2, b2, 0];\n const res2 = linearEquation(equation2, decimalPlaces);\n\n const res: Vector = [];\n\n if(isNumber(res1)){\n res.push(res1);\n }\n\n if(isNumber(res2)){\n res.push(res2);\n }\n\n return res;\n};\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2CubicBezierCurveExtrema = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2|null => {\n\n const a1 = -3 * startControlPoint[0] + 9 * center1ControlPoint[0] - 9 * center2ControlPoint[0] + 3 * endControlPoint[0];\n const b1 = 6 * startControlPoint[0] - 12 * center1ControlPoint[0] + 6 * center2ControlPoint[0];\n const c1 = -3 * startControlPoint[0] + 3 * center1ControlPoint[0];\n const equation1: Vector = [a1, b1, c1, 0];\n\n const a2 = -3 * startControlPoint[1] + 9 * center1ControlPoint[1] - 9 * center2ControlPoint[1] + 3 * endControlPoint[1];\n const b2 = 6 * startControlPoint[1] - 12 * center1ControlPoint[1] + 6 * center2ControlPoint[1];\n const c2 = -3 * startControlPoint[1] + 3 * center1ControlPoint[1];\n const equation2: Vector = [a2, b2, c2, 0];\n\n // Any value between 0 and 1 is a root that matters for B\u00E9zier curves, anything below or above that is irrelevant (because B\u00E9zier curves are only defined over the interval [0,1]).\n const res1 = quadraticEquation(equation1, decimalPlaces).filter(num => num >= 0 && num <= 1);\n const res2 = quadraticEquation(equation2, decimalPlaces).filter(num => num >= 0 && num <= 1);\n\n const res = [...res1, ...res2];\n if(res.length === 2){\n return [...res1, ...res2] as Vector2;\n }\n\n return null;\n};\n\n// -------------------- BOUNDING BOX --------------------------\n\nexport const v2QuadraticBezierBBox = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2QuadraticBezierCurveExtrema(startControlPoint, centerControlPoint, endControlPoint);\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2QuadraticBezierCurve(percent, startControlPoint, centerControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\nexport const v2CubicBezierBBox = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2CubicBezierCurveExtrema(startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint) || [];\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2CubicBezierCurve(percent, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x ?? Infinity);\n maxX = Math.max(maxX, x ?? -Infinity);\n\n minY = Math.min(minY, y ?? Infinity);\n maxY = Math.max(maxY, y ?? -Infinity);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\n\n", "import { Vector2 } from '../types';\nimport { v2Sub } from './linear-algebra/vector';\nimport { getV2Angle } from './angle';\nimport { convertRange } from './other';\n\n/**\n * Circle Equation\n * x^2 + y^2 = radius^2\n * ----------------------\n * Circle Parametric Equation\n * x(t) = radius * cos(t)\n * y(t) = radius * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const circleMovement = (center: Vector2, angle: number, radius: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius,\n center[1] + Math.sin(angle) * radius\n ];\n};\n\n/**\n * Circle Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const circleMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radius: number\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return circleMovement(center, angle, radius);\n};\n\n/**\n * Ellipse Equation\n * (x - centerX)^2 / (radius1^2) + (y - centerY)^2 / (radius2^2) = 1\n * -----------------------------------------------------------------\n * Ellipse Parametric Equation\n * x(t) = radius1 * cos(t)\n * y(t) = radius2 * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const ellipseMovement = (center: Vector2, angle: number, radius1: number, radius2: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius1,\n center[1] + Math.sin(angle) * radius2\n ];\n};\n\n/**\n * Ellipse Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const ellipseMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radii: Vector2\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return ellipseMovement(center, angle, radii[0], radii[1]);\n};\n\n/**\n * Sine Wave Equation (Sinusoid)\n * -----------------------------\n * const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n * amplitude = the peak deviation of the function from zero\n * frequency = number of cycles\n * phase = specifies (in radians) where in its cycle the oscillation is at t = 0.\n * think of it as \"shifting\" the starting point of the function to the right (positive p) or left (negative)\n */\nexport const sineWaveMovement = (x: number, amplitude: number, frequency: number, phase: number) : Vector2 => {\n /*\n example values:\n const amplitude = 50;\n const frequency = 0.005;\n const phase = 0;\n x: [0, 1000]\n */\n const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n\n return [x, y];\n};\n\n/**\n * Lissajous curve (Lissajous figure or Bowditch curve)\n * Parametric equation #1\n * f(t) = A * sin(k * t + m)\n * f(t) = B * sin(n * t)\n * 0 <= m <= PI/2\n * k, n >= 1\n * -----------------------\n * Parametric equation #2\n * f(t) = A * cos(k * t - m)\n * f(t) = B * cos(n * t - p)\n * -----------------------------\n * Shapes:\n * k = 1, n = 1, m = 0, p = 0 ---> line\n * A = B, k = 1, n = 1, m = PI/2, p = PI/2 ----> circle\n * A != B, k = 1, n = 1, m = PI/2, p = PI/2 ----> ellipse\n * k = 2, n = 2, m = PI/2, p = PI/2 ----> section of a parabola\n */\nexport const lissajousCurve = (\n width: number,\n height: number,\n t: number,\n k: number,\n n: number,\n m: number,\n p: number\n) :Vector2 => {\n return [\n width * Math.cos(k * t - m),\n height * Math.cos(n * t - p),\n ];\n};\n", "import { getRandom } from './random';\nimport { HSLColor, RGBColor } from '../types';\nimport { mod } from './other';\nimport { setDecimalPlaces } from './format';\n\n// ------------------------ RANDOM COLOR -------------------------------------\n\nexport const getRandomRGBColor = () : RGBColor => {\n const hslColor = getRandomHSLColor();\n return hslToRgb(hslColor);\n};\n\nexport const getRandomHexColor = () : string => {\n const hslColor = getRandomHSLColor();\n return hslToHex(hslColor);\n};\n\nexport const getRandomHSLColor = () : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given hue\n */\nexport const getRandomHSLColorWithHue = (h: number) : HSLColor => {\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given saturation\n */\nexport const getRandomHSLColorWithSaturation = (s: number) : HSLColor => {\n const h = getRandom(1, 360);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given lightness\n */\nexport const getRandomHSLColorWithLightness = (l: number) : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n return [h, s, l];\n};\n\nexport const getRandomGrayscaleHSLColor = () : HSLColor => {\n const l = getRandom(0, 100);\n return [0, 0, l];\n};\n\nexport const getRandomHSLColorWithinRanges = (\n hueStart = 1, hueEnd = 360,\n saturationStart = 0, saturationEnd = 100,\n lightStart = 0, lightEnd = 100\n) : HSLColor => {\n const h = getRandom(hueStart, hueEnd);\n const s = getRandom(saturationStart, saturationEnd);\n const l = getRandom(lightStart, lightEnd);\n return [h, s, l];\n};\n\n// ----------------------- CONVERT COLORS --------------------------------------\n\n/**\n * helper: convert hue value to %\n * @param {number} h\n * @return {number} [0, 100] %\n */\nconst convertHueToPercent = (h : number) : number => {\n\n // the hue value needs to be multiplied by 60 to convert it to degrees\n h *= 60;\n\n // if hue becomes negative, you need to add 360 to, because a circle has 360 degrees\n if(h < 0){\n h += 360;\n }\n\n // convert huw to %\n return h * 100 / 360;\n};\n\n/**\n * get hue from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] % - we use here % instead of [0, 359] degrees\n */\nconst getHue = (r : number, g : number, b : number, min : number | undefined = undefined, max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no hue, as it's gray\n if(min === max) return 0;\n\n // if red is max\n if(max === r){\n return convertHueToPercent((g - b) / (max - min));\n }\n\n // if green is max\n if(max === g){\n return convertHueToPercent(2.0 + (b - r) / (max - min));\n }\n\n // if blue is max\n if(max === b){\n return convertHueToPercent(4.0 + (r - g) / (max - min));\n }\n\n return 0;\n};\n\n/**\n * get luminance from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] %\n */\nconst getLuminance = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // calculate the luminance value\n // @ts-ignore\n const l = (min + max) / 2; // [0, 1]\n\n // return l value in %\n return l * 100;\n};\n\n/**\n * get saturation from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @param {number|undefined=} l - luminance in [0, 100] %\n * @return {number} [0, 100] %\n */\nconst getSaturation = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined,\n l : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no saturation, as it's gray\n if(min === max) return 0;\n\n // calculate luminance if it's not provided\n l = (l === undefined) ? getLuminance(r, g, b) : l;\n\n // check the level of luminance\n const s = (l <= 50) ?\n // @ts-ignore\n ((max - min) / (max + min)) : // this formula is used when luminance <= 50%\n // @ts-ignore\n (max - min) / (2.0 - max - min); // this formula is used when luminance > 50%\n\n // return saturation in %\n return s * 100;\n};\n\nexport const rgbToHsl = (rgb: RGBColor, decimalPlaces = Infinity): HSLColor => {\n\n // convert rgb values to the range [0, 1]\n const r = rgb[0] / 255;\n const g = rgb[1] / 255;\n const b = rgb[2] / 255;\n\n // find the minimum and maximum values of r, g, and b\n const min = Math.min(r, g, b);\n const max = Math.max(r, g, b);\n\n // calculate the luminance value in %\n const l = getLuminance(r, g, b, min, max);\n\n // calculate the saturation in %\n const s = getSaturation(r, g, b, min, max, l);\n\n // calculate the hue in % (not in degrees!)\n const h = getHue(r, g, b, min, max);\n\n if(h > 360 || s > 100 || l > 100){\n return [0, 0, 100];\n }\n\n if(h < 0 || s < 0 || l < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(h, decimalPlaces),\n setDecimalPlaces(s, decimalPlaces),\n setDecimalPlaces(l, decimalPlaces),\n ];\n};\n\n/**\n * helper: HSL to RGB\n */\nconst hslToRgbHelper = (helper1 : number, helper2 : number, colorHelper : number) : number => {\n\n // all values need to be between 0 and 1\n // if you get a negative value you need to add 1 to it\n if(colorHelper < 0) colorHelper += 1;\n\n // if you get a value above 1 you need to subtract 1 from it.\n if(colorHelper > 1) colorHelper -= 1;\n\n if(colorHelper * 6 < 1) return helper2 + (helper1 - helper2) * 6 * colorHelper;\n\n if(colorHelper * 2 < 1) return helper1;\n\n if(colorHelper * 3 < 2){\n return helper2 + (helper1 - helper2) * (0.666 - colorHelper) * 6;\n }\n else{\n return helper2;\n }\n};\n\nexport const hslToRgb = (hsl: HSLColor, decimalPlaces = Infinity): RGBColor => {\n\n // convert all values to [0, 1] from %\n const h = hsl[0] / 100;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n // if there is no saturation -> it\u2019s grey\n if(s === 0){\n // convert the luminance from [0, 1] to [0, 255]\n const gray = l * 255;\n return [gray, gray, gray];\n }\n\n // check the level of luminance\n const helper1 = (l < 0.5) ?\n (l * (1.0 + s)) :\n (l + s - l * s);\n\n const helper2 = 2 * l - helper1;\n\n const rHelper = h + 0.333;\n const gHelper = h;\n const bHelper = h - 0.333;\n\n let r = hslToRgbHelper(helper1, helper2, rHelper);\n let g = hslToRgbHelper(helper1, helper2, gHelper);\n let b = hslToRgbHelper(helper1, helper2, bHelper);\n\n // convert rgb to [0, 255]\n r *= 255;\n g *= 255;\n b *= 255;\n\n if(r > 255 || g > 255 || b > 255){\n return [255, 255, 255];\n }\n\n if(r < 0 || g < 0 || b < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(r, decimalPlaces),\n setDecimalPlaces(g, decimalPlaces),\n setDecimalPlaces(b, decimalPlaces),\n ];\n};\n\n/**\n * HSL to hex\n * hslToHex(360, 100, 50) // [360, 100, 5] ==> \"#ff0000\" (red)\n */\nexport const hslToHex = (hsl: HSLColor) => {\n\n if(hsl[0] > 360 || hsl[1] > 100 || hsl[2] > 100){\n return '#ffffff';\n }\n\n if(hsl[0] < 0 || hsl[1] < 0 || hsl[2] < 0){\n return '#000000';\n }\n\n const h = hsl[0] / 360;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n let r, g, b;\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n};\n\n// ----------------------- GET SHIFTED COLORS --------------------------------------\n\nexport const getShiftedHue = (color: HSLColor, shift = 180) : HSLColor => {\n let hue = color[0];\n hue += shift;\n\n if (hue > 360 || hue < 0) {\n hue = mod(hue, 360);\n }\n\n return [hue, color[1], color[2]];\n};\n\nexport const getShiftedLightness = (color: HSLColor, shift = 10) : HSLColor => {\n let lightness = color[2];\n lightness += shift;\n\n if (lightness > 100 || lightness < 0) {\n lightness = mod(lightness, 100);\n }\n\n return [color[0], color[1], lightness];\n};\n\nexport const getShiftedSaturation = (color: HSLColor, shift = 10) : HSLColor => {\n let saturation = color[1];\n saturation += shift;\n\n if (saturation > 100) {\n saturation -= 100;\n }\n\n if(saturation < 0){\n saturation += 100;\n }\n\n return [color[0], saturation, color[2]];\n};\n", "/**\n * guid like '932ade5e-c515-4807-ac01-73b20ab3fb66'\n */\nexport const guid = () => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);\n });\n};\n\n/**\n * id like 'df4unio1opulby2uqh4'\n */\nexport const newId = () => {\n return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);\n};\n", "import { ICircle, IPolygon, IRect, Matrix2, Vector2 } from '../types';\nimport { mod } from './other';\nimport { v2GetNormal, v2DotProduct } from './linear-algebra/vector';\n\n/**\n * Rectangles collision detection.\n * Rectangles should not be rotated.\n * The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles.\n * Any gap means a collision does not exist.\n * Returns true if collision is detected.\n */\nexport const rectCollide = (rect1: IRect, rect2: IRect) : boolean => {\n return rect1.x <= rect2.x + rect2.w &&\n rect1.x + rect1.w >= rect2.x &&\n rect1.y <= rect2.y + rect2.h &&\n rect1.h + rect1.y >= rect2.y;\n};\n\n/**\n * Circles collision detection.\n * This algorithm works by taking the center points of the two circles\n * and ensuring the distance between the center points\n * are less than the two radii added together.\n * Returns true if collision is detected.\n */\nexport const circleCollide = (circle1: ICircle, circle2: ICircle) => {\n const dx = Math.abs(circle1.cx - circle2.cx);\n const dy = Math.abs(circle1.cy - circle2.cy);\n const distance = Math.sqrt(dx * dx + dy * dy);\n return distance <= circle1.r + circle2.r;\n};\n\n//-------------------- Separating Axis Theorem (SAT) Collision detection -------------------------\n\nconst getEdges = (poly: IPolygon) : Matrix2[] => {\n const edges: Matrix2[] = [];\n\n for(let i= 0; i {\n const edges: Matrix2[] = [];\n\n // collect polygon edges, and combine then into a single array\n edges.push(...getEdges(poly1));\n edges.push(...getEdges(poly2));\n\n // for each edge, find the normal vector and project both polygons onto it\n for (const edge of edges) {\n const normal = v2GetNormal(edge[0], edge[1]);\n const p1Proj = projectPolygon(poly1, normal);\n const p2Proj = projectPolygon(poly2, normal);\n\n // Check if the projections overlap\n const isOverlap = p1Proj.max >= p2Proj.min && p2Proj.max >= p1Proj.min;\n\n // Check if the projections overlap; if not, the polygons do not collide\n if (!isOverlap) return false;\n }\n\n // If all tests pass, the polygons overlap and collide\n return true;\n};\n\n/**\n * Project every polygon point onto the normal.\n * Then find min and max.\n */\nconst projectPolygon = (polygon: IPolygon, normal: Vector2): { min: number, max: number } => {\n let min = Infinity;\n let max = -Infinity;\n\n // Project each vertex of the polygon onto the axis\n for (const vertex of polygon) {\n const projection = v2DotProduct(vertex, normal);\n min = Math.min(min, projection);\n max = Math.max(max, projection);\n }\n\n return { min, max };\n};", "export interface IAnimationProps {\n duration?: number;\n callback: (result: IAnimationResult) => void;\n restartOnResize?: boolean;\n resizeCallback?: (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => void;\n}\n\nexport interface IAnimationResult {\n start: () => void;\n stop: () => void;\n pause: () => void;\n resume: () => void;\n restart: () => void;\n isAnimating: () => boolean;\n getStartTime: () => number|undefined;\n getElapsedTime: () => number|undefined;\n getPercent: () => number|undefined;\n getResizeObserver: () => ResizeObserver|undefined;\n}\n\nexport const animate = (props: IAnimationProps) : IAnimationResult => {\n\n const _duration = props.duration !== undefined ? props.duration : Infinity;\n\n let startTime: number|undefined = undefined; // in milliseconds\n let animationId: number|undefined = undefined;\n\n // the time elapsed since the start of the animation (in milliseconds)\n let elapsed: number|undefined = undefined;\n let previousTimeStamp: number|undefined = undefined;\n\n let animating = false;\n let observer: ResizeObserver|undefined = undefined;\n\n // -------------------- COMMANDS ---------------------\n\n const stop = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = false;\n\n /*if(observer !== undefined){\n observer.disconnect();\n observer = undefined;\n }*/\n\n if(animationId === undefined) return;\n window.cancelAnimationFrame(animationId);\n };\n\n const restart = () => {\n stop();\n start();\n };\n\n const pause = () => {\n animating = false;\n };\n\n const resume = () => {\n animating = true;\n };\n\n /**\n * Animation Step.\n * @param {number} timeStamp in milliseconds\n */\n const step = (timeStamp: DOMHighResTimeStamp) => {\n\n if (startTime === undefined) {\n startTime = timeStamp;\n }\n\n // the time elapsed since the start of the animation (in milliseconds)\n elapsed = timeStamp - startTime;\n\n if (animating && previousTimeStamp !== timeStamp && typeof props.callback === 'function') {\n\n // do the rendering .............\n props.callback(getResult());\n }\n\n if(elapsed <= _duration){\n previousTimeStamp = timeStamp;\n animationId = window.requestAnimationFrame(step);\n }\n else{\n stop();\n }\n };\n\n const observerHandler = (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => {\n restart();\n\n if(typeof props.resizeCallback === 'function'){\n props.resizeCallback(_entries, _observer);\n }\n };\n\n const start = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = true;\n\n if(props.restartOnResize && window.ResizeObserver && observer === undefined){\n observer = new ResizeObserver(observerHandler);\n observer.observe(document.body, { box: 'border-box' });\n }\n else{\n animationId = window.requestAnimationFrame(step);\n }\n };\n\n // --------------- GET INFO ----------------------\n\n /**\n * the time elapsed since the start of the animation (in milliseconds)\n */\n const getElapsedTime = () : number|undefined => {\n return elapsed;\n };\n\n const isAnimating = () => {\n return animating;\n };\n\n const getStartTime = () => {\n return startTime;\n };\n\n const getPercent = () => {\n if(_duration === Infinity || elapsed === undefined) return undefined;\n return elapsed * 100 / _duration;\n };\n\n const getResizeObserver = () => {\n return observer;\n };\n\n const getResult = () : IAnimationResult => {\n return {\n\n // commands --------------\n start,\n stop,\n pause,\n resume,\n restart,\n\n // information -------\n isAnimating,\n getElapsedTime,\n getStartTime,\n getPercent,\n getResizeObserver,\n };\n };\n\n return getResult();\n};\n", "import { setDecimalPlaces } from './format';\n\nexport const getCircleCircumference = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * radius, decimalPlaces);\n};\n\nexport const getEllipseCircumference = (radius1: number, radius2: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * Math.sqrt((radius1 ** 2 + radius2 ** 2) / 2), decimalPlaces);\n};\n\nexport const isAngleInCircleArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg ||\n (currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg;\n};\n\n/**\n * get the side of a square inscribed in a circle\n */\nexport const getSquareInCircleSide = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(radius * 2 / Math.sqrt(2), decimalPlaces);\n};\n", "import { setDecimalPlaces, Vector2 } from 'mz-math';\n\nexport interface ISvg {\n cx: number;\n cy: number;\n radius: number;\n size: number;\n thickness: number;\n border: number;\n startAngleDeg: number;\n endAngleDeg: number;\n}\n\nexport const getSvg = (\n circleRadius: number,\n circleThickness: number,\n circleBorder: number,\n maxPointerRadius: number,\n startAngleDeg: number,\n endAngleDeg: number\n) : ISvg => {\n\n const thickness = circleThickness + circleBorder * 2;\n\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n const size = circleRadius * 2 + thickness + diff;\n\n const [ cx, cy ] = getSVGCenter(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n return {\n cx,\n cy,\n radius: circleRadius,\n size,\n thickness: circleThickness,\n border: circleBorder,\n startAngleDeg,\n endAngleDeg\n } as ISvg;\n};\n\nconst getSVGCenter = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : Vector2 => {\n\n const size = getSVGSize(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n const val = setDecimalPlaces(size/2, 2);\n\n return [\n val,\n val,\n ];\n};\n\nconst getSVGSize = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : number => {\n const thickness = circleThickness + circleBorder * 2;\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n return circleRadius * 2 + thickness + diff;\n};", "// Data Defaults --------------------\nexport const DEFAULT_MIN = 0;\nexport const DEFAULT_MAX = 100;\nexport const DEFAULT_STEP = 1;\nexport const DEFAULT_ARROW_STEP = 1;\nexport const DEFAULT_ROUND = 0;\n\n// Path Defaults ---------------------\nexport const DEFAULT_PATH_START_ANGLE = 0;\nexport const DEFAULT_PATH_END_ANGLE = 360;\nexport const DEFAULT_PATH_RADIUS = 150;\nexport const DEFAULT_PATH_THICKNESS = 5;\nexport const DEFAULT_PATH_BG_COLOR = '#efefef';\nexport const DEFAULT_PATH_BORDER = 0;\nexport const DEFAULT_PATH_BORDER_COLOR = '#444444';\n\n// Pointer Defaults ------------------\nexport const DEFAULT_POINTER_RADIUS = 10;\nexport const DEFAULT_POINTER_BG_COLOR = '#163a86';\nexport const DEFAULT_POINTER_BG_COLOR_SELECTED = '#000';\nexport const DEFAULT_POINTER_BG_COLOR_DISABLED = '#a8a8a8';\nexport const DEFAULT_POINTER_BORDER = 0;\nexport const DEFAULT_POINTER_BORDER_COLOR = '#000';\n\n// Connection Defaults ------------------\nexport const DEFAULT_CONNECTION_BG_COLOR = '#5daed2';\nexport const DEFAULT_CONNECTION_BG_COLOR_DISABLED = '#97b0bb';\n\n// Text Defaults ------------------------\nexport const DEFAULT_TEXT_COLOR = '#000';\nexport const DEFAULT_TEXT_FONT_SIZE = 16;\n\n// Ticks Defaults -----------------------\nexport const DEFAULT_TICKS_ENABLED = false;\nexport const DEFAULT_TICKS_WIDTH = 3;\nexport const DEFAULT_TICKS_HEIGHT = 10;\nexport const DEFAULT_TICKS_COLOR = '#efefef';\nexport const DEFAULT_TICKS_VALUES_COLOR = '#000';\nexport const DEFAULT_TICKS_VALUES_FONT_SIZE = 12;\nexport const DEFAULT_TICKS_GROUP_SIZE = 10;\nexport const DEFAULT_TICKS_VALUES_DISTANCE = 15;\n\n// Animation Defaults -----------------------\nexport const DEFAULT_ANIMATION_DURATION = 200;\n\n\n", "import { isNumber } from 'mz-math';\n\nexport const getNumber = (value: number|string|undefined|null, defaultValue: number) : number => {\n return isNumber(value) ? Number(value) : defaultValue;\n};\n\nexport const getString = (value: string|undefined|null, defaultValue: string) : string => {\n return value === undefined || value === null ? defaultValue : value;\n};\n\nexport const getBoolean = (value: boolean|undefined|null, defaultValue: boolean) : boolean => {\n return value === undefined || value === null ? defaultValue : value;\n};", "import { mod } from 'mz-math';\n\nexport interface ICircle {\n strokeDasharray: string;\n strokeOffset: number;\n}\n\nexport const isAngleInArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return (currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg) ||\n ((currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg);\n};\n\nexport const getAnglesDistance = (startAngle: number, endAngle: number) => {\n if(endAngle < startAngle) {\n endAngle += 360;\n }\n\n const diff = endAngle - startAngle;\n const diffMod = mod(diff, 360);\n\n return diffMod === 0 && diff > 0 ? 360 : diffMod;\n};\n\nexport const getCircle = (\n startAngleDeg: number,\n endAngleDeg: number,\n radius: number,\n) : ICircle => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n const circumference = 2 * Math.PI * radius;\n const angleDiff = endAngleDeg - startAngleDeg;\n const strokeOffset = -(startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDiff / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n return {\n strokeDasharray: [ strokeDasharray, complement ].join(' '),\n strokeOffset,\n } as ICircle;\n};", "import {\n Vector2,\n convertRange,\n mod,\n setDecimalPlaces,\n v2Sub,\n radiansToDegrees,\n degreesToRadians, circleMovement, v2Distance\n} from 'mz-math';\nimport { ISettings } from './settings-provider';\nimport {\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_POINTER_BG_COLOR,\n DEFAULT_POINTER_BG_COLOR_DISABLED,\n DEFAULT_POINTER_BG_COLOR_SELECTED,\n DEFAULT_POINTER_BORDER,\n DEFAULT_POINTER_BORDER_COLOR,\n DEFAULT_POINTER_RADIUS,\n} from './defaults-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport { IData } from './data-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IPointer {\n id: string;\n index: number;\n radius: number;\n angleDeg: number;\n prevAngleDeg: number;\n\n bgColor: string;\n bgColorSelected: string;\n bgColorDisabled: string;\n bgColorHover: string;\n\n border: number;\n borderColor: string;\n\n disabled: boolean;\n ariaLabel?: string;\n}\n\nexport interface IPointers {\n pointers: IPointer[];\n maxRadius: number;\n}\n\nexport const getAngleByMouse = (\n $svg: SVGSVGElement,\n clientX: number,\n clientY: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number\n) => {\n const { left, top } = $svg.getBoundingClientRect();\n\n const relativeMouse: Vector2 = [\n clientX - left,\n clientY - top,\n ];\n\n const vector = v2Sub(relativeMouse, [ cx, cy ]);\n\n let angleRad = Math.atan2(vector[1] / ry, vector[0] / rx);\n if(angleRad < 0){\n angleRad += 2 * Math.PI;\n }\n\n return radiansToDegrees(angleRad);\n};\n\nexport const angle2value = (data: IData, angle: number, pathStartAngle: number, pathEndAngle: number) : string | number => {\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(angle < pathStartAngle){\n angle += 360;\n }\n\n let value: string|number = convertRange(angle, pathStartAngle, pathEndAngle, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n return value;\n};\n\nconst value2angle = (data: IData, value: string | number, pathStartAngle: number, pathEndAngle: number) => {\n let _value: number;\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(data.data.length > 0) {\n const valueIndex = data.data.findIndex(item => item === value);\n _value = valueIndex === -1 ? 0 : valueIndex;\n }\n else{\n _value = typeof value !== 'number' ? data.min : value;\n }\n\n return mod(convertRange(_value, data.min, data.max, pathStartAngle, pathEndAngle), 360);\n};\n\nconst initPointers = (\n settings: ISettings,\n data: IData\n) : IPointer[] => {\n\n if(!settings || !settings.pointers || settings.pointers.length < 0 || !data) {\n const angleDeg = mod(getNumber(settings.pathStartAngle, DEFAULT_PATH_START_ANGLE), 360);\n\n const bgColor = getString(settings.pointerBgColor, DEFAULT_POINTER_BG_COLOR);\n const bgColorSelected = getString(settings.pointerBgColorSelected, DEFAULT_POINTER_BG_COLOR_SELECTED);\n const bgColorDisabled = getString(settings.pointerBgColorDisabled, DEFAULT_POINTER_BG_COLOR_DISABLED);\n const bgColorHover = getString(settings.pointerBgColorHover, bgColorSelected);\n\n return [{\n id: '0',\n index: 0,\n radius: getNumber(settings.pointerRadius, DEFAULT_POINTER_RADIUS),\n angleDeg,\n prevAngleDeg: angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border: getNumber(settings.pointerBorder, DEFAULT_POINTER_BORDER),\n borderColor: getString(settings.pointerBorderColor, DEFAULT_POINTER_BORDER_COLOR),\n disabled: !!settings.disabled,\n }]\n }\n\n const pointers: IPointer[] = [];\n\n for(let i=0; i {\n\n const pointers = initPointers(settings, data);\n\n return {\n pointers,\n maxRadius: getMaxRadius(pointers),\n }\n};\n\nconst getMaxRadius = (pointers: IPointer[]) : number => {\n if(pointers.length <= 0) return 0;\n\n let max = -Infinity;\n\n for(const pointer of pointers){\n max = Math.max(max, Math.max(0, pointer.radius + pointer.border/2));\n }\n\n return max;\n};\n\nexport const getClosestPointer = (\n pointers: IPointer[],\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n if(!pointers || pointers.length <= 0) return null;\n\n if(pointers.length === 1) return pointers[0];\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n let min: number|undefined = undefined;\n let closestPointer: IPointer = null;\n\n const enabledPointers = pointers.filter(p => !p.disabled);\n\n for(const pointer of enabledPointers) {\n const pointerAngleRad = convertRange(degreesToRadians(pointer.angleDeg), 0, Math.PI * 2, 0, Math.PI);\n const pointOnArc = circleMovement([ cx, cy ], pointerAngleRad, pathRadius);\n const distance = v2Distance(currentPointOnArc, pointOnArc);\n\n if(min === undefined || distance < min) {\n min = distance;\n closestPointer = pointer;\n }\n }\n\n return { ...closestPointer };\n};\n\nexport const getClosestEdge = (\n startAngleDegrees: number,\n endAngleDegrees: number,\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n const startAngleRad = convertRange(degreesToRadians(startAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const startPointOnArc = circleMovement([ cx, cy ], startAngleRad, pathRadius);\n\n const endAngleRad = convertRange(degreesToRadians(endAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const endPointOnArc = circleMovement([ cx, cy ], endAngleRad, pathRadius);\n\n const distance1 = v2Distance(currentPointOnArc, startPointOnArc);\n const distance2 = v2Distance(currentPointOnArc, endPointOnArc);\n\n return distance1 <= distance2 ? startAngleDegrees : endAngleDegrees;\n};\n\nexport const getMinMaxDistancePointers = (pointers: IPointer[], pathStartAngle: number) : [IPointer, IPointer] | null => {\n if(!pointers || pointers.length <= 0) return null;\n\n let minDistance = undefined;\n let maxDistance = undefined;\n let minPointer = null;\n let maxPointer = null;\n\n for(const pointer of pointers) {\n\n const distance = getAnglesDistance(pathStartAngle, pointer.angleDeg);\n\n if(minDistance === undefined || distance < minDistance) {\n minPointer = pointer;\n minDistance = distance;\n }\n\n if(maxDistance === undefined || distance > maxDistance) {\n maxPointer = pointer;\n maxDistance = distance;\n }\n }\n\n if(minPointer === null || maxPointer === null) return null;\n\n return [\n minPointer,\n maxPointer\n ];\n};\n\nexport const roundToStep = (angleDeg: number, step: number, pathStartAngle: number, pathEndAngle: number) : number => {\n if((mod(angleDeg, 360) === mod(pathStartAngle, 360)) ||\n (mod(angleDeg, 360) === mod(pathEndAngle, 360))) return angleDeg;\n return step === 0 ? 0 : Math.round(angleDeg / step) * step;\n};\n", "import { angle2value, getAngleByMouse, getClosestEdge, IPointer } from '../domain/pointers-provider';\nimport {\n useEffect,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n KeyboardEvent,\n useRef, useCallback,\n} from 'react';\nimport { circleMovement, convertRange, degreesToRadians, Vector2 } from 'mz-math';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { isAngleInArc } from '../domain/circle-provider';\nimport { IData } from '../domain/data-provider';\nimport { outlineNoneStyle } from '../domain/style-provider';\nimport { DEFAULT_POINTER_BG_COLOR } from '../domain/defaults-provider';\n\nexport interface IPointerProps {\n settings: ISettings;\n pointer: IPointer;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst getPointerFill = (\n pointer: IPointer,\n selectedPointerId: string,\n bgColor: string,\n bgColorSelected: string,\n bgColorDisabled: string,\n bgColorHover: string,\n isMouseOver: boolean\n) => {\n if(pointer.disabled) return bgColorDisabled;\n\n if(isMouseOver) return bgColorHover;\n\n if(pointer.id === selectedPointerId) {\n return bgColorSelected;\n }\n\n return bgColor;\n};\n\nconst Pointer = (props: IPointerProps) => {\n\n const pointerRef = useRef(null);\n\n const {\n pointer, svg, $svg, data, settings,\n setPointer, selectedPointerId,\n } = props;\n\n const {\n radius,\n angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border,\n borderColor,\n } = props.pointer;\n\n const { cx, cy } = svg;\n\n const [ center, setCenter ] = useState(null);\n const [ value, setValue ] = useState('');\n const [ fill, setFill ] = useState(DEFAULT_POINTER_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n useEffect(() => {\n setFill(getPointerFill(\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ));\n }, [\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ]);\n\n useEffect(() => {\n const value = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n setValue(value === undefined ? '' : value.toString())\n }, [\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const angleRad = convertRange(degreesToRadians(angleDeg), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const pointerCenter = circleMovement([cx, cy], angleRad, svg.radius);\n setCenter(pointerCenter);\n }, [\n angleDeg,\n cx,\n cy,\n svg.radius,\n ]);\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent | TouchEvent | ReactTouchEvent) => {\n if(!$svg || settings.disabled || pointer.disabled) return;\n\n const mouseX = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientX : (evt as TouchEvent).touches[0].clientX;\n const mouseY = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientY : (evt as TouchEvent).touches[0].clientY;\n\n const degrees = getAngleByMouse(\n $svg,\n mouseX,\n mouseY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n let newAngleDeg;\n\n if(!isAngleInArc(\n svg.startAngleDeg,\n svg.endAngleDeg,\n degrees\n )){\n newAngleDeg = getClosestEdge(\n svg.startAngleDeg,\n svg.endAngleDeg,\n pointer.angleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n else{\n newAngleDeg = degrees;\n }\n\n setPointer(pointer, newAngleDeg);\n }, [\n $svg,\n pointer,\n setPointer,\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n settings.disabled,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n const onKeyDown = (evt: KeyboardEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.keyboardDisabled) return;\n\n switch (evt.key) {\n case 'ArrowLeft': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowRight': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowUp': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowDown': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n }\n };\n\n useEffect(() => {\n const $current = pointerRef.current;\n\n const onTouch = (evt: TouchEvent | ReactTouchEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n onValueChange(evt);\n };\n\n const onWheel = (evt: WheelEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.mousewheelDisabled || document.activeElement !== $current) return;\n\n evt.stopPropagation();\n evt.preventDefault();\n\n const scrollTop = evt.deltaY < 0;\n\n let newAngleDeg;\n if(scrollTop) {\n newAngleDeg = pointer.angleDeg + data.arrowStepAngleDeg;\n }\n else{\n newAngleDeg = pointer.angleDeg - data.arrowStepAngleDeg;\n }\n\n setPointer(pointer, newAngleDeg);\n };\n\n $current?.addEventListener('touchmove', onTouch, {\n passive: false,\n });\n\n document.addEventListener('wheel', onWheel, {\n passive: false,\n });\n\n return () => {\n $current?.removeEventListener('touchmove', onTouch);\n document.removeEventListener('wheel', onWheel);\n };\n }, [\n center,\n onValueChange,\n data.arrowStepAngleDeg,\n pointer,\n setPointer,\n settings.disabled,\n settings.mousewheelDisabled,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n center &&\n \n\n {\n !settings.pointerSVG &&\n \n }\n\n {\n settings.pointerSVG &&\n \n { settings.pointerSVG }\n \n }\n \n }\n \n )\n};\n\nexport default Pointer;", "export const outlineNoneStyle = {\n outline: 'none',\n};", "import { IPointer, IPointers } from '../domain/pointers-provider';\nimport Pointer from './Pointer';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\nexport interface IPointersProps {\n pointers: IPointers;\n settings: ISettings;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst Pointers = (props: IPointersProps) => {\n\n const {\n pointers, settings, svg, $svg, data,\n setPointer, selectedPointerId,\n } = props;\n\n return (\n <>\n {\n pointers.pointers.map(pointer => {\n\n return (\n \n )\n })\n }\n \n )\n};\n\nexport default Pointers;", "import { ISettings } from './settings-provider';\nimport { getNumber } from './common-provider';\nimport {\n DEFAULT_ARROW_STEP,\n DEFAULT_MAX,\n DEFAULT_MIN,\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_ROUND,\n DEFAULT_STEP\n} from './defaults-provider';\nimport { mod } from 'mz-math';\n\nexport interface IData {\n min: number;\n max: number;\n stepAngleDeg: number;\n arrowStepAngleDeg: number;\n round: number;\n data: (string | number)[];\n isClosedShape: boolean;\n}\n\nexport const getData = (setting: ISettings) : IData => {\n\n let min = getNumber(setting.min, DEFAULT_MIN);\n let max = getNumber(setting.max, DEFAULT_MAX);\n const step = getNumber(setting.step, DEFAULT_STEP);\n const arrowStep = getNumber(setting.arrowStep, DEFAULT_ARROW_STEP);\n const round = getNumber(setting.round, DEFAULT_ROUND);\n const data = setting.data || [];\n\n if(data.length > 0) {\n const minIndex = data.findIndex(item => item === min);\n const maxIndex = data.findIndex(item => item === max);\n\n min = minIndex === -1 ? 0 : minIndex;\n max = maxIndex === -1 ? data.length : maxIndex;\n }\n else{\n if(min > max) {\n min = max + DEFAULT_MAX;\n }\n }\n\n const pathStartAngle = getNumber(setting.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n const pathEndAngle = getNumber(setting.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n const isClosedShape = mod(pathStartAngle, 360) === mod(pathEndAngle, 360);\n\n const stepAngleDeg = step * 360 / (max - min);\n const arrowStepAngleDeg = arrowStep * 360 / (max - min);\n\n return {\n min,\n max,\n round,\n data,\n stepAngleDeg,\n arrowStepAngleDeg,\n isClosedShape,\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_CONNECTION_BG_COLOR,\n DEFAULT_CONNECTION_BG_COLOR_DISABLED\n} from '../domain/defaults-provider';\nimport {\n getAngleByMouse,\n getClosestPointer,\n getMinMaxDistancePointers,\n IPointer,\n IPointers\n} from '../domain/pointers-provider';\nimport {\n MouseEvent as ReactMouseEvent,\n useCallback,\n useEffect, useRef,\n useState\n} from 'react';\nimport { getConnection, IConnection } from '../domain/connection-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\nimport { animate, IAnimationResult, mod } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\n\ninterface IConnectionProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst getStroke = (\n disabled: boolean,\n connectionBgColorDisabled: string,\n connectionBgColor: string,\n isMouseOver: boolean,\n connectionBgColorHover: string\n) => {\n if(disabled) return getString(connectionBgColorDisabled, DEFAULT_CONNECTION_BG_COLOR_DISABLED);\n\n const bgColor = getString(connectionBgColor, DEFAULT_CONNECTION_BG_COLOR);\n\n if(isMouseOver) {\n return getString(connectionBgColorHover, bgColor);\n }\n\n return bgColor;\n};\n\nconst Connection = (props: IConnectionProps) => {\n\n const { settings, pointers, $svg, svg, data, setPointer } = props;\n\n const [ connection, setConnection ] = useState(null);\n const [ animation, setAnimation ] = useState(null);\n const [ stroke, setStroke ] = useState(DEFAULT_CONNECTION_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n const rangeDraggingLastAngle = useRef();\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setStroke(getStroke(\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n isMouseOver,\n settings.connectionBgColorHover\n ));\n }, [\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n settings.connectionBgColorHover,\n isMouseOver,\n ]);\n\n useEffect(() => {\n setConnection(getConnection(\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n }, [\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ]);\n\n const onClick = (evt: ReactMouseEvent) => {\n\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // RANGE DRAGGING -------------------------------------------\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent) => {\n if(!$svg || settings.disabled || !settings.rangeDragging) return;\n\n const minMaxResult = getMinMaxDistancePointers(pointers.pointers, svg.startAngleDeg);\n if(!minMaxResult) return;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n const mouseDegrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n if(rangeDraggingLastAngle.current === undefined) {\n rangeDraggingLastAngle.current = mouseDegrees;\n return;\n }\n\n const diff = (mouseDegrees - rangeDraggingLastAngle.current);\n if(diff === 0 || Math.abs(diff) < data.stepAngleDeg) return;\n\n setPointer(minPointer, mod(minPointer.angleDeg + diff, 360));\n setPointer(maxPointer, mod(maxPointer.angleDeg + diff, 360));\n\n rangeDraggingLastAngle.current = mouseDegrees;\n }, [\n $svg,\n svg.cx,\n svg.cy,\n svg.radius,\n data.stepAngleDeg,\n pointers.pointers,\n setPointer,\n settings.disabled,\n settings.rangeDragging,\n svg.startAngleDeg,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n\n rangeDraggingLastAngle.current = undefined;\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(!settings.rangeDragging || settings.disabled || pointers.pointers.length <= 1) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n !getBoolean(settings.hideConnection, false) && connection &&\n \n }\n \n )\n};\n\nexport default Connection;", "import { IPointers } from './pointers-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IConnection {\n radius: number;\n cx: number;\n cy: number;\n\n // calculated properties ---------\n startAngleDeg: number;\n endAngleDeg: number;\n strokeDasharray: number[];\n strokeOffset: number;\n}\n\nexport const getConnection = (\n pointers: IPointers,\n radius: number,\n cx: number,\n cy: number,\n pathStartAngle: number,\n pathEndAngle: number,\n) : IConnection => {\n\n if(!pointers.pointers || pointers.pointers.length <= 0) return null;\n\n const result : IConnection = {\n radius,\n cx,\n cy,\n\n // calculated properties ---------\n startAngleDeg: pathStartAngle,\n endAngleDeg: pathStartAngle,\n strokeDasharray: [0, 0],\n strokeOffset: 0,\n };\n\n // Define start/end angles.\n if(pointers.pointers.length === 1) {\n result.startAngleDeg = pathStartAngle;\n result.endAngleDeg = pointers.pointers[0].angleDeg;\n }\n else{\n result.startAngleDeg = pointers.pointers[0].angleDeg;\n result.endAngleDeg = pointers.pointers[pointers.pointers.length - 1].angleDeg;\n\n /*const minMaxResult = getMinMaxDistancePointers(pointers.pointers, pathStartAngle);\n if(!minMaxResult) return null;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n result.startAngleDeg = minPointer.angleDeg;\n result.endAngleDeg = maxPointer.angleDeg;*/\n }\n\n const pathAnglesDistance = getAnglesDistance(pathStartAngle, pathEndAngle);\n\n if(result.startAngleDeg > result.endAngleDeg) {\n result.endAngleDeg += 360;\n }\n\n let angleDistance = getAnglesDistance(result.startAngleDeg, result.endAngleDeg);\n\n const shouldSwitch = angleDistance > pathAnglesDistance;\n\n if(shouldSwitch) {\n angleDistance = 360 - angleDistance;\n [result.startAngleDeg, result.endAngleDeg] = [result.endAngleDeg, result.startAngleDeg];\n }\n\n const circumference = 2 * Math.PI * radius;\n const strokeOffset = -(result.startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDistance / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n result.strokeDasharray = [ strokeDasharray, complement ];\n result.strokeOffset = strokeOffset;\n\n return result;\n};", "import { IAnimationResult, mod } from 'mz-math';\n\nexport const getAnimationProgressAngle = (\n progress: IAnimationResult,\n animationSourceDegrees: number,\n animationTargetDegrees: number,\n startPathAngleDeg: number\n) => {\n let percent = progress.getPercent();\n\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n let angle1 = animationSourceDegrees % 360;\n let angle2 = animationTargetDegrees % 360;\n\n if(angle1 < startPathAngleDeg) {\n angle1 += 360;\n }\n\n if(angle2 < startPathAngleDeg) {\n angle2 += 360;\n }\n\n const isClockwise = angle2 > angle1;\n\n if(isClockwise) {\n const clockwiseDistance = (angle2 - angle1 + 360) % 360;\n return mod(animationSourceDegrees + (percent * clockwiseDistance / 100), 360);\n }\n else {\n const counterclockwiseDistance = (angle1 - angle2 + 360) % 360;\n return mod(animationSourceDegrees - (percent * counterclockwiseDistance / 100), 360);\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { angle2value, IPointers } from '../domain/pointers-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE\n} from '../domain/defaults-provider';\nimport { useEffect, useState } from 'react';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITextProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n data: IData;\n}\n\nconst Text = (props: ITextProps) => {\n\n const { settings, pointers, svg, data } = props;\n\n const { cx, cy } = svg;\n const [ value, setValue ] = useState('');\n\n useEffect(() => {\n\n const values = pointers.pointers.map(pointer => angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n\n values.sort((value1, value2) => {\n return value1.toString().localeCompare(\n value2.toString(),\n 'en',\n { numeric: true }\n );\n });\n\n const texts = values.map(value => `${ settings.textPrefix || '' }${ value }${ settings.textSuffix || '' }`);\n\n const textBetween = getString(settings.textBetween, ' ');\n setValue(texts.join(textBetween));\n\n }, [\n data,\n pointers.pointers,\n svg.startAngleDeg,\n svg.endAngleDeg,\n settings.textPrefix,\n settings.textSuffix,\n settings.textBetween,\n ]);\n\n const hideText = getBoolean(settings.hideText, false);\n\n return (\n <>\n {\n !hideText &&\n \n\n { value }\n\n \n }\n \n )\n};\n\nexport default Text;", "import { useEffect, useState, Fragment } from 'react';\nimport { getTicks, getTicksSettings, ITick, ITicks } from '../domain/ticks-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITicksProps {\n settings: ISettings;\n svg: ISvg;\n data: IData;\n}\n\nconst Ticks = (props: ITicksProps) => {\n\n const { settings, svg, data } = props;\n\n const [ ticksSettings, setTicksSettings ] = useState(null);\n const [ ticks, setTicks ] = useState([]);\n\n useEffect(() => {\n setTicksSettings(getTicksSettings(settings, data));\n }, [\n settings,\n data,\n ]);\n\n useEffect(() => {\n if(!ticksSettings) return;\n\n let endAngleDeg = svg.endAngleDeg;\n if(endAngleDeg < svg.startAngleDeg) {\n endAngleDeg += 360;\n }\n\n setTicks(getTicks(\n ticksSettings,\n ticksSettings.ticksCount,\n svg.startAngleDeg,\n endAngleDeg,\n svg,\n data\n ));\n }, [\n data,\n svg,\n ticksSettings,\n ]);\n\n return (\n <>\n {\n ticksSettings && ticksSettings.enableTicks &&\n \n {\n ticks.map((tick, i) => {\n const { x, y, x1, y1, textX, textY, showText } = tick;\n\n return (\n \n \n\n {\n showText &&\n \n { settings.tickValuesPrefix }{ tick.tickValue }{ settings.tickValuesSuffix }\n \n }\n \n );\n })\n }\n \n }\n \n )\n};\n\nexport default Ticks;", "import {\n circleMovement,\n convertRange,\n degreesToRadians,\n setDecimalPlaces,\n v2MulScalar,\n v2Normalize\n} from 'mz-math';\nimport { ISvg } from './svg-provider';\nimport { IData } from './data-provider';\nimport { ISettings } from './settings-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport {\n DEFAULT_TICKS_COLOR, DEFAULT_TICKS_ENABLED, DEFAULT_TICKS_GROUP_SIZE,\n DEFAULT_TICKS_HEIGHT, DEFAULT_TICKS_VALUES_COLOR,\n DEFAULT_TICKS_VALUES_DISTANCE, DEFAULT_TICKS_VALUES_FONT_SIZE,\n DEFAULT_TICKS_WIDTH\n} from './defaults-provider';\n\nexport interface ITicks {\n ticksCount: number;\n enableTicks: boolean;\n ticksWidth: number;\n ticksHeight: number;\n longerTicksHeight: number;\n ticksDistanceToPanel: number;\n tickValuesDistance: number;\n ticksColor: string;\n tickValuesColor: string;\n tickValuesFontSize: number;\n ticksGroupSize: number;\n longerTickValuesOnly: boolean;\n showTickValues: boolean;\n}\n\nexport interface ITick {\n x: number;\n y: number;\n x1: number;\n y1: number;\n textX: number;\n textY: number;\n isLonger: boolean;\n showText: boolean;\n tickValue?: string;\n}\n\nexport const getTicksSettings = (settings: ISettings, data: IData) : ITicks => {\n\n let ticksCount = getNumber(settings.ticksCount, 0);\n if(!ticksCount) {\n if(data.data && data.data.length > 0) {\n ticksCount = data.data.length;\n }\n else{\n ticksCount = data.max;\n }\n }\n\n const ticksHeight = getNumber(settings.ticksHeight, DEFAULT_TICKS_HEIGHT);\n\n return {\n ticksCount,\n enableTicks: getBoolean(settings.enableTicks, DEFAULT_TICKS_ENABLED),\n ticksWidth: getNumber(settings.ticksWidth, DEFAULT_TICKS_WIDTH),\n ticksHeight,\n longerTicksHeight: getNumber(settings.longerTicksHeight, ticksHeight * 2),\n ticksDistanceToPanel: getNumber(settings.ticksDistanceToPanel, 0),\n tickValuesDistance: getNumber(settings.tickValuesDistance, DEFAULT_TICKS_VALUES_DISTANCE),\n ticksColor: getString(settings.ticksColor, DEFAULT_TICKS_COLOR),\n tickValuesColor: getString(settings.tickValuesColor, DEFAULT_TICKS_VALUES_COLOR),\n tickValuesFontSize: getNumber(settings.tickValuesFontSize, DEFAULT_TICKS_VALUES_FONT_SIZE),\n ticksGroupSize: getNumber(settings.ticksGroupSize, DEFAULT_TICKS_GROUP_SIZE),\n longerTickValuesOnly: getBoolean(settings.longerTickValuesOnly, true),\n showTickValues: getBoolean(settings.showTickValues, true),\n };\n};\n\nexport const getTicks = (\n ticksSettings: ITicks,\n ticksCount: number,\n pathStartAngle: number,\n pathEndAngle: number,\n svg: ISvg,\n data: IData\n) : ITick[] => {\n\n const ticks: ITick[] = [];\n\n const deltaAngle = Math.abs(pathEndAngle - pathStartAngle);\n const oneTickAngleSize = ticksCount === 0 ? 0 : deltaAngle / ticksCount;\n\n let count = ticksCount;\n if(!data.isClosedShape) {\n count++;\n }\n\n for(let i=0; i [0, Math.PI]\n\n let [x, y] = circleMovement([svg.cx, svg.cy], angleRad, svg.radius);\n\n const isLonger = ticksSettings.ticksGroupSize !== undefined && (i % ticksSettings.ticksGroupSize === 0 );\n\n let desiredDistance = ticksSettings.ticksHeight;\n\n if(isLonger) {\n desiredDistance = ticksSettings.longerTicksHeight;\n }\n\n const normalizedDirectionVector = v2Normalize([svg.cx - x, svg.cy - y]);\n const tickEndVector = v2MulScalar(normalizedDirectionVector, desiredDistance);\n\n const tickStartVector = v2MulScalar(normalizedDirectionVector, ticksSettings.ticksDistanceToPanel + svg.thickness/2);\n x += tickStartVector[0];\n y += tickStartVector[1];\n\n const x1 = x + tickEndVector[0];\n const y1 = y + tickEndVector[1];\n\n // ------- Define tick value. ---------------------\n let tickValue: string|undefined = undefined;\n if(ticksSettings.showTickValues && (!ticksSettings.longerTickValuesOnly || ticksSettings.longerTickValuesOnly && (isLonger || ticksSettings.ticksGroupSize === undefined))) {\n\n let value: string|number = convertRange(i, 0, ticksCount, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n tickValue = (value ?? '').toString();\n }\n\n let textX = 0;\n let textY = 0;\n const showText = tickValue !== undefined;\n\n if(showText) {\n const _tickValuesDistance = getNumber(desiredDistance + ticksSettings.tickValuesDistance, desiredDistance * 1.5);\n const tickTextVector = v2MulScalar(normalizedDirectionVector, _tickValuesDistance);\n textX = x + tickTextVector[0];\n textY = y + tickTextVector[1];\n }\n\n ticks.push({\n x,\n y,\n x1,\n y1,\n textX,\n textY,\n isLonger,\n tickValue,\n showText,\n });\n }\n\n return ticks;\n};", "import { useEffect, useState, MouseEvent, useRef } from 'react';\nimport { getCircle, ICircle } from '../domain/circle-provider';\nimport { getNumber, getString } from '../domain/common-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_PATH_BG_COLOR,\n DEFAULT_PATH_BORDER_COLOR,\n} from '../domain/defaults-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { getAngleByMouse, getClosestPointer, IPointer, IPointers } from '../domain/pointers-provider';\nimport { animate, IAnimationResult, newId } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\nimport InnerCircle from './InnerCircle';\n\ninterface ICircleProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst Circle = (props: ICircleProps) => {\n\n const { settings, pointers, $svg, svg, setPointer } = props;\n\n const [ animation, setAnimation ] = useState(null);\n const [ maskId ] = useState(newId());\n const [ circle, setCircle ] = useState({\n strokeDasharray: '0 1000000',\n strokeOffset: 0,\n });\n\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setCircle(getCircle(\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius\n ));\n }, [\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius,\n ]);\n\n const onClick = (evt: MouseEvent) => {\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n return (\n \n\n {\n settings.pathInnerBgColor &&\n \n }\n\n {\n svg.border > 0 &&\n \n }\n\n \n \n )\n};\n\nexport default Circle;\n", "import { ISvg } from '../domain/svg-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ICircle } from '../domain/circle-provider';\nimport { useEffect, useState } from 'react';\nimport { circleMovement, convertRange, degreesToRadians, mod, Vector2 } from 'mz-math';\nimport { getBoolean } from '../domain/common-provider';\n\ninterface IInnerCircleProps {\n maskId: string;\n settings: ISettings;\n svg: ISvg;\n circle: ICircle;\n}\n\nconst InnerCircle = (props: IInnerCircleProps) => {\n\n const { svg, maskId, settings, circle } = props;\n\n const [ startPoint, setStartPoint ] = useState([0, 0]);\n const [ endPoint, setEndPoint ] = useState([0, 0]);\n const [ largeArcFlag, setLargeArcFlag ] = useState(0);\n const [ pathInnerBgFull, setPathInnerBgFull] = useState(false);\n\n useEffect(() => {\n if(mod(svg.startAngleDeg, 360) === mod(svg.endAngleDeg, 360)) {\n setPathInnerBgFull(true);\n return;\n }\n\n setPathInnerBgFull(getBoolean(settings.pathInnerBgFull, false));\n }, [\n settings.pathInnerBgFull,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const startAngleDeg = convertRange(svg.startAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setStartPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(startAngleDeg), svg.radius));\n\n const endAngleDeg = convertRange(svg.endAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setEndPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(endAngleDeg), svg.radius));\n\n const largeArcFlag = svg.endAngleDeg - svg.startAngleDeg <= 180 ? 1 : 0;\n setLargeArcFlag(largeArcFlag);\n }, [\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n ]);\n\n return (\n <>\n {\n !pathInnerBgFull &&\n \n \n \n \n }\n\n \n \n )\n};\n\nexport default InnerCircle;"], - "mappings": "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", + "sourcesContent": ["import { useEffect, useRef, useState } from 'react';\nimport { getSvg, ISvg } from './domain/svg-provider';\nimport { angle2value, getClosestEdge, getPointers, IPointer, IPointers, roundToStep } from './domain/pointers-provider';\nimport { ISettings, ISettingsPointer } from './domain/settings-provider';\nimport { getNumber } from './domain/common-provider';\nimport {\n DEFAULT_PATH_BORDER, DEFAULT_PATH_END_ANGLE, DEFAULT_PATH_RADIUS, DEFAULT_PATH_START_ANGLE,\n DEFAULT_PATH_THICKNESS\n} from './domain/defaults-provider';\nimport Pointers from './ui/Pointers';\nimport { getData, IData } from './domain/data-provider';\nimport Connection from './ui/Connection';\nimport Text from './ui/Text';\nimport Ticks from './ui/Ticks';\nimport Circle from './ui/Circle';\nimport { mod } from 'mz-math';\nimport { isAngleInArc } from './domain/circle-provider';\nimport { outlineNoneStyle } from './domain/style-provider';\n\nexport const RoundSlider = (props: ISettings) => {\n\n const [ data, setData ] = useState(null);\n const [ svg, setSvg ] = useState(null);\n const [ pointers, setPointers ] = useState(null);\n const [ selectedPointerId, setSelectedPointerId ] = useState('');\n\n const prevAngleDegRef = useRef(null);\n const svgRef = useRef(null);\n\n useEffect(() => {\n const _data = getData(props);\n const hasChanged = JSON.stringify(data) !== JSON.stringify(_data);\n if(!hasChanged) return;\n\n setData(_data);\n }, [\n data,\n props\n ]);\n\n useEffect(() => {\n setPointers(getPointers(props, data));\n },\n // eslint-disable-next-line\n [\n props.pointerRadius,\n props.pathStartAngle,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pointers,\n props.pointerRadius,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pathStartAngle,\n props.pathEndAngle,\n data,\n ]);\n\n useEffect(() => {\n if(!pointers) return;\n\n const pathStartAngle = getNumber(props.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n let pathEndAngle = getNumber(props.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n\n if(pathEndAngle <= pathStartAngle) {\n pathEndAngle += 360;\n }\n\n setSvg(getSvg(\n getNumber(props.pathRadius, DEFAULT_PATH_RADIUS),\n getNumber(props.pathThickness, DEFAULT_PATH_THICKNESS),\n getNumber(props.pathBorder, DEFAULT_PATH_BORDER),\n pointers.maxRadius,\n pathStartAngle,\n pathEndAngle,\n ));\n }, [\n props.pathRadius,\n props.pathThickness,\n props.pathBorder,\n props.pathStartAngle,\n props.pathEndAngle,\n pointers,\n ]);\n\n useEffect(() => {\n const clearSelectedPointer = (evt: MouseEvent) => {\n const $target = evt.target as HTMLElement;\n const $pointer = $target.closest('[data-type=\"pointer\"]');\n if($pointer) return;\n\n setSelectedPointerId('');\n };\n\n document.addEventListener('mousedown', clearSelectedPointer);\n\n return () => {\n document.removeEventListener('mousedown', clearSelectedPointer);\n };\n }, []);\n\n const setPointersCallback = (pointer: IPointer, newAngleDeg: number) => {\n if(props.disabled || !pointers.pointers || !pointer || pointer.disabled) return;\n\n newAngleDeg = roundToStep(newAngleDeg, data.stepAngleDeg, svg.startAngleDeg, svg.endAngleDeg);\n if(data.isClosedShape && mod(newAngleDeg, 360) === mod(svg.endAngleDeg, 360)){\n newAngleDeg = svg.startAngleDeg;\n }\n\n if(pointer.angleDeg === newAngleDeg){\n updatePointer(pointer, newAngleDeg, false);\n return;\n }\n\n const handleOverlap = !props.pointersOverlap;\n if(handleOverlap) {\n\n let prevAngle, nextAngle;\n\n if(data.isClosedShape) {\n const prevIndex = mod(pointer.index - 1, pointers.pointers.length);\n const nextIndex = mod(pointer.index + 1, pointers.pointers.length);\n\n const prevPointer = pointers.pointers[prevIndex];\n const nextPointer = pointers.pointers[nextIndex];\n\n prevAngle = prevPointer.angleDeg;\n nextAngle = nextPointer.angleDeg;\n\n if(pointers.pointers.length === 2 && (prevAngle === nextAngle)) {\n\n const splitPointDeg = prevAngle; // === nextAngle\n\n if(prevAngleDegRef.current === null) {\n prevAngleDegRef.current = newAngleDeg;\n }\n else{\n // Clockwise: new angle in (splitPointDeg, splitPointDeg + 90]\n // Clockwise: prev angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: new angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: prev angle in (splitPointDeg, splitPointDeg + 90]\n\n const SAFE_ANGLE = 150;\n\n let t1 = splitPointDeg - SAFE_ANGLE;\n let t2 = splitPointDeg - 0.001;\n\n if(t1 < 0) t1 += 360;\n if(t2 < 0) t2 += 360;\n\n const clockwiseNew = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, newAngleDeg);\n const clockwisePrev = isAngleInArc(t1, t2, prevAngleDegRef.current);\n const clockwise = clockwiseNew && clockwisePrev;\n\n let t3 = splitPointDeg - SAFE_ANGLE;\n let t4 = splitPointDeg - 0.001;\n\n if(t3 < 0) t3 += 360;\n if(t4 < 0) t4 += 360;\n\n const counterClockwiseNew = isAngleInArc(t3, t4, newAngleDeg);\n const counterClockwisePrev = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, prevAngleDegRef.current);\n const counterClockwise = counterClockwiseNew && counterClockwisePrev;\n\n if(clockwise || counterClockwise) {\n updatePointer(pointer, splitPointDeg, true);\n return;\n }\n\n if(newAngleDeg !== splitPointDeg) {\n prevAngleDegRef.current = newAngleDeg;\n }\n }\n }\n }\n else{\n prevAngle = pointer.index === 0 ? svg.startAngleDeg : pointers.pointers[pointer.index - 1].angleDeg;\n nextAngle = pointer.index === pointers.pointers.length - 1 ? svg.endAngleDeg : pointers.pointers[pointer.index + 1].angleDeg;\n }\n\n if(nextAngle <= prevAngle) {\n nextAngle += 360;\n }\n else{\n if(mod(prevAngle, 360) <= mod(nextAngle, 360)) {\n prevAngle = mod(prevAngle, 360);\n nextAngle = mod(nextAngle, 360);\n }\n }\n\n if(!isAngleInArc(prevAngle, nextAngle, newAngleDeg)){\n newAngleDeg = getClosestEdge(\n prevAngle,\n nextAngle,\n newAngleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n }\n\n updatePointer(pointer, newAngleDeg, pointer.angleDeg !== newAngleDeg);\n };\n\n const updatePointer = (pointer: IPointer, newAngleDeg: number, angleChanged: boolean) => {\n\n if(angleChanged) {\n const _pointers = { ...pointers };\n _pointers.pointers = [...pointers.pointers];\n _pointers.pointers[pointer.index].prevAngleDeg = _pointers.pointers[pointer.index].angleDeg;\n _pointers.pointers[pointer.index].angleDeg = newAngleDeg;\n pointers.pointers = _pointers.pointers;\n\n setPointers(_pointers);\n\n if(typeof props.onChange === 'function') {\n\n const updatedPointers: ISettingsPointer[] = _pointers.pointers.map(pointer => {\n\n const val = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n\n return {\n radius: pointer.radius,\n value: val,\n bgColor: pointer.bgColor,\n bgColorSelected: pointer.bgColorSelected,\n bgColorDisabled: pointer.bgColorDisabled,\n border: pointer.border,\n borderColor: pointer.borderColor,\n disabled: pointer.disabled,\n ariaLabel: pointer.ariaLabel,\n };\n });\n\n props.onChange(updatedPointers);\n }\n }\n\n setSelectedPointerId(pointer.id);\n\n const $pointer = svgRef.current?.querySelector(`[data-id=\"${ pointer.id }\"]`) as HTMLElement;\n if($pointer) {\n $pointer.focus();\n }\n };\n\n return (\n <>\n {\n svg &&\n \n\n {\n (props.SvgDefs) &&\n \n { props.SvgDefs }\n \n }\n\n \n\n \n\n \n\n \n\n \n \n }\n \n )\n};", "export const setDecimalPlaces = (num: number, decimalPlaces: number | undefined = Infinity) => {\n if(decimalPlaces === Infinity) return num;\n\n if(decimalPlaces < 0){\n decimalPlaces = 0;\n }\n\n const coefficient = 10 ** decimalPlaces;\n return Math.round(num * coefficient) / coefficient;\n};", "import { Vector2 } from '../types';\nimport { setDecimalPlaces } from './format';\n\nexport const mod = (n: number, m: number) => {\n return ((n % m) + m) % m;\n};\n\n/**\n * Convert range [a, b] to [c, d].\n * f(x) = (d - c) * (x - a) / (b - a) + c\n */\nexport const convertRange = (x: number, a: number, b: number, c: number, d: number) => {\n return (d - c) * (x - a) / (b - a) + c;\n};\n\n/**\n * Check if 2 ranges [a,b] and [c,d] overlap.\n */\nexport const doRangesOverlap = (a: number, b: number, c: number, d: number) => {\n return Math.max(a, c) <= Math.min(b, d) ;\n};\n\n// eslint-disable-next-line\nexport const isNumber = (value: any) => {\n return !isNaN(parseFloat(value)) && isFinite(value);\n};\n\n/**\n * Convert polar coordinates to cartesian coordinates.\n */\nexport const polarToCartesian = (center: Vector2, radii: Vector2, angleInRad: number, decimalPlaces = Infinity) : Vector2 => {\n const [cx, cy] = center;\n const [rx, ry] = radii;\n\n return [\n setDecimalPlaces(cx + (rx * Math.cos(angleInRad)), decimalPlaces),\n setDecimalPlaces(cy + (ry * Math.sin(angleInRad)), decimalPlaces),\n ];\n};", "import { Vector, Vector2, Vector3 } from '../types';\nimport { setDecimalPlaces } from './format';\nimport { v2Length, vNormalize, vDotProduct, vSub } from './linear-algebra/vector';\nimport { mod } from './other';\n\nexport const getV2Angle = (v2: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1], v2[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleInEllipse = (v2: Vector2, radii: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1]/radii[1], v2[0]/radii[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const setV2Angle = (v2: Vector2, newAngleRad: number, decimalPlaces = Infinity): Vector2 => {\n const length = v2Length(v2);\n return [\n setDecimalPlaces(Math.cos(newAngleRad) * length, decimalPlaces),\n setDecimalPlaces(Math.sin(newAngleRad) * length, decimalPlaces),\n ];\n};\n\nexport const radiansToDegrees = (radians: number, decimalPlaces = Infinity) => {\n const res = radians * (180 / Math.PI);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\nexport const degreesToRadians = (degrees: number, decimalPlaces = Infinity) => {\n const res = degrees * (Math.PI / 180);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\n/**\n * Returns the range [0, Math.PI]\n * A = Math.acos( dot(v1, v2)/(v1.length()*v2.length()) );\n */\nexport const getVNAngleBetween = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n const unitVector1 = vNormalize(vector1);\n const unitVector2 = vNormalize(vector2);\n const dotProduct = vDotProduct(unitVector1, unitVector2);\n const angle = Math.acos(dotProduct);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleBetween = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) : number => {\n // return getVNAngleBetween(vector1, vector2, decimalPlaces);\n const diff = vSub(vector1, vector2);\n const angle = Math.atan2(diff[1], diff[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV3AngleBetween = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return getVNAngleBetween(vector1, vector2, decimalPlaces);\n};\n\nexport const isAngleBetween = (angleDegrees: number, startAngleDegrees: number, endAngleDegrees: number) : boolean => {\n const distance = getAnglesSub(startAngleDegrees, endAngleDegrees);\n const distance1 = getAnglesSub(startAngleDegrees, angleDegrees);\n const distance2 = getAnglesSub(endAngleDegrees, angleDegrees);\n const totalDistance = distance1 + distance2;\n\n // Use a small threshold for floating point errors\n return Math.abs(totalDistance - distance) <= 0.001;\n}\n\nexport const isClockwise = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n return angle2Deg >= angle1Deg;\n};\n\n/**\n * Shortest distance (angular) between two angles.\n */\nexport const getAnglesSub = (angleDegrees1: number, angleDegrees2: number, decimalPlaces = Infinity) : number => {\n const angleDistance = Math.abs(mod(angleDegrees1, 360) - mod(angleDegrees2, 360));\n return setDecimalPlaces(angleDistance <= 180 ? angleDistance : 360 - angleDistance, decimalPlaces);\n};\n\nexport const getAnglesDistance = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0, decimalPlaces = Infinity) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n if(isClockwise(angle1Deg, angle2Deg, startAngleDeg)) {\n return setDecimalPlaces((angle2Deg - angle1Deg + 360) % 360, decimalPlaces);\n }\n else{\n return setDecimalPlaces((angle1Deg - angle2Deg + 360) % 360, decimalPlaces);\n }\n};\n\nexport const percentToAngle = (percent: number, startAngleDeg: number, endAngleDeg: number, circleStartAngle = 0) => {\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n const distance = getAnglesDistance(startAngleDeg, endAngleDeg, circleStartAngle);\n\n const clockwise = isClockwise(startAngleDeg, endAngleDeg, circleStartAngle);\n if(clockwise) {\n return mod(circleStartAngle + (percent * distance / 100), 360);\n }\n else {\n return mod(circleStartAngle - (percent * distance / 100), 360);\n }\n};", "import { Vector, Vector2, Vector3, Vector4 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { getV2Angle, setV2Angle } from '../angle';\n\n// ------------ SUM ------------------------\n\nexport const vSum = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSum(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sum = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSum(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ SUB ------------------------\n\nexport const vSub = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSub(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sub = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSub(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ MUL SCALAR ------------------------\n\nexport const vMulScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n const vector: Vector = [];\n\n for(let i=0; i {\n return vMulScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3MulScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vMulScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ DIVIDE ------------------------\n\nexport const vDivideScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vDivideScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3DivideScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vDivideScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ LENGTH ------------------------\n\nexport const vLength = (vector: Vector, decimalPlaces = Infinity) => {\n let sum = 0;\n\n for(let i=0; i {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v3Length = (vector: Vector3, decimalPlaces = Infinity) => {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v2SetLength = (v2: Vector2, newLength: number, decimalPlaces = Infinity): Vector2 => {\n const angle = getV2Angle(v2);\n return [\n setDecimalPlaces(Math.cos(angle) * newLength, decimalPlaces),\n setDecimalPlaces(Math.sin(angle) * newLength, decimalPlaces),\n ];\n};\n\n// ----------- DISTANCE ------------------------\n\nexport const vDistance = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v2Distance = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v3Distance = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\n// ------------ NORMALIZE ------------------------\n\n/**\n * Normalization creates a unit vector, which is a vector of length 1.\n */\nexport const vNormalize = (v: Vector, decimalPlaces = Infinity) : Vector => {\n const length = vLength(v);\n const unitVector: Vector = [];\n\n for(let i=0; i {\n return vNormalize(v2, decimalPlaces) as Vector2;\n};\n\nexport const v3Normalize = (v3: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vNormalize(v3, decimalPlaces) as Vector3;\n};\n\n// ------------ DOT PRODUCT ------------------------\n\nexport const vDotProduct = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n let sum = 0;\n\n for(let i=0; i {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\nexport const v3DotProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\n// ------------ CROSS PRODUCT ------------------------\n\n/**\n * Cross product is possible on 3D vectors only.\n * The cross product a \u00D7 b is defined as a vector c that is perpendicular (orthogonal) to both a and b.\n */\nexport const v3CrossProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity): Vector3 => {\n return [\n setDecimalPlaces(vector1[1] * vector2[2] - vector1[2] * vector2[1], decimalPlaces),\n setDecimalPlaces(vector1[2] * vector2[0] - vector1[0] * vector2[2], decimalPlaces),\n setDecimalPlaces(vector1[0] * vector2[1] - vector1[1] * vector2[0], decimalPlaces),\n ];\n};\n\n// --------------- INIT VECTOR HELPER -----------------\n\nexport const v2 = (defaultValue = 0): Vector2 => {\n return [defaultValue, defaultValue];\n};\n\nexport const v3 = (defaultValue = 0): Vector3 => {\n return [defaultValue, defaultValue, defaultValue];\n};\n\nexport const v4 = (defaultValue = 0): Vector4 => {\n return [defaultValue, defaultValue, defaultValue, defaultValue];\n};\n\nexport const vN = (N: number, defaultValue = 0): Vector => {\n\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n const vector: Vector = [];\n for(let i=0; i {\n let vector: Vector2 = [0, 0];\n vector = v2SetLength(vector, distance);\n return setV2Angle(vector, angleRad);\n};\n\n// --------------- EQUALITY -------------------------\n\nexport const vEqual = (vector1: Vector, vector2: Vector): boolean => {\n if(vector1.length !== vector2.length) return false;\n\n for(let i=0; i {\n const sub = v2Sub(vector2, vector1);\n return [\n -setDecimalPlaces(sub[1], decimalPlaces),\n setDecimalPlaces(sub[0], decimalPlaces)\n ];\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector, Vector2, Vector3 } from '../../types';\nimport { vMulScalar, vSum, vSub, vDotProduct, vN, vEqual, vDivideScalar } from './vector';\n\n// --------------- SUM ----------------------\n\nexport const mSum = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sum = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- SUB ----------------------\n\nexport const mSub = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sub = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- MUL SCALAR ----------------------\n\nexport const mMulScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vMulScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2MulScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mMulScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3MulScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mMulScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n// --------------- DIVIDE SCALAR ----------------------\n\nexport const mDivideScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vDivideScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2DivideScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mDivideScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3DivideScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mDivideScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n\n// --------------- TRANSPOSE ----------------------\n\nexport const mTranspose = (m: Matrix): Matrix => {\n\n const vectorsCount = m.length;\n if(vectorsCount <= 0) return m;\n\n const vectorLength = m[0].length;\n if(vectorLength <= 0) return m;\n\n const matrix: Matrix = [];\n for(let i=0; i {\n return mTranspose(m2);\n};\n\nexport const m3Transpose = (m3: Matrix3): Matrix => {\n return mTranspose(m3);\n};\n\n// ----------------- RESET ----------------------\n\nexport const mReset = (m: Matrix, defaultValue = 0): Matrix => {\n\n if(m.length <= 0) return [];\n\n const res: Matrix = [];\n\n for(let i=0; i {\n return mReset(m2, defaultValue) as Matrix2;\n};\n\nexport const m3Reset = (m3: Matrix3, defaultValue = 0): Matrix3 => {\n return mReset(m3, defaultValue) as Matrix3;\n};\n\n// --------------- MATRIX INIT HELPERS -----------------\n\nexport const m2x2 = (defaultValue = 0): Matrix2 => {\n return [\n [defaultValue, defaultValue],\n [defaultValue, defaultValue],\n ];\n};\n\nexport const m3x3 = (defaultValue = 0): Matrix3 => {\n return [\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const m4x4 = (defaultValue = 0): Matrix4 => {\n return [\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const mNxM = (N: number, M: number, defaultValue = 0): Matrix => {\n if(N <= 0 || M <= 0){\n throw new Error('M and N must be positive numbers.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return [\n [1, 0],\n [0, 1],\n ];\n};\n\nexport const identity3 = (): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\nexport const identity4 = (): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Identity Matrix (I).\n * M x I = I x M = M for any matrix M.\n * Identity Matrix is a special case of scale matrix.\n */\nexport const identityN = (N: number): Matrix => {\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n if(N === 0) return [];\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mDeepCopy(m2) as Matrix2;\n};\n\nexport const m3DeepCopy = (m3: Matrix3): Matrix3 => {\n return mDeepCopy(m3) as Matrix3;\n};\n\n// -------------- APPEND / PREPEND ROW OR COLUMN ---------------\n\nexport const mAppendCol = (m: Matrix, col: Vector): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n const copy = mDeepCopy(m);\n copy.push(row);\n return copy;\n};\n\nexport const m2AppendRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.push(row);\n return copy;\n};\n\nexport const m3AppendRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.push(row);\n return copy;\n};\n\nexport const mPrependRow = (m: Matrix, row: Vector) : Matrix => {\n const copy = mDeepCopy(m);\n copy.unshift(row);\n return copy;\n};\n\nexport const m2PrependRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.unshift(row);\n return copy;\n};\n\nexport const m3PrependRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.unshift(row);\n return copy;\n};\n\n// ------------ DELETE ROW OR COLUMN ----------------------------\n\nexport const mDelLastRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.pop();\n return copy;\n};\n\nexport const mDelFirstRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.shift();\n return copy;\n};\n\nexport const mDelLastColumn = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const size = m[0].length;\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n\n const matrix: Matrix = [];\n for(let i=0; i {\n\n if(matrix.length < 0) return [];\n\n if(matrix[0].length !== vector.length){\n throw new Error('The number of columns in the matrix must be equal to the length of the vector.');\n }\n\n const res: Vector = [];\n\n for(let i=0; i {\n if(matrix1.length !== matrix2.length) return false;\n\n for(let i=0; i returns matrix N (m-1 x m-1)\n * The matrix must be square.\n */\nconst mMinorHelper = (m: Matrix, row: number, col: number) => {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // prepare the matrix without provided row and column\n const matrix = mMinorHelper(m, row, col);\n\n // calculate the matrix determinant\n return mDeterminant(matrix);\n};\n\n/**\n * Calculate determinant for NxN matrix.\n * Matrix should be square.\n */\nexport const mDeterminant = (matrix: Matrix): number => {\n const size = matrix.length;\n if(size === 0) return 1;\n\n if(size !== matrix[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return matrix[0][0];\n if(size === 2) return m2Determinant(matrix as Matrix2);\n\n let d = 0;\n\n for(let i=0; i {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return m2[0][0] * m2[1][1] - m2[1][0] * m2[0][1];\n};\n\n/**\n * Calculate determinant for 3x3 matrix.\n * Matrix should be square.\n */\nexport const m3Determinant = (m3: Matrix3): number => {\n if(m3.length !== m3[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return mDeterminant(m3);\n};\n\n// ------------------ INVERSE -----------------------\n\nexport const m2Adjugate = (m2: Matrix2): Matrix2|null => {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return [\n [m2[1][1], -m2[0][1]],\n [-m2[1][0], m2[0][0]],\n ];\n};\n\nexport const m3Adjugate = (m3: Matrix3) : Matrix3|null => {\n return mAdjugate(m3) as (Matrix3|null);\n};\n\n/**\n * Adjugate is a transpose of a cofactor matrix\n */\nexport const mAdjugate = (m: Matrix): Matrix|null => {\n\n const size = m.length;\n if(size <= 0) return null;\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return m;\n\n if(size === 2) return m2Adjugate(m as Matrix2);\n\n // build a cofactor matrix ----------------\n const cofactors: Matrix = [];\n\n for(let i=0; i {\n if(m.length > 0 && m.length !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = mDeterminant(m);\n return d === 0;\n};\n\n/**\n * Square matrix A (nxn) is invertible is there is another square matrix B (nxn) so AxB = BxA = I\n * For A (2x2) matrix, the inverse is:\n * (1 / (determinant(A))) * adj(A)\n */\nexport const m2Inverse = (m2: Matrix2, decimalPlaces = Infinity): (Matrix2 | null) => {\n if(m2.length > 0 && m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = m2Determinant(m2);\n if(d === 0) return null;\n\n const adj = m2Adjugate(m2);\n if(adj === null) return null;\n\n return m2DivideScalar(adj, d, decimalPlaces);\n};\n\nexport const m3Inverse = (m3: Matrix3, decimalPlaces = Infinity): (Matrix3 | null) => {\n return mInverse(m3, decimalPlaces) as (Matrix3|null);\n};\n\nexport const mInverse = (m: Matrix, decimalPlaces = Infinity): (Matrix | null) => {\n const size = m.length;\n\n if(size > 0 && size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // find a determinant ----------------------\n const d = mDeterminant(m);\n\n // find an Adjugate - a transpose of a cofactor matrix\n const adj = mAdjugate(m);\n if(adj === null) return null;\n\n return mDivideScalar(adj, d, decimalPlaces);\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector2, Vector3, Vector4 } from '../../types';\nimport { v2Normalize, v3MulScalar, v3Normalize } from './vector';\nimport { mMulVector, mMul } from './matrix';\nimport { setDecimalPlaces } from '../format';\n\n/*\nAny 2D affine transformation can be decomposed\ninto a rotation, followed by a scaling, followed by a\nshearing, and followed by a translation.\n---------------------------------------------------------\nAffine matrix = translation x shearing x scaling x rotation\n */\n\n// ----------------- CSS -------------------------------------\n\n/**\n * Matrix 2D in non-homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2ToCSS = (m: Matrix2) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, 0, 0)`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2hToCSS = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, ${ tx }, ${ ty })`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m2hToCSS3d = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix3d(${ a }, ${ b }, 0, 0, ${ c }, ${ d }, 0, 0, 0, 0, 1, 0, ${ tx }, ${ ty }, 0, 1)`;\n};\n\n/**\n * Matrix 3D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m3hToCSS3d = (m: Matrix4) : string => {\n\n return `matrix3d(\n ${ m[0][0] }, ${ m[0][1] }, ${ m[0][2] }, ${ m[0][3] },\n ${ m[1][0] }, ${ m[1][1] }, ${ m[1][2] }, ${ m[1][3] },\n ${ m[2][0] }, ${ m[2][1] }, ${ m[2][2] }, ${ m[2][3] },\n ${ m[3][0] }, ${ m[3][1] }, ${ m[3][2] }, ${ m[3][3] }\n )`;\n};\n\n// ---------------- TRANSLATION MATRICES ----------------------\n\nexport const m2Translation = (position: Vector2, decimalPlaces = Infinity): Matrix2 => {\n\n return [\n [1, 0],\n [0, 1],\n [setDecimalPlaces(position[0], decimalPlaces), setDecimalPlaces(position[1], decimalPlaces)],\n ];\n};\n\nexport const m3Translation = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n [\n setDecimalPlaces(position[0], decimalPlaces),\n setDecimalPlaces(position[1], decimalPlaces),\n setDecimalPlaces(position[2], decimalPlaces)\n ],\n ];\n};\n\n/**\n * 2D Translation matrix in homogeneous coordinates.\n */\nexport const m2TranslationH = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1],\n ];\n};\n\n/**\n * 3D Translation matrix in homogeneous coordinates.\n */\nexport const m3TranslationH = (position: Vector4, decimalPlaces = Infinity): Matrix4 => {\n\n return [\n [1, 0, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, 0, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1, setDecimalPlaces(position[2], decimalPlaces)],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- ROTATION MATRICES -------------------------\n\n/**\n * Rotation of an angle about the origin.\n */\nexport const m2Rotation = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix2 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin],\n [sin, cos],\n ] :\n [\n [cos, sin],\n [-sin, cos],\n ];\n};\n\n/**\n * Rotation of an angle about the origin in homogeneous coordinates (clockwise).\n */\nexport const m2RotationH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ]:\n [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation of an angle \"angleRad\" around the given point (transformOrigin) in homogeneous coordinates (clockwise).\n * result_vector = TranslationMatrix(x, y) * RotationMatrix() * TranslationMatrix(-x, -y) * position_vector\n */\nexport const m2RotationAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const rotation = m2RotationH(angleRad, isClockwise, decimalPlaces);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, rotation);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2RotateAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n position: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2RotationAroundPointH(angleRad, transformOrigin, isClockwise, decimalPlaces);\n return mMulVector(mat3h, position) as Vector3;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2Rotate = (angleRad: number, vector: Vector2, isClockwise = true, decimalPlaces = Infinity): Vector2 => {\n const unitVector = v2Normalize(vector);\n return mMulVector(m2Rotation(angleRad, isClockwise, decimalPlaces), unitVector) as Vector2;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2RotateH = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m2RotationH(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the X axis (clockwise).\n */\nexport const m3RotationX = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0],\n [0, cos, -sin],\n [0, sin, cos],\n ] :\n [\n [1, 0, 0],\n [0, cos, sin],\n [0, -sin, cos],\n ];\n};\n\n/**\n * Rotation around the X axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationXH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0, 0],\n [0, cos, -sin, 0],\n [0, sin, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [1, 0, 0, 0],\n [0, cos, sin, 0],\n [0, -sin, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateX = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationX(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Y axis (clockwise).\n */\nexport const m3RotationY = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin],\n [0, 1, 0],\n [-sin, 0, cos],\n ] :\n [\n [cos, 0, -sin],\n [0, 1, 0],\n [sin, 0, cos],\n ];\n};\n\n/**\n * Rotation around the Y axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationYH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin, 0],\n [0, 1, 0, 0],\n [-sin, 0, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [cos, 0, -sin, 0],\n [0, 1, 0, 0],\n [sin, 0, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateY = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationY(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Z axis (clockwise).\n */\nexport const m3RotationZ = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ] : [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation around the Z axis (clockwise)- in homogeneous coordinates\n */\nexport const m3RotationZH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0, 0],\n [sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ] : [\n [cos, sin, 0, 0],\n [-sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateZ = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationZ(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n// ---------------- SCALE MATRICES -------------\n\n/**\n * Get matrix for arbitrary scaling pivot point.\n * result_vector = TranslationMatrix(x, y) * ScaleMatrix() * TranslationMatrix(-x, -y) * scale_vector\n */\nexport const m2ScaleAtPointHMatrix = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const scale = m2ScaleH(scaleVector);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, scale);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2ScaleAtPointH = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n point: Vector3,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2ScaleAtPointHMatrix(scaleVector, transformOrigin, decimalPlaces);\n return mMulVector(mat3h, point) as Vector3;\n};\n\nexport const m2Scale = (scaleVector: Vector2): Matrix2 => {\n return [\n [scaleVector[0], 0],\n [0, scaleVector[1]],\n ];\n};\n\nexport const v2Scale = (scaleVector: Vector2, vector: Vector2): Vector2 => {\n return mMulVector(m2Scale(scaleVector), vector) as Vector2;\n};\n\n/**\n * homogeneous coordinates\n */\nexport const m2ScaleH = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, 1],\n ];\n};\n\nexport const m3Scale = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, scaleVector[2]],\n ];\n};\n\nexport const m3ScaleH = (scaleVector: Vector4): Matrix4 => {\n return [\n [scaleVector[0], 0, 0, 0],\n [0, scaleVector[1], 0, 0],\n [0, 0, scaleVector[2], 0],\n [0, 0, 0, 1]\n ];\n};\n\nexport const v3Scale = (scaleVector: Vector3, vector: Vector3): Vector3 => {\n return mMulVector(m3Scale(scaleVector), vector) as Vector3;\n};\n\n/**\n * Stretch, parallel to the x-axis.\n */\nexport const m2ScaleX = (scale: number): Matrix2 => {\n return [\n [scale, 0],\n [0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the x-axis - homogeneous coordinates\n */\nexport const m2ScaleXH = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleX = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleXH = (scale: number): Matrix4 => {\n return [\n [scale, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleY = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleYH = (scale: number): Matrix => {\n return [\n [1, 0, 0, 0],\n [0, scale, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZ = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, scale],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZH = (scale: number): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, scale, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis.\n */\nexport const m2ScaleY = (scale: number): Matrix2 => {\n return [\n [1, 0],\n [0, scale],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis - homogeneous coordinates\n */\nexport const m2ScaleYH = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n// ---------------- REFLECTION MATRICES -------------------------\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOrigin = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOriginH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection about the origin in non-homogeneous coordinates\n */\nexport const m3ReflectionOrigin = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection about the origin in homogeneous coordinates\n */\nexport const m3ReflectionOriginH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection about y=-x\n */\nexport const m2ReflectionYmX = (): Matrix2 => {\n\n return [\n [0, -1],\n [-1, 0],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionX = (): Matrix2 => {\n\n return [\n [1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionXH = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection in the y-axis.\n */\nexport const m2ReflectionY = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, 1],\n ];\n};\n\nexport const m2ReflectionYH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionYZ = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in homogeneous coordinates\n */\nexport const m3ReflectionYZH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXZ = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in homogeneous coordinates\n */\nexport const m3ReflectionXZH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXY = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in homogeneous coordinates\n */\nexport const m3ReflectionXYH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- SHEARING MATRICES -------------------------\n\n\n/**\n * Shearing in y-axis, with x-axis fixed with (0,1) moving to (factor, 1)\n */\nexport const m2ShearingY = (factor: number): Matrix2 => {\n\n return [\n [1, factor],\n [0, 1],\n ];\n};\n\n/**\n * Shearing in x-axis, with y-axis fixed with (1,0) moving to (1, factor)\n */\nexport const m2ShearingX = (factor: number): Matrix2 => {\n\n return [\n [1, 0],\n [factor, 1],\n ];\n};", "import { setDecimalPlaces } from './format';\n\n/**\n * Returns a random number in the [min,max] range.\n */\nexport const getRandom = (min: number, max: number, decimalPlaces = Infinity): number => {\n return setDecimalPlaces(Math.random() * (max - min) + min, decimalPlaces);\n};\n\n/**\n * Returns a random integer number in the [min,max] range.\n */\nexport const getRandomInt = (min: number, max: number): number => {\n return Math.floor(Math.random() * (max - min + 1) + min);\n};\n\nexport const getRandomBoolean = () => Math.random() < 0.5;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const getRandomItemFromArray = (array: any[]) => {\n const randomIndex = getRandomInt(0, array.length - 1);\n return array[randomIndex];\n};", "export const stringToNumber = (value: string|undefined|null|number, defaultNumber: number) => {\n if(value === undefined || value === null) return defaultNumber;\n const res = Number(value) ?? defaultNumber;\n return isNaN(res) ? defaultNumber : res;\n};", "import { setDecimalPlaces } from './format';\nimport { Vector2, Vector3 } from '../types';\n\n/**\n * u(x) and v(x) are functions ---------->\n *\n * dx(u + v) = dx(u) + dx(v)\n * dx(u - v) = dx(u) - dx(v)\n * dx(u * v) = dx(u) * v + u * dx(v)\n * dx(u / v) = (dx(u) * v - u * dx(v)) / (v ^ 2), when v(x) != 0\n */\n\n// ------------------ Derivatives of Polynomial ---------------------------\n\n/**\n * y = 3x+2\n * dxPolynomial(10, [[3, 1], [2, 0]])\n */\nexport const dxPolynomial = (x: number, polynomial: number[][], decimalPlaces = Infinity) => {\n let res = 0;\n\n for(const part of polynomial){\n if(part.length !== 2) return NaN;\n\n const coeff = part[0];\n const power = part[1];\n res += coeff * power * Math.pow(x, power - 1);\n }\n\n return setDecimalPlaces(res, decimalPlaces);\n}\n\n// ---------------------- Bezier Curves ---------------------------\n\n/**\n * Derivative of Bezier Curve is another Bezier Curve.\n * t must min in range [0, 1]\n */\nexport const dxV2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n // The derivative: P1 * (2t-2) + (2*P3-4*P2) * t + 2 * P2\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\nexport const dxV2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n\n// ----------------- Derivatives of trigonometry functions ---------------------------\n\nexport const dxSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(Math.cos(x), decimalPlaces);\n};\n\nexport const dxCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-Math.sin(x), decimalPlaces);\n};\n\nexport const dxTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.cos(x) ** 2), decimalPlaces);\n};\n\n/**\n * x != Math.PI * n, where n is an integer\n */\nexport const dxCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sin(x) ** 2), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\nexport const dxArcTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (1 + x ** 2), decimalPlaces);\n};\n\nexport const dxArcCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (1 + x ** 2), decimalPlaces);\n};\n", "import { Matrix, Matrix2, Matrix3, Vector, Vector2, Vector3 } from '../../types';\nimport { m2Inverse, m3Inverse, mInverse, mMulVector, mDelLastColumn, mGetLastColumn } from '../linear-algebra/matrix';\nimport { setDecimalPlaces } from '../format';\nimport { v2Sub } from '../linear-algebra/vector';\n\n/**\n * Linear equation\n * ax + b = c\n * x = (c - b) / a; a != 0\n */\nexport const linearEquation = (equation: Vector3, decimalPlaces = Infinity) : number => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n\n const diff = c - b;\n\n if(a === 0 && diff === 0) return Infinity; // any number is a solution\n if(a === 0) return NaN; // no solution\n\n return setDecimalPlaces(diff / a, decimalPlaces);\n};\n\n/**\n * System of 2 linear equations.\n * [x, y] = inverse(Matrix of equation parameters) x (vector of equation results)\n * ---------------\n * 3x + 2y = 7\n * -6x + 6y = 6\n */\nexport const linearEquationSystem2 = (equation1: Vector3, equation2: Vector3, decimalPlaces = Infinity) : Vector2 | null => {\n const equationParams: Matrix2 = [\n [equation1[0], equation1[1]],\n [equation2[0], equation2[1]],\n ];\n\n const inversed = m2Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector2 = [\n equation1[2],\n equation2[2]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector2;\n};\n\n/**\n * System of 3 linear equations.\n * ---------------------------------------\n * 3x + 2y + 5z = 7\n * -6x + 6y + 6z = 6\n * 2x + 7y - z = 4\n */\nexport const linearEquationSystem3 = (\n equation1: Vector,\n equation2: Vector,\n equation3: Vector,\n decimalPlaces = Infinity) : Vector3 | null => {\n const equationParams: Matrix3 = [\n [equation1[0], equation1[1], equation1[2]],\n [equation2[0], equation2[1], equation2[2]],\n [equation3[0], equation3[1], equation3[2]],\n ];\n\n const inversed = m3Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector3 = [\n equation1[3],\n equation2[3],\n equation3[3]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector3;\n};\n\n/**\n * System of N linear equations.\n */\nexport const linearEquationSystemN = (equations: Matrix, decimalPlaces = Infinity) : Vector | null => {\n if(equations.length <= 0) return null;\n\n const equationParams = mDelLastColumn(equations);\n\n const inversed = mInverse(equationParams);\n if(inversed === null) return null; // no results\n\n // the last column of the equations matrix\n const equationResults = mGetLastColumn(equations);\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector;\n};\n\n/**\n * Calculate the equation of a line given two points in a 2D space.\n * y = ax + b\n * y - y1 = m(x - x1)\n * m = (y2 - y1) / (x2 - x1)\n */\nexport const getLinearEquationBy2Points = (point1: Vector2, point2: Vector2) : {\n slope: number|undefined,\n yIntercept: number|undefined,\n xIntercept: number|undefined,\n formula: string,\n} => {\n const [deltaX, deltaY] = v2Sub(point2, point1);\n const [x, y] = point1;\n\n if(deltaX === 0) {\n return {\n slope: undefined,\n xIntercept: x,\n yIntercept: undefined,\n formula: `x = ${ x }`,\n };\n }\n\n const m = deltaY / deltaX;\n const b = y - m * x;\n let formula = '';\n\n if(m === 0) {\n formula = `y = ${ b }`;\n }\n else{\n formula = `y = ${ m === 1 ? '' : m }x`;\n\n if(b !== 0) {\n formula += ` ${ b < 0 ? '-' : '+' } ${ Math.abs(b) }`;\n }\n }\n\n return {\n slope: m,\n xIntercept: undefined,\n yIntercept: b,\n formula,\n };\n};", "import { Vector } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { linearEquation } from './linear-equations';\nimport { isNumber } from '../other';\n\n/**\n * Quadratic Equation.\n * ax^2 + bx + c = d\n */\nexport const quadraticEquation = (equation: Vector, decimalPlaces = Infinity) : Vector => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n const d = equation[3];\n\n if(a === 0){\n // it's a linear equation -------------------------------------------\n const res = linearEquation([b, c, d], decimalPlaces);\n if(isNumber(res)) return [res];\n return [];\n }\n\n const diff = c - d;\n\n const discriminant = b * b - (4 * a * diff);\n\n if(discriminant < 0){\n return []; // no results\n }\n\n if(discriminant === 0){\n return [ setDecimalPlaces(-b / (2 * a), decimalPlaces) ]; // 1 result\n }\n\n // if(determinant > 0) ---> 2 results\n const t1 = 2 * a;\n const t2 = Math.sqrt(discriminant);\n\n return [\n setDecimalPlaces((-b + t2) / t1, decimalPlaces),\n setDecimalPlaces((-b - t2) / t1, decimalPlaces),\n ];\n};", "import { IBBox, Vector, Vector2, Vector3 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport {\n dxV2CubicBezierCurve,\n dxV2QuadraticBezierCurve,\n dxV3CubicBezierCurve,\n dxV3QuadraticBezierCurve\n} from '../derivative';\nimport { v2Normalize, v3Normalize } from '../linear-algebra/vector';\nimport { linearEquation } from '../equations/linear-equations';\nimport { quadraticEquation } from '../equations/quadratic-equations';\nimport { isNumber } from '../other';\n\n/**\n * B\u00E9zier Curves\n * quadratic: y = P1 * (1-t)\u00B2 + P2 * 2 * (1-t)t + P3 * t\u00B2\n * t in range [0, 1]\n */\n\n// -------------------- GET POINT ON CURVE --------------------------\n\n/**\n * Get a point on a quadratic B\u00E9zier curve as a function of time.\n */\nexport const v2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n/**\n * Get a point on a cubic B\u00E9zier curve as a function of time.\n */\nexport const v2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n// -------------------- TANGENT --------------------------\n\n/**\n * Tangent indicates the direction of travel at specific points along the B\u00E9zier curve,\n * and is literally just the first derivative of our curve.\n */\nexport const v2QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\nexport const v2CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\n// -------------------- NORMAL --------------------------\n\n/**\n * Normal is a vector that runs at a right angle to the direction of the curve, and is typically of length 1.\n * To find it, we take the normalised tangent vector, and then rotate it by a 90 degrees.\n */\nexport const v2QuadraticBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2QuadraticBezierCurveTangent(t, startControlPoint, centerControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\nexport const v2CubicBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2CubicBezierCurveTangent(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\n// -------------------- EXTREMA --------------------------\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2QuadraticBezierCurveExtrema = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector => {\n\n /*\n (-2 * (1 - t)) * startControlPoint[0] + (2 - 4 * t) * centerControlPoint[0] + (2 * t) * endControlPoint[0]\n 2 * t * startControlPoint[0] - 4 * t * centerControlPoint[0] + 2 * t * endControlPoint[0] - 2 * startControlPoint[0] + 2 * centerControlPoint[0]\n t * (2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0]) + (- 2 * startControlPoint[0] + 2 * centerControlPoint[0])\n */\n\n const a1 = 2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0];\n const b1 = -2 * startControlPoint[0] + 2 * centerControlPoint[0];\n const equation1: Vector3 = [a1, b1, 0];\n const res1 = linearEquation(equation1, decimalPlaces);\n\n const a2 = 2 * startControlPoint[1] - 4 * centerControlPoint[1] + 2 * endControlPoint[1];\n const b2 = -2 * startControlPoint[1] + 2 * centerControlPoint[1];\n const equation2: Vector3 = [a2, b2, 0];\n const res2 = linearEquation(equation2, decimalPlaces);\n\n const res: Vector = [];\n\n if(isNumber(res1)){\n res.push(res1);\n }\n\n if(isNumber(res2)){\n res.push(res2);\n }\n\n return res;\n};\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2CubicBezierCurveExtrema = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2|null => {\n\n const a1 = -3 * startControlPoint[0] + 9 * center1ControlPoint[0] - 9 * center2ControlPoint[0] + 3 * endControlPoint[0];\n const b1 = 6 * startControlPoint[0] - 12 * center1ControlPoint[0] + 6 * center2ControlPoint[0];\n const c1 = -3 * startControlPoint[0] + 3 * center1ControlPoint[0];\n const equation1: Vector = [a1, b1, c1, 0];\n\n const a2 = -3 * startControlPoint[1] + 9 * center1ControlPoint[1] - 9 * center2ControlPoint[1] + 3 * endControlPoint[1];\n const b2 = 6 * startControlPoint[1] - 12 * center1ControlPoint[1] + 6 * center2ControlPoint[1];\n const c2 = -3 * startControlPoint[1] + 3 * center1ControlPoint[1];\n const equation2: Vector = [a2, b2, c2, 0];\n\n // Any value between 0 and 1 is a root that matters for B\u00E9zier curves, anything below or above that is irrelevant (because B\u00E9zier curves are only defined over the interval [0,1]).\n const res1 = quadraticEquation(equation1, decimalPlaces).filter(num => num >= 0 && num <= 1);\n const res2 = quadraticEquation(equation2, decimalPlaces).filter(num => num >= 0 && num <= 1);\n\n const res = [...res1, ...res2];\n if(res.length === 2){\n return [...res1, ...res2] as Vector2;\n }\n\n return null;\n};\n\n// -------------------- BOUNDING BOX --------------------------\n\nexport const v2QuadraticBezierBBox = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2QuadraticBezierCurveExtrema(startControlPoint, centerControlPoint, endControlPoint);\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2QuadraticBezierCurve(percent, startControlPoint, centerControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\nexport const v2CubicBezierBBox = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2CubicBezierCurveExtrema(startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint) || [];\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2CubicBezierCurve(percent, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x ?? Infinity);\n maxX = Math.max(maxX, x ?? -Infinity);\n\n minY = Math.min(minY, y ?? Infinity);\n maxY = Math.max(maxY, y ?? -Infinity);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\n\n", "import { Vector2 } from '../types';\nimport { v2Sub } from './linear-algebra/vector';\nimport { getV2Angle } from './angle';\nimport { convertRange } from './other';\n\n/**\n * Circle Equation\n * x^2 + y^2 = radius^2\n * ----------------------\n * Circle Parametric Equation\n * x(t) = radius * cos(t)\n * y(t) = radius * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const circleMovement = (center: Vector2, angle: number, radius: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius,\n center[1] + Math.sin(angle) * radius\n ];\n};\n\n/**\n * Circle Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const circleMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radius: number\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return circleMovement(center, angle, radius);\n};\n\n/**\n * Ellipse Equation\n * (x - centerX)^2 / (radius1^2) + (y - centerY)^2 / (radius2^2) = 1\n * -----------------------------------------------------------------\n * Ellipse Parametric Equation\n * x(t) = radius1 * cos(t)\n * y(t) = radius2 * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const ellipseMovement = (center: Vector2, angle: number, radius1: number, radius2: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius1,\n center[1] + Math.sin(angle) * radius2\n ];\n};\n\n/**\n * Ellipse Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const ellipseMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radii: Vector2\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return ellipseMovement(center, angle, radii[0], radii[1]);\n};\n\n/**\n * Sine Wave Equation (Sinusoid)\n * -----------------------------\n * const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n * amplitude = the peak deviation of the function from zero\n * frequency = number of cycles\n * phase = specifies (in radians) where in its cycle the oscillation is at t = 0.\n * think of it as \"shifting\" the starting point of the function to the right (positive p) or left (negative)\n */\nexport const sineWaveMovement = (x: number, amplitude: number, frequency: number, phase: number) : Vector2 => {\n /*\n example values:\n const amplitude = 50;\n const frequency = 0.005;\n const phase = 0;\n x: [0, 1000]\n */\n const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n\n return [x, y];\n};\n\n/**\n * Lissajous curve (Lissajous figure or Bowditch curve)\n * Parametric equation #1\n * f(t) = A * sin(k * t + m)\n * f(t) = B * sin(n * t)\n * 0 <= m <= PI/2\n * k, n >= 1\n * -----------------------\n * Parametric equation #2\n * f(t) = A * cos(k * t - m)\n * f(t) = B * cos(n * t - p)\n * -----------------------------\n * Shapes:\n * k = 1, n = 1, m = 0, p = 0 ---> line\n * A = B, k = 1, n = 1, m = PI/2, p = PI/2 ----> circle\n * A != B, k = 1, n = 1, m = PI/2, p = PI/2 ----> ellipse\n * k = 2, n = 2, m = PI/2, p = PI/2 ----> section of a parabola\n */\nexport const lissajousCurve = (\n width: number,\n height: number,\n t: number,\n k: number,\n n: number,\n m: number,\n p: number\n) :Vector2 => {\n return [\n width * Math.cos(k * t - m),\n height * Math.cos(n * t - p),\n ];\n};\n", "import { getRandom } from './random';\nimport { HSLColor, RGBColor } from '../types';\nimport { mod } from './other';\nimport { setDecimalPlaces } from './format';\n\n// ------------------------ RANDOM COLOR -------------------------------------\n\nexport const getRandomRGBColor = () : RGBColor => {\n const hslColor = getRandomHSLColor();\n return hslToRgb(hslColor);\n};\n\nexport const getRandomHexColor = () : string => {\n const hslColor = getRandomHSLColor();\n return hslToHex(hslColor);\n};\n\nexport const getRandomHSLColor = () : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given hue\n */\nexport const getRandomHSLColorWithHue = (h: number) : HSLColor => {\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given saturation\n */\nexport const getRandomHSLColorWithSaturation = (s: number) : HSLColor => {\n const h = getRandom(1, 360);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given lightness\n */\nexport const getRandomHSLColorWithLightness = (l: number) : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n return [h, s, l];\n};\n\nexport const getRandomGrayscaleHSLColor = () : HSLColor => {\n const l = getRandom(0, 100);\n return [0, 0, l];\n};\n\nexport const getRandomHSLColorWithinRanges = (\n hueStart = 1, hueEnd = 360,\n saturationStart = 0, saturationEnd = 100,\n lightStart = 0, lightEnd = 100\n) : HSLColor => {\n const h = getRandom(hueStart, hueEnd);\n const s = getRandom(saturationStart, saturationEnd);\n const l = getRandom(lightStart, lightEnd);\n return [h, s, l];\n};\n\n// ----------------------- CONVERT COLORS --------------------------------------\n\n/**\n * helper: convert hue value to %\n * @param {number} h\n * @return {number} [0, 100] %\n */\nconst convertHueToPercent = (h : number) : number => {\n\n // the hue value needs to be multiplied by 60 to convert it to degrees\n h *= 60;\n\n // if hue becomes negative, you need to add 360 to, because a circle has 360 degrees\n if(h < 0){\n h += 360;\n }\n\n // convert huw to %\n return h * 100 / 360;\n};\n\n/**\n * get hue from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] % - we use here % instead of [0, 359] degrees\n */\nconst getHue = (r : number, g : number, b : number, min : number | undefined = undefined, max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no hue, as it's gray\n if(min === max) return 0;\n\n // if red is max\n if(max === r){\n return convertHueToPercent((g - b) / (max - min));\n }\n\n // if green is max\n if(max === g){\n return convertHueToPercent(2.0 + (b - r) / (max - min));\n }\n\n // if blue is max\n if(max === b){\n return convertHueToPercent(4.0 + (r - g) / (max - min));\n }\n\n return 0;\n};\n\n/**\n * get luminance from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] %\n */\nconst getLuminance = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // calculate the luminance value\n // @ts-ignore\n const l = (min + max) / 2; // [0, 1]\n\n // return l value in %\n return l * 100;\n};\n\n/**\n * get saturation from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @param {number|undefined=} l - luminance in [0, 100] %\n * @return {number} [0, 100] %\n */\nconst getSaturation = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined,\n l : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no saturation, as it's gray\n if(min === max) return 0;\n\n // calculate luminance if it's not provided\n l = (l === undefined) ? getLuminance(r, g, b) : l;\n\n // check the level of luminance\n const s = (l <= 50) ?\n // @ts-ignore\n ((max - min) / (max + min)) : // this formula is used when luminance <= 50%\n // @ts-ignore\n (max - min) / (2.0 - max - min); // this formula is used when luminance > 50%\n\n // return saturation in %\n return s * 100;\n};\n\nexport const rgbToHsl = (rgb: RGBColor, decimalPlaces = Infinity): HSLColor => {\n\n // convert rgb values to the range [0, 1]\n const r = rgb[0] / 255;\n const g = rgb[1] / 255;\n const b = rgb[2] / 255;\n\n // find the minimum and maximum values of r, g, and b\n const min = Math.min(r, g, b);\n const max = Math.max(r, g, b);\n\n // calculate the luminance value in %\n const l = getLuminance(r, g, b, min, max);\n\n // calculate the saturation in %\n const s = getSaturation(r, g, b, min, max, l);\n\n // calculate the hue in % (not in degrees!)\n const h = getHue(r, g, b, min, max);\n\n if(h > 360 || s > 100 || l > 100){\n return [0, 0, 100];\n }\n\n if(h < 0 || s < 0 || l < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(h, decimalPlaces),\n setDecimalPlaces(s, decimalPlaces),\n setDecimalPlaces(l, decimalPlaces),\n ];\n};\n\n/**\n * helper: HSL to RGB\n */\nconst hslToRgbHelper = (helper1 : number, helper2 : number, colorHelper : number) : number => {\n\n // all values need to be between 0 and 1\n // if you get a negative value you need to add 1 to it\n if(colorHelper < 0) colorHelper += 1;\n\n // if you get a value above 1 you need to subtract 1 from it.\n if(colorHelper > 1) colorHelper -= 1;\n\n if(colorHelper * 6 < 1) return helper2 + (helper1 - helper2) * 6 * colorHelper;\n\n if(colorHelper * 2 < 1) return helper1;\n\n if(colorHelper * 3 < 2){\n return helper2 + (helper1 - helper2) * (0.666 - colorHelper) * 6;\n }\n else{\n return helper2;\n }\n};\n\nexport const hslToRgb = (hsl: HSLColor, decimalPlaces = Infinity): RGBColor => {\n\n // convert all values to [0, 1] from %\n const h = hsl[0] / 100;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n // if there is no saturation -> it\u2019s grey\n if(s === 0){\n // convert the luminance from [0, 1] to [0, 255]\n const gray = l * 255;\n return [gray, gray, gray];\n }\n\n // check the level of luminance\n const helper1 = (l < 0.5) ?\n (l * (1.0 + s)) :\n (l + s - l * s);\n\n const helper2 = 2 * l - helper1;\n\n const rHelper = h + 0.333;\n const gHelper = h;\n const bHelper = h - 0.333;\n\n let r = hslToRgbHelper(helper1, helper2, rHelper);\n let g = hslToRgbHelper(helper1, helper2, gHelper);\n let b = hslToRgbHelper(helper1, helper2, bHelper);\n\n // convert rgb to [0, 255]\n r *= 255;\n g *= 255;\n b *= 255;\n\n if(r > 255 || g > 255 || b > 255){\n return [255, 255, 255];\n }\n\n if(r < 0 || g < 0 || b < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(r, decimalPlaces),\n setDecimalPlaces(g, decimalPlaces),\n setDecimalPlaces(b, decimalPlaces),\n ];\n};\n\n/**\n * HSL to hex\n * hslToHex(360, 100, 50) // [360, 100, 5] ==> \"#ff0000\" (red)\n */\nexport const hslToHex = (hsl: HSLColor) => {\n\n if(hsl[0] > 360 || hsl[1] > 100 || hsl[2] > 100){\n return '#ffffff';\n }\n\n if(hsl[0] < 0 || hsl[1] < 0 || hsl[2] < 0){\n return '#000000';\n }\n\n const h = hsl[0] / 360;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n let r, g, b;\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n};\n\n// ----------------------- GET SHIFTED COLORS --------------------------------------\n\nexport const getShiftedHue = (color: HSLColor, shift = 180) : HSLColor => {\n let hue = color[0];\n hue += shift;\n\n if (hue > 360 || hue < 0) {\n hue = mod(hue, 360);\n }\n\n return [hue, color[1], color[2]];\n};\n\nexport const getShiftedLightness = (color: HSLColor, shift = 10) : HSLColor => {\n let lightness = color[2];\n lightness += shift;\n\n if (lightness > 100 || lightness < 0) {\n lightness = mod(lightness, 100);\n }\n\n return [color[0], color[1], lightness];\n};\n\nexport const getShiftedSaturation = (color: HSLColor, shift = 10) : HSLColor => {\n let saturation = color[1];\n saturation += shift;\n\n if (saturation > 100) {\n saturation -= 100;\n }\n\n if(saturation < 0){\n saturation += 100;\n }\n\n return [color[0], saturation, color[2]];\n};\n", "/**\n * guid like '932ade5e-c515-4807-ac01-73b20ab3fb66'\n */\nexport const guid = () => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);\n });\n};\n\n/**\n * id like 'df4unio1opulby2uqh4'\n */\nexport const newId = () => {\n return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);\n};\n", "import { ICircle, IPolygon, IRect, Matrix2, Vector2 } from '../types';\nimport { mod } from './other';\nimport { v2GetNormal, v2DotProduct } from './linear-algebra/vector';\n\n/**\n * Rectangles collision detection.\n * Rectangles should not be rotated.\n * The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles.\n * Any gap means a collision does not exist.\n * Returns true if collision is detected.\n */\nexport const rectCollide = (rect1: IRect, rect2: IRect) : boolean => {\n return rect1.x <= rect2.x + rect2.w &&\n rect1.x + rect1.w >= rect2.x &&\n rect1.y <= rect2.y + rect2.h &&\n rect1.h + rect1.y >= rect2.y;\n};\n\n/**\n * Circles collision detection.\n * This algorithm works by taking the center points of the two circles\n * and ensuring the distance between the center points\n * are less than the two radii added together.\n * Returns true if collision is detected.\n */\nexport const circleCollide = (circle1: ICircle, circle2: ICircle) => {\n const dx = Math.abs(circle1.cx - circle2.cx);\n const dy = Math.abs(circle1.cy - circle2.cy);\n const distance = Math.sqrt(dx * dx + dy * dy);\n return distance <= circle1.r + circle2.r;\n};\n\n//-------------------- Separating Axis Theorem (SAT) Collision detection -------------------------\n\nconst getEdges = (poly: IPolygon) : Matrix2[] => {\n const edges: Matrix2[] = [];\n\n for(let i= 0; i {\n const edges: Matrix2[] = [];\n\n // collect polygon edges, and combine then into a single array\n edges.push(...getEdges(poly1));\n edges.push(...getEdges(poly2));\n\n // for each edge, find the normal vector and project both polygons onto it\n for (const edge of edges) {\n const normal = v2GetNormal(edge[0], edge[1]);\n const p1Proj = projectPolygon(poly1, normal);\n const p2Proj = projectPolygon(poly2, normal);\n\n // Check if the projections overlap\n const isOverlap = p1Proj.max >= p2Proj.min && p2Proj.max >= p1Proj.min;\n\n // Check if the projections overlap; if not, the polygons do not collide\n if (!isOverlap) return false;\n }\n\n // If all tests pass, the polygons overlap and collide\n return true;\n};\n\n/**\n * Project every polygon point onto the normal.\n * Then find min and max.\n */\nconst projectPolygon = (polygon: IPolygon, normal: Vector2): { min: number, max: number } => {\n let min = Infinity;\n let max = -Infinity;\n\n // Project each vertex of the polygon onto the axis\n for (const vertex of polygon) {\n const projection = v2DotProduct(vertex, normal);\n min = Math.min(min, projection);\n max = Math.max(max, projection);\n }\n\n return { min, max };\n};", "export interface IAnimationProps {\n duration?: number;\n callback: (result: IAnimationResult) => void;\n restartOnResize?: boolean;\n resizeCallback?: (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => void;\n}\n\nexport interface IAnimationResult {\n start: () => void;\n stop: () => void;\n pause: () => void;\n resume: () => void;\n restart: () => void;\n isAnimating: () => boolean;\n getStartTime: () => number|undefined;\n getElapsedTime: () => number|undefined;\n getPercent: () => number|undefined;\n getResizeObserver: () => ResizeObserver|undefined;\n}\n\nexport const animate = (props: IAnimationProps) : IAnimationResult => {\n\n const _duration = props.duration !== undefined ? props.duration : Infinity;\n\n let startTime: number|undefined = undefined; // in milliseconds\n let animationId: number|undefined = undefined;\n\n // the time elapsed since the start of the animation (in milliseconds)\n let elapsed: number|undefined = undefined;\n let previousTimeStamp: number|undefined = undefined;\n\n let animating = false;\n let observer: ResizeObserver|undefined = undefined;\n\n // -------------------- COMMANDS ---------------------\n\n const stop = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = false;\n\n /*if(observer !== undefined){\n observer.disconnect();\n observer = undefined;\n }*/\n\n if(animationId === undefined) return;\n window.cancelAnimationFrame(animationId);\n };\n\n const restart = () => {\n stop();\n start();\n };\n\n const pause = () => {\n animating = false;\n };\n\n const resume = () => {\n animating = true;\n };\n\n /**\n * Animation Step.\n * @param {number} timeStamp in milliseconds\n */\n const step = (timeStamp: DOMHighResTimeStamp) => {\n\n if (startTime === undefined) {\n startTime = timeStamp;\n }\n\n // the time elapsed since the start of the animation (in milliseconds)\n elapsed = timeStamp - startTime;\n\n if (animating && previousTimeStamp !== timeStamp && typeof props.callback === 'function') {\n\n // do the rendering .............\n props.callback(getResult());\n }\n\n if(elapsed <= _duration){\n previousTimeStamp = timeStamp;\n animationId = window.requestAnimationFrame(step);\n }\n else{\n stop();\n }\n };\n\n const observerHandler = (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => {\n restart();\n\n if(typeof props.resizeCallback === 'function'){\n props.resizeCallback(_entries, _observer);\n }\n };\n\n const start = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = true;\n\n if(props.restartOnResize && window.ResizeObserver && observer === undefined){\n observer = new ResizeObserver(observerHandler);\n observer.observe(document.body, { box: 'border-box' });\n }\n else{\n animationId = window.requestAnimationFrame(step);\n }\n };\n\n // --------------- GET INFO ----------------------\n\n /**\n * the time elapsed since the start of the animation (in milliseconds)\n */\n const getElapsedTime = () : number|undefined => {\n return elapsed;\n };\n\n const isAnimating = () => {\n return animating;\n };\n\n const getStartTime = () => {\n return startTime;\n };\n\n const getPercent = () => {\n if(_duration === Infinity || elapsed === undefined) return undefined;\n return elapsed * 100 / _duration;\n };\n\n const getResizeObserver = () => {\n return observer;\n };\n\n const getResult = () : IAnimationResult => {\n return {\n\n // commands --------------\n start,\n stop,\n pause,\n resume,\n restart,\n\n // information -------\n isAnimating,\n getElapsedTime,\n getStartTime,\n getPercent,\n getResizeObserver,\n };\n };\n\n return getResult();\n};\n", "import { setDecimalPlaces } from './format';\n\nexport const getCircleCircumference = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * radius, decimalPlaces);\n};\n\nexport const getEllipseCircumference = (radius1: number, radius2: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * Math.sqrt((radius1 ** 2 + radius2 ** 2) / 2), decimalPlaces);\n};\n\nexport const isAngleInCircleArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg ||\n (currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg;\n};\n\n/**\n * get the side of a square inscribed in a circle\n */\nexport const getSquareInCircleSide = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(radius * 2 / Math.sqrt(2), decimalPlaces);\n};\n", "import { setDecimalPlaces, Vector2 } from 'mz-math';\n\nexport interface ISvg {\n cx: number;\n cy: number;\n radius: number;\n size: number;\n thickness: number;\n border: number;\n startAngleDeg: number;\n endAngleDeg: number;\n}\n\nexport const getSvg = (\n circleRadius: number,\n circleThickness: number,\n circleBorder: number,\n maxPointerRadius: number,\n startAngleDeg: number,\n endAngleDeg: number\n) : ISvg => {\n\n const thickness = circleThickness + circleBorder * 2;\n\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n const size = circleRadius * 2 + thickness + diff;\n\n const [ cx, cy ] = getSVGCenter(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n return {\n cx,\n cy,\n radius: circleRadius,\n size,\n thickness: circleThickness,\n border: circleBorder,\n startAngleDeg,\n endAngleDeg\n } as ISvg;\n};\n\nexport const getSVGCenter = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : Vector2 => {\n\n const size = getSVGSize(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n const val = setDecimalPlaces(size/2, 2);\n\n return [\n val,\n val,\n ];\n};\n\nexport const getSVGSize = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : number => {\n const thickness = circleThickness + circleBorder * 2;\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n return circleRadius * 2 + thickness + diff;\n};", "// Data Defaults --------------------\nexport const DEFAULT_MIN = 0;\nexport const DEFAULT_MAX = 100;\nexport const DEFAULT_STEP = 1;\nexport const DEFAULT_ARROW_STEP = 1;\nexport const DEFAULT_ROUND = 0;\n\n// Path Defaults ---------------------\nexport const DEFAULT_PATH_START_ANGLE = 0;\nexport const DEFAULT_PATH_END_ANGLE = 360;\nexport const DEFAULT_PATH_RADIUS = 150;\nexport const DEFAULT_PATH_THICKNESS = 5;\nexport const DEFAULT_PATH_BG_COLOR = '#efefef';\nexport const DEFAULT_PATH_BORDER = 0;\nexport const DEFAULT_PATH_BORDER_COLOR = '#444444';\n\n// Pointer Defaults ------------------\nexport const DEFAULT_POINTER_RADIUS = 10;\nexport const DEFAULT_POINTER_BG_COLOR = '#163a86';\nexport const DEFAULT_POINTER_BG_COLOR_SELECTED = '#000';\nexport const DEFAULT_POINTER_BG_COLOR_DISABLED = '#a8a8a8';\nexport const DEFAULT_POINTER_BORDER = 0;\nexport const DEFAULT_POINTER_BORDER_COLOR = '#000';\n\n// Connection Defaults ------------------\nexport const DEFAULT_CONNECTION_BG_COLOR = '#5daed2';\nexport const DEFAULT_CONNECTION_BG_COLOR_DISABLED = '#97b0bb';\n\n// Text Defaults ------------------------\nexport const DEFAULT_TEXT_COLOR = '#000';\nexport const DEFAULT_TEXT_FONT_SIZE = 16;\n\n// Ticks Defaults -----------------------\nexport const DEFAULT_TICKS_ENABLED = false;\nexport const DEFAULT_TICKS_WIDTH = 3;\nexport const DEFAULT_TICKS_HEIGHT = 10;\nexport const DEFAULT_TICKS_COLOR = '#efefef';\nexport const DEFAULT_TICKS_VALUES_COLOR = '#000';\nexport const DEFAULT_TICKS_VALUES_FONT_SIZE = 12;\nexport const DEFAULT_TICKS_GROUP_SIZE = 10;\nexport const DEFAULT_TICKS_VALUES_DISTANCE = 15;\n\n// Animation Defaults -----------------------\nexport const DEFAULT_ANIMATION_DURATION = 200;\n\n\n", "import { isNumber } from 'mz-math';\n\nexport const getNumber = (value: number|string|undefined|null, defaultValue: number) : number => {\n return isNumber(value) ? Number(value) : defaultValue;\n};\n\nexport const getString = (value: string|undefined|null, defaultValue: string) : string => {\n return value === undefined || value === null ? defaultValue : value;\n};\n\nexport const getBoolean = (value: boolean|undefined|null, defaultValue: boolean) : boolean => {\n return value === undefined || value === null ? defaultValue : value;\n};", "import { mod } from 'mz-math';\n\nexport interface ICircle {\n strokeDasharray: string;\n strokeOffset: number;\n}\n\nexport const isAngleInArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return (currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg) ||\n ((currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg);\n};\n\nexport const getAnglesDistance = (startAngle: number, endAngle: number) => {\n if(endAngle < startAngle) {\n endAngle += 360;\n }\n\n const diff = endAngle - startAngle;\n const diffMod = mod(diff, 360);\n\n return diffMod === 0 && diff > 0 ? 360 : diffMod;\n};\n\nexport const getCircle = (\n startAngleDeg: number,\n endAngleDeg: number,\n radius: number,\n) : ICircle => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n const circumference = 2 * Math.PI * radius;\n const angleDiff = endAngleDeg - startAngleDeg;\n const strokeOffset = -(startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDiff / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n return {\n strokeDasharray: [ strokeDasharray, complement ].join(' '),\n strokeOffset,\n } as ICircle;\n};", "import {\n Vector2,\n convertRange,\n mod,\n setDecimalPlaces,\n v2Sub,\n radiansToDegrees,\n degreesToRadians, circleMovement, v2Distance\n} from 'mz-math';\nimport { ISettings } from './settings-provider';\nimport {\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_POINTER_BG_COLOR,\n DEFAULT_POINTER_BG_COLOR_DISABLED,\n DEFAULT_POINTER_BG_COLOR_SELECTED,\n DEFAULT_POINTER_BORDER,\n DEFAULT_POINTER_BORDER_COLOR,\n DEFAULT_POINTER_RADIUS,\n} from './defaults-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport { IData } from './data-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IPointer {\n id: string;\n index: number;\n radius: number;\n angleDeg: number;\n prevAngleDeg: number;\n\n bgColor: string;\n bgColorSelected: string;\n bgColorDisabled: string;\n bgColorHover: string;\n\n border: number;\n borderColor: string;\n\n disabled: boolean;\n ariaLabel?: string;\n}\n\nexport interface IPointers {\n pointers: IPointer[];\n maxRadius: number;\n}\n\nexport const getAngleByMouse = (\n $svg: SVGSVGElement,\n clientX: number,\n clientY: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number\n) => {\n const { left, top } = $svg.getBoundingClientRect();\n\n const relativeMouse: Vector2 = [\n clientX - left,\n clientY - top,\n ];\n\n const vector = v2Sub(relativeMouse, [ cx, cy ]);\n\n let angleRad = Math.atan2(vector[1] / ry, vector[0] / rx);\n if(angleRad < 0){\n angleRad += 2 * Math.PI;\n }\n\n return radiansToDegrees(angleRad);\n};\n\nexport const angle2value = (data: IData, angle: number, pathStartAngle: number, pathEndAngle: number) : string | number => {\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(angle < pathStartAngle){\n angle += 360;\n }\n\n let value: string|number = convertRange(angle, pathStartAngle, pathEndAngle, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n return value;\n};\n\nconst value2angle = (data: IData, value: string | number, pathStartAngle: number, pathEndAngle: number) => {\n let _value: number;\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(data.data.length > 0) {\n const valueIndex = data.data.findIndex(item => item === value);\n _value = valueIndex === -1 ? 0 : valueIndex;\n }\n else{\n _value = typeof value !== 'number' ? data.min : value;\n }\n\n return mod(convertRange(_value, data.min, data.max, pathStartAngle, pathEndAngle), 360);\n};\n\nexport const initPointers = (\n settings: ISettings,\n data: IData\n) : IPointer[] => {\n\n if(!settings || !settings.pointers || settings.pointers.length < 0 || !data) {\n const angleDeg = mod(getNumber(settings.pathStartAngle, DEFAULT_PATH_START_ANGLE), 360);\n\n const bgColor = getString(settings.pointerBgColor, DEFAULT_POINTER_BG_COLOR);\n const bgColorSelected = getString(settings.pointerBgColorSelected, DEFAULT_POINTER_BG_COLOR_SELECTED);\n const bgColorDisabled = getString(settings.pointerBgColorDisabled, DEFAULT_POINTER_BG_COLOR_DISABLED);\n const bgColorHover = getString(settings.pointerBgColorHover, bgColorSelected);\n\n return [{\n id: '0',\n index: 0,\n radius: getNumber(settings.pointerRadius, DEFAULT_POINTER_RADIUS),\n angleDeg,\n prevAngleDeg: angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border: getNumber(settings.pointerBorder, DEFAULT_POINTER_BORDER),\n borderColor: getString(settings.pointerBorderColor, DEFAULT_POINTER_BORDER_COLOR),\n disabled: !!settings.disabled,\n }]\n }\n\n const pointers: IPointer[] = [];\n\n for(let i=0; i {\n\n const pointers = initPointers(settings, data);\n\n return {\n pointers,\n maxRadius: getMaxRadius(pointers),\n }\n};\n\nconst getMaxRadius = (pointers: IPointer[]) : number => {\n if(pointers.length <= 0) return 0;\n\n let max = -Infinity;\n\n for(const pointer of pointers){\n max = Math.max(max, Math.max(0, pointer.radius + pointer.border/2));\n }\n\n return max;\n};\n\nexport const getClosestPointer = (\n pointers: IPointer[],\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n if(!pointers || pointers.length <= 0) return null;\n\n if(pointers.length === 1) return pointers[0];\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n let min: number|undefined = undefined;\n let closestPointer: IPointer = null;\n\n const enabledPointers = pointers.filter(p => !p.disabled);\n\n for(const pointer of enabledPointers) {\n const pointerAngleRad = convertRange(degreesToRadians(pointer.angleDeg), 0, Math.PI * 2, 0, Math.PI);\n const pointOnArc = circleMovement([ cx, cy ], pointerAngleRad, pathRadius);\n const distance = v2Distance(currentPointOnArc, pointOnArc);\n\n if(min === undefined || distance < min) {\n min = distance;\n closestPointer = pointer;\n }\n }\n\n return { ...closestPointer };\n};\n\nexport const getClosestEdge = (\n startAngleDegrees: number,\n endAngleDegrees: number,\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n const startAngleRad = convertRange(degreesToRadians(startAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const startPointOnArc = circleMovement([ cx, cy ], startAngleRad, pathRadius);\n\n const endAngleRad = convertRange(degreesToRadians(endAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const endPointOnArc = circleMovement([ cx, cy ], endAngleRad, pathRadius);\n\n const distance1 = v2Distance(currentPointOnArc, startPointOnArc);\n const distance2 = v2Distance(currentPointOnArc, endPointOnArc);\n\n return distance1 <= distance2 ? startAngleDegrees : endAngleDegrees;\n};\n\nexport const getMinMaxDistancePointers = (pointers: IPointer[], pathStartAngle: number) : [IPointer, IPointer] | null => {\n if(!pointers || pointers.length <= 0) return null;\n\n let minDistance = undefined;\n let maxDistance = undefined;\n let minPointer = null;\n let maxPointer = null;\n\n for(const pointer of pointers) {\n\n const distance = getAnglesDistance(pathStartAngle, pointer.angleDeg);\n\n if(minDistance === undefined || distance < minDistance) {\n minPointer = pointer;\n minDistance = distance;\n }\n\n if(maxDistance === undefined || distance > maxDistance) {\n maxPointer = pointer;\n maxDistance = distance;\n }\n }\n\n if(minPointer === null || maxPointer === null) return null;\n\n return [\n minPointer,\n maxPointer\n ];\n};\n\nexport const roundToStep = (angleDeg: number, step: number, pathStartAngle: number, pathEndAngle: number) : number => {\n if((mod(angleDeg, 360) === mod(pathStartAngle, 360)) ||\n (mod(angleDeg, 360) === mod(pathEndAngle, 360))) return angleDeg;\n return step === 0 ? 0 : Math.round(angleDeg / step) * step;\n};\n", "import { angle2value, getAngleByMouse, getClosestEdge, IPointer } from '../domain/pointers-provider';\nimport {\n useEffect,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n KeyboardEvent,\n useRef, useCallback,\n} from 'react';\nimport { circleMovement, convertRange, degreesToRadians, Vector2 } from 'mz-math';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { isAngleInArc } from '../domain/circle-provider';\nimport { IData } from '../domain/data-provider';\nimport { outlineNoneStyle } from '../domain/style-provider';\nimport { DEFAULT_POINTER_BG_COLOR } from '../domain/defaults-provider';\n\nexport interface IPointerProps {\n settings: ISettings;\n pointer: IPointer;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst getPointerFill = (\n pointer: IPointer,\n selectedPointerId: string,\n bgColor: string,\n bgColorSelected: string,\n bgColorDisabled: string,\n bgColorHover: string,\n isMouseOver: boolean\n) => {\n if(pointer.disabled) return bgColorDisabled;\n\n if(isMouseOver) return bgColorHover;\n\n if(pointer.id === selectedPointerId) {\n return bgColorSelected;\n }\n\n return bgColor;\n};\n\nconst Pointer = (props: IPointerProps) => {\n\n const pointerRef = useRef(null);\n\n const {\n pointer, svg, $svg, data, settings,\n setPointer, selectedPointerId,\n } = props;\n\n const {\n radius,\n angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border,\n borderColor,\n } = props.pointer;\n\n const { cx, cy } = svg;\n\n const [ center, setCenter ] = useState(null);\n const [ value, setValue ] = useState('');\n const [ fill, setFill ] = useState(DEFAULT_POINTER_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n useEffect(() => {\n setFill(getPointerFill(\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ));\n }, [\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ]);\n\n useEffect(() => {\n const value = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n setValue(value === undefined ? '' : value.toString())\n }, [\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const angleRad = convertRange(degreesToRadians(angleDeg), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const pointerCenter = circleMovement([cx, cy], angleRad, svg.radius);\n setCenter(pointerCenter);\n }, [\n angleDeg,\n cx,\n cy,\n svg.radius,\n ]);\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent | TouchEvent | ReactTouchEvent) => {\n if(!$svg || settings.disabled || pointer.disabled) return;\n\n const mouseX = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientX : (evt as TouchEvent).touches[0].clientX;\n const mouseY = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientY : (evt as TouchEvent).touches[0].clientY;\n\n const degrees = getAngleByMouse(\n $svg,\n mouseX,\n mouseY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n let newAngleDeg;\n\n if(!isAngleInArc(\n svg.startAngleDeg,\n svg.endAngleDeg,\n degrees\n )){\n newAngleDeg = getClosestEdge(\n svg.startAngleDeg,\n svg.endAngleDeg,\n pointer.angleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n else{\n newAngleDeg = degrees;\n }\n\n setPointer(pointer, newAngleDeg);\n }, [\n $svg,\n pointer,\n setPointer,\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n settings.disabled,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n const onKeyDown = (evt: KeyboardEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.keyboardDisabled) return;\n\n switch (evt.key) {\n case 'ArrowLeft': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowRight': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowUp': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowDown': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n }\n };\n\n useEffect(() => {\n const $current = pointerRef.current;\n\n const onTouch = (evt: TouchEvent | ReactTouchEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n onValueChange(evt);\n };\n\n const onWheel = (evt: WheelEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.mousewheelDisabled || document.activeElement !== $current) return;\n\n evt.stopPropagation();\n evt.preventDefault();\n\n const scrollTop = evt.deltaY < 0;\n\n let newAngleDeg;\n if(scrollTop) {\n newAngleDeg = pointer.angleDeg + data.arrowStepAngleDeg;\n }\n else{\n newAngleDeg = pointer.angleDeg - data.arrowStepAngleDeg;\n }\n\n setPointer(pointer, newAngleDeg);\n };\n\n $current?.addEventListener('touchmove', onTouch, {\n passive: false,\n });\n\n document.addEventListener('wheel', onWheel, {\n passive: false,\n });\n\n return () => {\n $current?.removeEventListener('touchmove', onTouch);\n document.removeEventListener('wheel', onWheel);\n };\n }, [\n center,\n onValueChange,\n data.arrowStepAngleDeg,\n pointer,\n setPointer,\n settings.disabled,\n settings.mousewheelDisabled,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n center &&\n \n\n {\n !settings.pointerSVG &&\n \n }\n\n {\n settings.pointerSVG &&\n \n { settings.pointerSVG }\n \n }\n \n }\n \n )\n};\n\nexport default Pointer;", "export const outlineNoneStyle = {\n outline: 'none',\n};", "import { IPointer, IPointers } from '../domain/pointers-provider';\nimport Pointer from './Pointer';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\nexport interface IPointersProps {\n pointers: IPointers;\n settings: ISettings;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst Pointers = (props: IPointersProps) => {\n\n const {\n pointers, settings, svg, $svg, data,\n setPointer, selectedPointerId,\n } = props;\n\n return (\n <>\n {\n pointers.pointers.map(pointer => {\n\n return (\n \n )\n })\n }\n \n )\n};\n\nexport default Pointers;", "import { ISettings } from './settings-provider';\nimport { getNumber } from './common-provider';\nimport {\n DEFAULT_ARROW_STEP,\n DEFAULT_MAX,\n DEFAULT_MIN,\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_ROUND,\n DEFAULT_STEP\n} from './defaults-provider';\nimport { mod } from 'mz-math';\n\nexport interface IData {\n min: number;\n max: number;\n stepAngleDeg: number;\n arrowStepAngleDeg: number;\n round: number;\n data: (string | number)[];\n isClosedShape: boolean;\n}\n\nexport const getData = (setting: ISettings) : IData => {\n\n let min = getNumber(setting.min, DEFAULT_MIN);\n let max = getNumber(setting.max, DEFAULT_MAX);\n const step = getNumber(setting.step, DEFAULT_STEP);\n const arrowStep = getNumber(setting.arrowStep, DEFAULT_ARROW_STEP);\n const round = getNumber(setting.round, DEFAULT_ROUND);\n const data = setting.data || [];\n\n if(data.length > 0) {\n const minIndex = data.findIndex(item => item === min);\n const maxIndex = data.findIndex(item => item === max);\n\n min = minIndex === -1 ? 0 : minIndex;\n max = maxIndex === -1 ? data.length : maxIndex;\n }\n else{\n if(min > max) {\n min = max + DEFAULT_MAX;\n }\n }\n\n const pathStartAngle = getNumber(setting.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n const pathEndAngle = getNumber(setting.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n const isClosedShape = mod(pathStartAngle, 360) === mod(pathEndAngle, 360);\n\n const stepAngleDeg = step * 360 / (max - min);\n const arrowStepAngleDeg = arrowStep * 360 / (max - min);\n\n return {\n min,\n max,\n round,\n data,\n stepAngleDeg,\n arrowStepAngleDeg,\n isClosedShape,\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_CONNECTION_BG_COLOR,\n DEFAULT_CONNECTION_BG_COLOR_DISABLED\n} from '../domain/defaults-provider';\nimport {\n getAngleByMouse,\n getClosestPointer,\n getMinMaxDistancePointers,\n IPointer,\n IPointers\n} from '../domain/pointers-provider';\nimport {\n MouseEvent as ReactMouseEvent,\n useCallback,\n useEffect, useRef,\n useState\n} from 'react';\nimport { getConnection, IConnection } from '../domain/connection-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\nimport { animate, IAnimationResult, mod } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\n\ninterface IConnectionProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst getStroke = (\n disabled: boolean,\n connectionBgColorDisabled: string,\n connectionBgColor: string,\n isMouseOver: boolean,\n connectionBgColorHover: string\n) => {\n if(disabled) return getString(connectionBgColorDisabled, DEFAULT_CONNECTION_BG_COLOR_DISABLED);\n\n const bgColor = getString(connectionBgColor, DEFAULT_CONNECTION_BG_COLOR);\n\n if(isMouseOver) {\n return getString(connectionBgColorHover, bgColor);\n }\n\n return bgColor;\n};\n\nconst Connection = (props: IConnectionProps) => {\n\n const { settings, pointers, $svg, svg, data, setPointer } = props;\n\n const [ connection, setConnection ] = useState(null);\n const [ animation, setAnimation ] = useState(null);\n const [ stroke, setStroke ] = useState(DEFAULT_CONNECTION_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n const rangeDraggingLastAngle = useRef();\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setStroke(getStroke(\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n isMouseOver,\n settings.connectionBgColorHover\n ));\n }, [\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n settings.connectionBgColorHover,\n isMouseOver,\n ]);\n\n useEffect(() => {\n setConnection(getConnection(\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n }, [\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ]);\n\n const onClick = (evt: ReactMouseEvent) => {\n\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // RANGE DRAGGING -------------------------------------------\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent) => {\n if(!$svg || settings.disabled || !settings.rangeDragging) return;\n\n const minMaxResult = getMinMaxDistancePointers(pointers.pointers, svg.startAngleDeg);\n if(!minMaxResult) return;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n const mouseDegrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n if(rangeDraggingLastAngle.current === undefined) {\n rangeDraggingLastAngle.current = mouseDegrees;\n return;\n }\n\n const diff = (mouseDegrees - rangeDraggingLastAngle.current);\n if(diff === 0 || Math.abs(diff) < data.stepAngleDeg) return;\n\n setPointer(minPointer, mod(minPointer.angleDeg + diff, 360));\n setPointer(maxPointer, mod(maxPointer.angleDeg + diff, 360));\n\n rangeDraggingLastAngle.current = mouseDegrees;\n }, [\n $svg,\n svg.cx,\n svg.cy,\n svg.radius,\n data.stepAngleDeg,\n pointers.pointers,\n setPointer,\n settings.disabled,\n settings.rangeDragging,\n svg.startAngleDeg,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n\n rangeDraggingLastAngle.current = undefined;\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(!settings.rangeDragging || settings.disabled || pointers.pointers.length <= 1) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n !getBoolean(settings.hideConnection, false) && connection &&\n \n }\n \n )\n};\n\nexport default Connection;", "import { IPointers } from './pointers-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IConnection {\n radius: number;\n cx: number;\n cy: number;\n\n // calculated properties ---------\n startAngleDeg: number;\n endAngleDeg: number;\n strokeDasharray: number[];\n strokeOffset: number;\n}\n\nexport const getConnection = (\n pointers: IPointers,\n radius: number,\n cx: number,\n cy: number,\n pathStartAngle: number,\n pathEndAngle: number,\n) : IConnection => {\n\n if(!pointers.pointers || pointers.pointers.length <= 0) return null;\n\n const result : IConnection = {\n radius,\n cx,\n cy,\n\n // calculated properties ---------\n startAngleDeg: pathStartAngle,\n endAngleDeg: pathStartAngle,\n strokeDasharray: [0, 0],\n strokeOffset: 0,\n };\n\n // Define start/end angles.\n if(pointers.pointers.length === 1) {\n result.startAngleDeg = pathStartAngle;\n result.endAngleDeg = pointers.pointers[0].angleDeg;\n }\n else{\n result.startAngleDeg = pointers.pointers[0].angleDeg;\n result.endAngleDeg = pointers.pointers[pointers.pointers.length - 1].angleDeg;\n\n /*const minMaxResult = getMinMaxDistancePointers(pointers.pointers, pathStartAngle);\n if(!minMaxResult) return null;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n result.startAngleDeg = minPointer.angleDeg;\n result.endAngleDeg = maxPointer.angleDeg;*/\n }\n\n const pathAnglesDistance = getAnglesDistance(pathStartAngle, pathEndAngle);\n\n if(result.startAngleDeg > result.endAngleDeg) {\n result.endAngleDeg += 360;\n }\n\n let angleDistance = getAnglesDistance(result.startAngleDeg, result.endAngleDeg);\n\n const shouldSwitch = angleDistance > pathAnglesDistance;\n\n if(shouldSwitch) {\n angleDistance = 360 - angleDistance;\n [result.startAngleDeg, result.endAngleDeg] = [result.endAngleDeg, result.startAngleDeg];\n }\n\n const circumference = 2 * Math.PI * radius;\n const strokeOffset = -(result.startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDistance / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n result.strokeDasharray = [ strokeDasharray, complement ];\n result.strokeOffset = strokeOffset;\n\n return result;\n};", "import { IAnimationResult, mod } from 'mz-math';\n\nexport const getAnimationProgressAngle = (\n progress: IAnimationResult,\n animationSourceDegrees: number,\n animationTargetDegrees: number,\n startPathAngleDeg: number\n) => {\n let percent = progress.getPercent();\n\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n let angle1 = animationSourceDegrees % 360;\n let angle2 = animationTargetDegrees % 360;\n\n if(angle1 < startPathAngleDeg) {\n angle1 += 360;\n }\n\n if(angle2 < startPathAngleDeg) {\n angle2 += 360;\n }\n\n const isClockwise = angle2 > angle1;\n\n if(isClockwise) {\n const clockwiseDistance = (angle2 - angle1 + 360) % 360;\n return mod(animationSourceDegrees + (percent * clockwiseDistance / 100), 360);\n }\n else {\n const counterclockwiseDistance = (angle1 - angle2 + 360) % 360;\n return mod(animationSourceDegrees - (percent * counterclockwiseDistance / 100), 360);\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { angle2value, IPointers } from '../domain/pointers-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE\n} from '../domain/defaults-provider';\nimport { useEffect, useState } from 'react';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITextProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n data: IData;\n}\n\nconst Text = (props: ITextProps) => {\n\n const { settings, pointers, svg, data } = props;\n\n const { cx, cy } = svg;\n const [ value, setValue ] = useState('');\n\n useEffect(() => {\n\n const values = pointers.pointers.map(pointer => angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n\n values.sort((value1, value2) => {\n return value1.toString().localeCompare(\n value2.toString(),\n 'en',\n { numeric: true }\n );\n });\n\n const texts = values.map(value => `${ settings.textPrefix || '' }${ value }${ settings.textSuffix || '' }`);\n\n const textBetween = getString(settings.textBetween, ' ');\n setValue(texts.join(textBetween));\n\n }, [\n data,\n pointers.pointers,\n svg.startAngleDeg,\n svg.endAngleDeg,\n settings.textPrefix,\n settings.textSuffix,\n settings.textBetween,\n ]);\n\n const hideText = getBoolean(settings.hideText, false);\n\n return (\n <>\n {\n !hideText &&\n \n\n { value }\n\n \n }\n \n )\n};\n\nexport default Text;", "import { useEffect, useState, Fragment } from 'react';\nimport { getTicks, getTicksSettings, ITick, ITicks } from '../domain/ticks-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITicksProps {\n settings: ISettings;\n svg: ISvg;\n data: IData;\n}\n\nconst Ticks = (props: ITicksProps) => {\n\n const { settings, svg, data } = props;\n\n const [ ticksSettings, setTicksSettings ] = useState(null);\n const [ ticks, setTicks ] = useState([]);\n\n useEffect(() => {\n setTicksSettings(getTicksSettings(settings, data));\n }, [\n settings,\n data,\n ]);\n\n useEffect(() => {\n if(!ticksSettings) return;\n\n let endAngleDeg = svg.endAngleDeg;\n if(endAngleDeg < svg.startAngleDeg) {\n endAngleDeg += 360;\n }\n\n setTicks(getTicks(\n ticksSettings,\n ticksSettings.ticksCount,\n svg.startAngleDeg,\n endAngleDeg,\n svg,\n data\n ));\n }, [\n data,\n svg,\n ticksSettings,\n ]);\n\n return (\n <>\n {\n ticksSettings && ticksSettings.enableTicks &&\n \n {\n ticks.map((tick, i) => {\n const { x, y, x1, y1, textX, textY, showText } = tick;\n\n return (\n \n \n\n {\n showText &&\n \n { settings.tickValuesPrefix }{ tick.tickValue }{ settings.tickValuesSuffix }\n \n }\n \n );\n })\n }\n \n }\n \n )\n};\n\nexport default Ticks;", "import {\n circleMovement,\n convertRange,\n degreesToRadians,\n setDecimalPlaces,\n v2MulScalar,\n v2Normalize\n} from 'mz-math';\nimport { ISvg } from './svg-provider';\nimport { IData } from './data-provider';\nimport { ISettings } from './settings-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport {\n DEFAULT_TICKS_COLOR, DEFAULT_TICKS_ENABLED, DEFAULT_TICKS_GROUP_SIZE,\n DEFAULT_TICKS_HEIGHT, DEFAULT_TICKS_VALUES_COLOR,\n DEFAULT_TICKS_VALUES_DISTANCE, DEFAULT_TICKS_VALUES_FONT_SIZE,\n DEFAULT_TICKS_WIDTH\n} from './defaults-provider';\n\nexport interface ITicks {\n ticksCount: number;\n enableTicks: boolean;\n ticksWidth: number;\n ticksHeight: number;\n longerTicksHeight: number;\n ticksDistanceToPanel: number;\n tickValuesDistance: number;\n ticksColor: string;\n tickValuesColor: string;\n tickValuesFontSize: number;\n ticksGroupSize: number;\n longerTickValuesOnly: boolean;\n showTickValues: boolean;\n}\n\nexport interface ITick {\n x: number;\n y: number;\n x1: number;\n y1: number;\n textX: number;\n textY: number;\n isLonger: boolean;\n showText: boolean;\n tickValue?: string;\n}\n\nexport const getTicksSettings = (settings: ISettings, data: IData) : ITicks => {\n\n let ticksCount = getNumber(settings.ticksCount, 0);\n if(!ticksCount) {\n if(data.data && data.data.length > 0) {\n ticksCount = data.data.length;\n }\n else{\n ticksCount = data.max;\n }\n }\n\n const ticksHeight = getNumber(settings.ticksHeight, DEFAULT_TICKS_HEIGHT);\n\n return {\n ticksCount,\n enableTicks: getBoolean(settings.enableTicks, DEFAULT_TICKS_ENABLED),\n ticksWidth: getNumber(settings.ticksWidth, DEFAULT_TICKS_WIDTH),\n ticksHeight,\n longerTicksHeight: getNumber(settings.longerTicksHeight, ticksHeight * 2),\n ticksDistanceToPanel: getNumber(settings.ticksDistanceToPanel, 0),\n tickValuesDistance: getNumber(settings.tickValuesDistance, DEFAULT_TICKS_VALUES_DISTANCE),\n ticksColor: getString(settings.ticksColor, DEFAULT_TICKS_COLOR),\n tickValuesColor: getString(settings.tickValuesColor, DEFAULT_TICKS_VALUES_COLOR),\n tickValuesFontSize: getNumber(settings.tickValuesFontSize, DEFAULT_TICKS_VALUES_FONT_SIZE),\n ticksGroupSize: getNumber(settings.ticksGroupSize, DEFAULT_TICKS_GROUP_SIZE),\n longerTickValuesOnly: getBoolean(settings.longerTickValuesOnly, true),\n showTickValues: getBoolean(settings.showTickValues, true),\n };\n};\n\nexport const getTicks = (\n ticksSettings: ITicks,\n ticksCount: number,\n pathStartAngle: number,\n pathEndAngle: number,\n svg: ISvg,\n data: IData\n) : ITick[] => {\n\n const ticks: ITick[] = [];\n\n const deltaAngle = Math.abs(pathEndAngle - pathStartAngle);\n const oneTickAngleSize = ticksCount === 0 ? 0 : deltaAngle / ticksCount;\n\n let count = ticksCount;\n if(!data.isClosedShape) {\n count++;\n }\n\n for(let i=0; i [0, Math.PI]\n\n let [x, y] = circleMovement([svg.cx, svg.cy], angleRad, svg.radius);\n\n const isLonger = ticksSettings.ticksGroupSize !== undefined && (i % ticksSettings.ticksGroupSize === 0 );\n\n let desiredDistance = ticksSettings.ticksHeight;\n\n if(isLonger) {\n desiredDistance = ticksSettings.longerTicksHeight;\n }\n\n const normalizedDirectionVector = v2Normalize([svg.cx - x, svg.cy - y]);\n const tickEndVector = v2MulScalar(normalizedDirectionVector, desiredDistance);\n\n const tickStartVector = v2MulScalar(normalizedDirectionVector, ticksSettings.ticksDistanceToPanel + svg.thickness/2);\n x += tickStartVector[0];\n y += tickStartVector[1];\n\n const x1 = x + tickEndVector[0];\n const y1 = y + tickEndVector[1];\n\n // ------- Define tick value. ---------------------\n let tickValue: string|undefined = undefined;\n if(ticksSettings.showTickValues && (!ticksSettings.longerTickValuesOnly || ticksSettings.longerTickValuesOnly && (isLonger || ticksSettings.ticksGroupSize === undefined))) {\n\n let value: string|number = convertRange(i, 0, ticksCount, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n tickValue = (value ?? '').toString();\n }\n\n let textX = 0;\n let textY = 0;\n const showText = tickValue !== undefined;\n\n if(showText) {\n const _tickValuesDistance = getNumber(desiredDistance + ticksSettings.tickValuesDistance, desiredDistance * 1.5);\n const tickTextVector = v2MulScalar(normalizedDirectionVector, _tickValuesDistance);\n textX = x + tickTextVector[0];\n textY = y + tickTextVector[1];\n }\n\n ticks.push({\n x,\n y,\n x1,\n y1,\n textX,\n textY,\n isLonger,\n tickValue,\n showText,\n });\n }\n\n return ticks;\n};", "import { useEffect, useState, MouseEvent, useRef } from 'react';\nimport { getCircle, ICircle } from '../domain/circle-provider';\nimport { getNumber, getString } from '../domain/common-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_PATH_BG_COLOR,\n DEFAULT_PATH_BORDER_COLOR,\n} from '../domain/defaults-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { getAngleByMouse, getClosestPointer, IPointer, IPointers } from '../domain/pointers-provider';\nimport { animate, IAnimationResult, newId } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\nimport InnerCircle from './InnerCircle';\n\ninterface ICircleProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst Circle = (props: ICircleProps) => {\n\n const { settings, pointers, $svg, svg, setPointer } = props;\n\n const [ animation, setAnimation ] = useState(null);\n const [ maskId ] = useState(newId());\n const [ circle, setCircle ] = useState({\n strokeDasharray: '0 1000000',\n strokeOffset: 0,\n });\n\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setCircle(getCircle(\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius\n ));\n }, [\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius,\n ]);\n\n const onClick = (evt: MouseEvent) => {\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n return (\n \n\n {\n settings.pathInnerBgColor &&\n \n }\n\n {\n svg.border > 0 &&\n \n }\n\n \n \n )\n};\n\nexport default Circle;\n", "import { ISvg } from '../domain/svg-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ICircle } from '../domain/circle-provider';\nimport { useEffect, useState } from 'react';\nimport { circleMovement, convertRange, degreesToRadians, mod, Vector2 } from 'mz-math';\nimport { getBoolean } from '../domain/common-provider';\n\ninterface IInnerCircleProps {\n maskId: string;\n settings: ISettings;\n svg: ISvg;\n circle: ICircle;\n}\n\nconst InnerCircle = (props: IInnerCircleProps) => {\n\n const { svg, maskId, settings, circle } = props;\n\n const [ startPoint, setStartPoint ] = useState([0, 0]);\n const [ endPoint, setEndPoint ] = useState([0, 0]);\n const [ largeArcFlag, setLargeArcFlag ] = useState(0);\n const [ pathInnerBgFull, setPathInnerBgFull] = useState(false);\n\n useEffect(() => {\n if(mod(svg.startAngleDeg, 360) === mod(svg.endAngleDeg, 360)) {\n setPathInnerBgFull(true);\n return;\n }\n\n setPathInnerBgFull(getBoolean(settings.pathInnerBgFull, false));\n }, [\n settings.pathInnerBgFull,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const startAngleDeg = convertRange(svg.startAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setStartPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(startAngleDeg), svg.radius));\n\n const endAngleDeg = convertRange(svg.endAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setEndPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(endAngleDeg), svg.radius));\n\n const largeArcFlag = svg.endAngleDeg - svg.startAngleDeg <= 180 ? 1 : 0;\n setLargeArcFlag(largeArcFlag);\n }, [\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n ]);\n\n return (\n <>\n {\n !pathInnerBgFull &&\n \n \n \n \n }\n\n \n \n )\n};\n\nexport default InnerCircle;"], + "mappings": "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", "names": ["useEffect", "useRef", "useState", "setDecimalPlaces", "num", "decimalPlaces", "coefficient", "__pow", "mod", "n", "m", "convertRange", "x", "a", "b", "c", "d", "isNumber", "value", "radiansToDegrees", "radians", "decimalPlaces", "res", "setDecimalPlaces", "degreesToRadians", "degrees", "vSub", "vector1", "vector2", "decimalPlaces", "vector", "i", "setDecimalPlaces", "v2Sub", "vMulScalar", "v", "scalar", "decimalPlaces", "vector", "i", "setDecimalPlaces", "v2MulScalar", "v2", "vLength", "vector", "decimalPlaces", "sum", "i", "setDecimalPlaces", "v2Distance", "vector1", "vector2", "decimalPlaces", "diff", "vSub", "vLength", "vNormalize", "v", "decimalPlaces", "length", "vLength", "unitVector", "i", "setDecimalPlaces", "v2Normalize", "v2", "circleMovement", "center", "angle", "radius", "newId", "animate", "props", "_duration", "startTime", "animationId", "elapsed", "previousTimeStamp", "animating", "observer", "stop", "restart", "start", "pause", "resume", "step", "timeStamp", "getResult", "observerHandler", "_entries", "_observer", "getElapsedTime", "isAnimating", "getStartTime", "getPercent", "getResizeObserver", "getSvg", "circleRadius", "circleThickness", "circleBorder", "maxPointerRadius", "startAngleDeg", "endAngleDeg", "thickness", "diff", "size", "cx", "cy", "getSVGCenter", "getSVGSize", "val", "s", "DEFAULT_PATH_BG_COLOR", "DEFAULT_PATH_BORDER_COLOR", "DEFAULT_POINTER_BG_COLOR", "DEFAULT_POINTER_BG_COLOR_SELECTED", "DEFAULT_POINTER_BG_COLOR_DISABLED", "DEFAULT_POINTER_BORDER_COLOR", "DEFAULT_CONNECTION_BG_COLOR", "DEFAULT_CONNECTION_BG_COLOR_DISABLED", "DEFAULT_TEXT_COLOR", "DEFAULT_TICKS_COLOR", "DEFAULT_TICKS_VALUES_COLOR", "getNumber", "value", "defaultValue", "H", "getString", "getBoolean", "isAngleInArc", "startAngleDeg", "endAngleDeg", "currentDegrees", "getAnglesDistance", "startAngle", "endAngle", "diff", "diffMod", "y", "getCircle", "radius", "circumference", "angleDiff", "strokeOffset", "strokeDasharray", "complement", "getAngleByMouse", "$svg", "clientX", "clientY", "cx", "cy", "rx", "ry", "left", "top", "relativeMouse", "vector", "R", "angleRad", "Mr", "angle2value", "data", "angle", "pathStartAngle", "pathEndAngle", "value", "j", "index", "s", "value2angle", "_value", "valueIndex", "item", "y", "initPointers", "settings", "angleDeg", "getNumber", "bgColor", "getString", "DEFAULT_POINTER_BG_COLOR", "bgColorSelected", "DEFAULT_POINTER_BG_COLOR_SELECTED", "bgColorDisabled", "DEFAULT_POINTER_BG_COLOR_DISABLED", "bgColorHover", "DEFAULT_POINTER_BORDER_COLOR", "pointers", "i", "settingPointer", "radius", "border", "borderColor", "disabled", "getBoolean", "angleAfterStep", "roundToStep", "getPointers", "getMaxRadius", "max", "pointer", "getClosestPointer", "currentPlaceDegrees", "pathRadius", "hr", "currentPointOnArc", "Kt", "min", "closestPointer", "enabledPointers", "p", "pointerAngleRad", "pointOnArc", "distance", "Er", "__spreadValues", "getClosestEdge", "startAngleDegrees", "endAngleDegrees", "startAngleRad", "startPointOnArc", "endAngleRad", "endPointOnArc", "distance1", "distance2", "getMinMaxDistancePointers", "minDistance", "maxDistance", "minPointer", "maxPointer", "getAnglesDistance", "step", "useEffect", "useState", "useRef", "useCallback", "outlineNoneStyle", "Fragment", "jsx", "jsxs", "getPointerFill", "pointer", "selectedPointerId", "bgColor", "bgColorSelected", "bgColorDisabled", "bgColorHover", "isMouseOver", "Pointer", "props", "pointerRef", "useRef", "svg", "$svg", "data", "settings", "setPointer", "radius", "angleDeg", "border", "borderColor", "cx", "cy", "center", "setCenter", "useState", "value", "setValue", "fill", "setFill", "DEFAULT_POINTER_BG_COLOR", "setIsMouseOver", "useEffect", "angle2value", "angleRad", "j", "hr", "pointerCenter", "Kt", "onValueChange", "useCallback", "evt", "mouseX", "mouseY", "degrees", "getAngleByMouse", "newAngleDeg", "isAngleInArc", "getClosestEdge", "onMouseUp", "onMouseDown", "onKeyDown", "$current", "onTouch", "onWheel", "scrollTop", "onMouseOver", "onMouseOut", "outlineNoneStyle", "Pointer_default", "Fragment", "jsx", "Pointers", "props", "pointers", "settings", "svg", "$svg", "data", "setPointer", "selectedPointerId", "pointer", "Pointer_default", "Pointers_default", "getData", "setting", "min", "getNumber", "max", "step", "arrowStep", "round", "data", "minIndex", "item", "maxIndex", "pathStartAngle", "pathEndAngle", "isClosedShape", "y", "stepAngleDeg", "arrowStepAngleDeg", "useCallback", "useEffect", "useRef", "useState", "getConnection", "pointers", "radius", "cx", "cy", "pathStartAngle", "pathEndAngle", "result", "pathAnglesDistance", "getAnglesDistance", "angleDistance", "circumference", "strokeOffset", "strokeDasharray", "complement", "getAnimationProgressAngle", "progress", "animationSourceDegrees", "animationTargetDegrees", "startPathAngleDeg", "percent", "angle1", "angle2", "clockwiseDistance", "y", "counterclockwiseDistance", "Fragment", "jsx", "getStroke", "disabled", "connectionBgColorDisabled", "connectionBgColor", "isMouseOver", "connectionBgColorHover", "getString", "DEFAULT_CONNECTION_BG_COLOR_DISABLED", "bgColor", "DEFAULT_CONNECTION_BG_COLOR", "Connection", "props", "settings", "pointers", "$svg", "svg", "data", "setPointer", "connection", "setConnection", "useState", "animation", "setAnimation", "stroke", "setStroke", "setIsMouseOver", "rangeDraggingLastAngle", "useRef", "animationClosestPointer", "animationSourceDegrees", "animationTargetDegrees", "useEffect", "getConnection", "onClick", "evt", "degrees", "getAngleByMouse", "closestPointer", "getClosestPointer", "onValueChange", "useCallback", "minMaxResult", "getMinMaxDistancePointers", "minPointer", "maxPointer", "mouseDegrees", "diff", "y", "onMouseUp", "onMouseDown", "_animation", "Fo", "progress", "currentDegrees", "getAnimationProgressAngle", "getNumber", "onMouseOver", "onMouseOut", "getBoolean", "Connection_default", "useEffect", "useState", "Fragment", "jsx", "Text", "props", "settings", "pointers", "svg", "data", "cx", "cy", "value", "setValue", "values", "pointer", "angle2value", "value1", "value2", "texts", "textBetween", "getString", "hideText", "getBoolean", "getNumber", "DEFAULT_TEXT_COLOR", "Text_default", "useEffect", "useState", "Fragment", "getTicksSettings", "settings", "data", "ticksCount", "getNumber", "ticksHeight", "getBoolean", "getString", "DEFAULT_TICKS_COLOR", "DEFAULT_TICKS_VALUES_COLOR", "getTicks", "ticksSettings", "pathStartAngle", "pathEndAngle", "svg", "ticks", "deltaAngle", "oneTickAngleSize", "count", "i", "currentAngle", "angleRad", "j", "hr", "x", "y", "Kt", "isLonger", "desiredDistance", "normalizedDirectionVector", "E", "tickEndVector", "wr", "tickStartVector", "x1", "y1", "tickValue", "value", "index", "s", "textX", "textY", "showText", "_tickValuesDistance", "tickTextVector", "Fragment", "jsx", "jsxs", "Ticks", "props", "settings", "svg", "data", "ticksSettings", "setTicksSettings", "useState", "ticks", "setTicks", "useEffect", "getTicksSettings", "endAngleDeg", "getTicks", "tick", "i", "x", "y", "x1", "y1", "textX", "textY", "showText", "Ticks_default", "useEffect", "useState", "useRef", "useEffect", "useState", "Fragment", "jsx", "jsxs", "InnerCircle", "props", "svg", "maskId", "settings", "circle", "startPoint", "setStartPoint", "useState", "endPoint", "setEndPoint", "largeArcFlag", "setLargeArcFlag", "pathInnerBgFull", "setPathInnerBgFull", "useEffect", "y", "getBoolean", "startAngleDeg", "j", "Kt", "hr", "endAngleDeg", "InnerCircle_default", "jsx", "jsxs", "Circle", "props", "settings", "pointers", "$svg", "svg", "setPointer", "animation", "setAnimation", "useState", "maskId", "Yo", "circle", "setCircle", "animationClosestPointer", "useRef", "animationSourceDegrees", "animationTargetDegrees", "useEffect", "getCircle", "onClick", "evt", "degrees", "getAngleByMouse", "closestPointer", "getClosestPointer", "_animation", "Fo", "progress", "currentDegrees", "getAnimationProgressAngle", "getNumber", "InnerCircle_default", "getString", "DEFAULT_PATH_BORDER_COLOR", "DEFAULT_PATH_BG_COLOR", "Circle_default", "Fragment", "jsx", "jsxs", "RoundSlider", "props", "data", "setData", "useState", "svg", "setSvg", "pointers", "setPointers", "selectedPointerId", "setSelectedPointerId", "prevAngleDegRef", "useRef", "svgRef", "useEffect", "_data", "getData", "getPointers", "pathStartAngle", "getNumber", "pathEndAngle", "getSvg", "clearSelectedPointer", "evt", "setPointersCallback", "pointer", "newAngleDeg", "roundToStep", "y", "updatePointer", "prevAngle", "nextAngle", "prevIndex", "nextIndex", "prevPointer", "nextPointer", "splitPointDeg", "t1", "t2", "clockwiseNew", "isAngleInArc", "clockwisePrev", "clockwise", "t3", "t4", "counterClockwiseNew", "counterClockwisePrev", "getClosestEdge", "angleChanged", "_a", "_pointers", "__spreadValues", "updatedPointers", "val", "angle2value", "$pointer", "__spreadProps", "outlineNoneStyle", "Circle_default", "Ticks_default", "Connection_default", "Pointers_default", "Text_default"] } diff --git a/dist/mz-react-round-slider.min.js b/dist/mz-react-round-slider.min.js index 74da8d4..4ee045f 100644 --- a/dist/mz-react-round-slider.min.js +++ b/dist/mz-react-round-slider.min.js @@ -4,7 +4,7 @@ https://github.com/mzusin/react-round-slider MIT License Copyright (c) 2023-present, Miriam Zusin */ -(()=>{var zt=Object.create;var Oe=Object.defineProperty,Gt=Object.defineProperties,qt=Object.getOwnPropertyDescriptor,Xt=Object.getOwnPropertyDescriptors,Yt=Object.getOwnPropertyNames,Ye=Object.getOwnPropertySymbols,Kt=Object.getPrototypeOf,We=Object.prototype.hasOwnProperty,Wt=Object.prototype.propertyIsEnumerable;var Ke=(e,t,n)=>t in e?Oe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,ce=(e,t)=>{for(var n in t||(t={}))We.call(t,n)&&Ke(e,n,t[n]);if(Ye)for(var n of Ye(t))Wt.call(t,n)&&Ke(e,n,t[n]);return e},je=(e,t)=>Gt(e,Xt(t));var xe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var jt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Yt(t))!We.call(e,r)&&r!==n&&Oe(e,r,{get:()=>t[r],enumerable:!(o=qt(t,r))||o.enumerable});return e};var T=(e,t,n)=>(n=e!=null?zt(Kt(e)):{},jt(t||!e||!e.__esModule?Oe(n,"default",{value:e,enumerable:!0}):n,e));var at=xe(p=>{"use strict";var me=Symbol.for("react.element"),Zt=Symbol.for("react.portal"),Qt=Symbol.for("react.fragment"),Jt=Symbol.for("react.strict_mode"),er=Symbol.for("react.profiler"),tr=Symbol.for("react.provider"),rr=Symbol.for("react.context"),nr=Symbol.for("react.forward_ref"),or=Symbol.for("react.suspense"),sr=Symbol.for("react.memo"),ir=Symbol.for("react.lazy"),Ze=Symbol.iterator;function ar(e){return e===null||typeof e!="object"?null:(e=Ze&&e[Ze]||e["@@iterator"],typeof e=="function"?e:null)}var et={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},tt=Object.assign,rt={};function se(e,t,n){this.props=e,this.context=t,this.refs=rt,this.updater=n||et}se.prototype.isReactComponent={};se.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};se.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function nt(){}nt.prototype=se.prototype;function Fe(e,t,n){this.props=e,this.context=t,this.refs=rt,this.updater=n||et}var Be=Fe.prototype=new nt;Be.constructor=Fe;tt(Be,se.prototype);Be.isPureReactComponent=!0;var Qe=Array.isArray,ot=Object.prototype.hasOwnProperty,$e={current:null},st={key:!0,ref:!0,__self:!0,__source:!0};function it(e,t,n){var o,r={},s=null,i=null;if(t!=null)for(o in t.ref!==void 0&&(i=t.ref),t.key!==void 0&&(s=""+t.key),t)ot.call(t,o)&&!st.hasOwnProperty(o)&&(r[o]=t[o]);var a=arguments.length-2;if(a===1)r.children=n;else if(1{"use strict";lt.exports=at()});var yt=xe(ye=>{"use strict";var xr=K(),Sr=Symbol.for("react.element"),Ir=Symbol.for("react.fragment"),Ar=Object.prototype.hasOwnProperty,Cr=xr.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Er={key:!0,ref:!0,__self:!0,__source:!0};function Pt(e,t,n){var o,r={},s=null,i=null;n!==void 0&&(s=""+n),t.key!==void 0&&(s=""+t.key),t.ref!==void 0&&(i=t.ref);for(o in t)Ar.call(t,o)&&!Er.hasOwnProperty(o)&&(r[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps,t)r[o]===void 0&&(r[o]=t[o]);return{$$typeof:Sr,type:e,key:s,ref:i,props:r,_owner:Cr.current}}ye.Fragment=Ir;ye.jsx=Pt;ye.jsxs=Pt});var M=xe((bn,Mt)=>{"use strict";Mt.exports=yt()});var $=T(K(),1);var gr=Math.pow,U=(e,t=1/0)=>{if(t===1/0)return e;t<0&&(t=0);let n=gr(10,t);return Math.round(e*n)/n},S=(e,t)=>(e%t+t)%t,R=(e,t,n,o,r)=>(r-o)*(e-t)/(n-t)+o;var ut=e=>!isNaN(parseFloat(e))&&isFinite(e);var ct=(e,t=1/0)=>{let n=e*(180/Math.PI);return U(n,t)},F=(e,t=1/0)=>{let n=e*(Math.PI/180);return U(n,t)};var mt=(e,t,n=1/0)=>{let o=[];for(let r=0;rmt(e,t,n);var dr=(e,t,n=1/0)=>{let o=[];for(let r=0;rdr(e,t,n);var dt=(e,t=1/0)=>{let n=0;for(let o=0;o{let o=mt(e,t);return dt(o,n)};var fr=(e,t=1/0)=>{let n=dt(e),o=[];for(let r=0;rfr(e,t);var B=(e,t,n)=>(t=t%Math.PI*2,[e[0]+Math.cos(t)*n,e[1]+Math.sin(t)*n]);var ht=()=>Math.random().toString(36).substring(2)+new Date().getTime().toString(36);var Te=e=>{let t=e.duration!==void 0?e.duration:1/0,n,o,r,s,i=!1,a,l=()=>{n=void 0,r=void 0,s=void 0,i=!1,o!==void 0&&window.cancelAnimationFrame(o)},c=()=>{l(),m()},g=()=>{i=!1},f=()=>{i=!0},b=k=>{n===void 0&&(n=k),r=k-n,i&&s!==k&&typeof e.callback=="function"&&e.callback(A()),r<=t?(s=k,o=window.requestAnimationFrame(b)):l()},u=(k,P)=>{c(),typeof e.resizeCallback=="function"&&e.resizeCallback(k,P)},m=()=>{n=void 0,r=void 0,s=void 0,i=!0,e.restartOnResize&&window.ResizeObserver&&a===void 0?(a=new ResizeObserver(u),a.observe(document.body,{box:"border-box"})):o=window.requestAnimationFrame(b)},D=()=>r,h=()=>i,v=()=>n,_=()=>{if(!(t===1/0||r===void 0))return r*100/t},L=()=>a,A=()=>({start:m,stop:l,pause:g,resume:f,restart:c,isAnimating:h,getElapsedTime:D,getStartTime:v,getPercent:_,getResizeObserver:L});return A()};var pt=(e,t,n,o,r,s)=>{let i=t+n*2,a=Math.max(0,o*2-i),l=e*2+i+a,[c,g]=hr(e,o,t,n);return{cx:c,cy:g,radius:e,size:l,thickness:t,border:n,startAngleDeg:r,endAngleDeg:s}},hr=(e,t,n,o)=>{let r=pr(e,t,n,o),s=U(r/2,2);return[s,s]},pr=(e,t,n,o)=>{let r=n+o*2,s=Math.max(0,t*2-r);return e*2+r+s};var bt="#efefef";var vt="#444444";var ge="#163a86",Ve="#000",He="#a8a8a8";var ze="#000",Ge="#5daed2",Dt="#97b0bb",xt="#000";var St="#efefef",It="#000";var d=(e,t)=>ut(e)?Number(e):t,I=(e,t)=>e==null?t:e,V=(e,t)=>e==null?t:e;var Z=(e,t,n)=>(e>t&&(t+=360),n>=e&&n<=t||n+360>=e&&n+360<=t),de=(e,t)=>{t0?360:o},At=(e,t,n)=>{e>t&&(t+=360);let o=2*Math.PI*n,r=t-e,s=-(e/360)*o,i=r/360*o,a=o-i;return{strokeDasharray:[i,a].join(" "),strokeOffset:s}};var re=(e,t,n,o,r,s,i)=>{let{left:a,top:l}=e.getBoundingClientRect(),c=[t-a,n-l],g=gt(c,[o,r]),f=Math.atan2(g[1]/i,g[0]/s);return f<0&&(f+=2*Math.PI),ct(f)},ae=(e,t,n,o)=>{o0){let s=Math.round(r);r=e.data[s]}else r=U(r,e.round);return r},br=(e,t,n,o)=>{let r;if(o0){let s=e.data.findIndex(i=>i===t);r=s===-1?0:s}else r=typeof t!="number"?e.min:t;return S(R(r,e.min,e.max,n,o),360)},vr=(e,t)=>{if(!e||!e.pointers||e.pointers.length<0||!t){let o=S(d(e.pathStartAngle,0),360),r=I(e.pointerBgColor,ge),s=I(e.pointerBgColorSelected,Ve),i=I(e.pointerBgColorDisabled,He),a=I(e.pointerBgColorHover,s);return[{id:"0",index:0,radius:d(e.pointerRadius,10),angleDeg:o,prevAngleDeg:o,bgColor:r,bgColorSelected:s,bgColorDisabled:i,bgColorHover:a,border:d(e.pointerBorder,0),borderColor:I(e.pointerBorderColor,ze),disabled:!!e.disabled}]}let n=[];for(let o=0;o{let n=vr(e,t);return{pointers:n,maxRadius:Dr(n)}},Dr=e=>{if(e.length<=0)return 0;let t=-1/0;for(let n of e)t=Math.max(t,Math.max(0,n.radius+n.border/2));return t},_e=(e,t,n,o,r)=>{if(!e||e.length<=0)return null;if(e.length===1)return e[0];let s=R(F(t),0,Math.PI*2,0,Math.PI),i=B([n,o],s,r),a,l=null,c=e.filter(g=>!g.disabled);for(let g of c){let f=R(F(g.angleDeg),0,Math.PI*2,0,Math.PI),b=B([n,o],f,r),u=Ee(i,b);(a===void 0||u{let i=R(F(n),0,Math.PI*2,0,Math.PI),a=B([o,r],i,s),l=R(F(e),0,Math.PI*2,0,Math.PI),c=B([o,r],l,s),g=R(F(t),0,Math.PI*2,0,Math.PI),f=B([o,r],g,s),b=Ee(a,c),u=Ee(a,f);return b<=u?e:t},_t=(e,t)=>{if(!e||e.length<=0)return null;let n,o,r=null,s=null;for(let i of e){let a=de(t,i.angleDeg);(n===void 0||ao)&&(s=i,o=a)}return r===null||s===null?null:[r,s]},qe=(e,t,n,o)=>S(e,360)===S(n,360)||S(e,360)===S(o,360)?e:t===0?0:Math.round(e/t)*t;var N=T(K(),1);var he={outline:"none"};var Q=T(M(),1),Tr=(e,t,n,o,r,s,i)=>e.disabled?r:i?s:e.id===t?o:n,_r=e=>{let t=(0,N.useRef)(null),{pointer:n,svg:o,$svg:r,data:s,settings:i,setPointer:a,selectedPointerId:l}=e,{radius:c,angleDeg:g,bgColor:f,bgColorSelected:b,bgColorDisabled:u,bgColorHover:m,border:D,borderColor:h}=e.pointer,{cx:v,cy:_}=o,[L,A]=(0,N.useState)(null),[k,P]=(0,N.useState)(""),[te,G]=(0,N.useState)(ge),[y,C]=(0,N.useState)(!1);(0,N.useEffect)(()=>{G(Tr(n,l,f,b,u,m,y))},[n,l,f,b,u,m,y]),(0,N.useEffect)(()=>{let x=ae(s,n.angleDeg,o.startAngleDeg,o.endAngleDeg);P(x===void 0?"":x.toString())},[s,n.angleDeg,o.startAngleDeg,o.endAngleDeg]),(0,N.useEffect)(()=>{let x=R(F(g),0,Math.PI*2,0,Math.PI),oe=B([v,_],x,o.radius);A(oe)},[g,v,_,o.radius]);let E=(0,N.useCallback)(x=>{if(!r||i.disabled||n.disabled)return;let oe=x.type.indexOf("mouse")!==-1?x.clientX:x.touches[0].clientX,De=x.type.indexOf("mouse")!==-1?x.clientY:x.touches[0].clientY,X=re(r,oe,De,o.cx,o.cy,o.radius,o.radius),ue;Z(o.startAngleDeg,o.endAngleDeg,X)?ue=X:ue=Pe(o.startAngleDeg,o.endAngleDeg,n.angleDeg,o.cx,o.cy,o.radius),a(n,ue)},[r,n,a,o.cx,o.cy,o.endAngleDeg,o.radius,o.startAngleDeg,i.disabled]),ne=()=>{window.removeEventListener("mousemove",E),window.removeEventListener("mouseup",E)},Y=x=>{i.disabled||n.disabled||(E(x),window.addEventListener("mousemove",E),window.addEventListener("mouseup",ne))},q=x=>{if(!(i.disabled||n.disabled||i.keyboardDisabled))switch(x.key){case"ArrowLeft":{x.preventDefault(),a(n,n.angleDeg+s.arrowStepAngleDeg);break}case"ArrowRight":{x.preventDefault(),a(n,n.angleDeg-s.arrowStepAngleDeg);break}case"ArrowUp":{x.preventDefault(),a(n,n.angleDeg-s.arrowStepAngleDeg);break}case"ArrowDown":{x.preventDefault(),a(n,n.angleDeg+s.arrowStepAngleDeg);break}}};(0,N.useEffect)(()=>{let x=t.current,oe=X=>{i.disabled||n.disabled||(X.preventDefault(),X.stopPropagation(),E(X))},De=X=>{if(i.disabled||n.disabled||i.mousewheelDisabled||document.activeElement!==x)return;X.stopPropagation(),X.preventDefault();let ue=X.deltaY<0,Le;ue?Le=n.angleDeg+s.arrowStepAngleDeg:Le=n.angleDeg-s.arrowStepAngleDeg,a(n,Le)};return x==null||x.addEventListener("touchmove",oe,{passive:!1}),document.addEventListener("wheel",De,{passive:!1}),()=>{x==null||x.removeEventListener("touchmove",oe),document.removeEventListener("wheel",De)}},[L,E,s.arrowStepAngleDeg,n,a,i.disabled,i.mousewheelDisabled]);let Re=()=>{C(!0)},we=()=>{C(!1)};return(0,Q.jsx)(Q.Fragment,{children:L&&(0,Q.jsxs)("g",{ref:t,transform:`translate(${L[0]-c/2}, ${L[1]-c/2})`,role:"slider","aria-disabled":n.disabled?!0:void 0,"aria-valuenow":n.angleDeg,"aria-valuetext":k,"aria-label":n.ariaLabel,"data-type":"pointer",className:`mz-round-slider-pointer ${n.disabled?"mz-round-slider-pointer-disabled":""}`,"data-angle":n.angleDeg,"data-id":n.id,"data-index":n.index,onMouseDown:Y,onKeyDown:q,onMouseOver:Re,onMouseOut:we,tabIndex:0,cursor:n.disabled?"default":"pointer",style:he,children:[!i.pointerSVG&&(0,Q.jsx)("circle",{cx:c/2,cy:c/2,r:c,fill:te,strokeWidth:D,stroke:h,style:{transition:"0.3s fill"}}),i.pointerSVG&&(0,Q.jsx)("g",{children:i.pointerSVG})]})})},kt=_r;var pe=T(M(),1),Pr=e=>{let{pointers:t,settings:n,svg:o,$svg:r,data:s,setPointer:i,selectedPointerId:a}=e;return(0,pe.jsx)(pe.Fragment,{children:t.pointers.map(l=>(0,pe.jsx)(kt,{pointer:l,svg:o,settings:n,$svg:r,data:s,setPointer:i,selectedPointerId:a},l.id))})},Rt=Pr;var Lt=e=>{let t=d(e.min,0),n=d(e.max,100),o=d(e.step,1),r=d(e.arrowStep,1),s=d(e.round,0),i=e.data||[];if(i.length>0){let b=i.findIndex(m=>m===t),u=i.findIndex(m=>m===n);t=b===-1?0:b,n=u===-1?i.length:u}else t>n&&(t=n+100);let a=d(e.pathStartAngle,0),l=d(e.pathEndAngle,360),c=S(a,360)===S(l,360),g=o*360/(n-t),f=r*360/(n-t);return{min:t,max:n,round:s,data:i,stepAngleDeg:g,arrowStepAngleDeg:f,isClosedShape:c}};var w=T(K(),1);var Ot=(e,t,n,o,r,s)=>{if(!e.pointers||e.pointers.length<=0)return null;let i={radius:t,cx:n,cy:o,startAngleDeg:r,endAngleDeg:r,strokeDasharray:[0,0],strokeOffset:0};e.pointers.length===1?(i.startAngleDeg=r,i.endAngleDeg=e.pointers[0].angleDeg):(i.startAngleDeg=e.pointers[0].angleDeg,i.endAngleDeg=e.pointers[e.pointers.length-1].angleDeg);let a=de(r,s);i.startAngleDeg>i.endAngleDeg&&(i.endAngleDeg+=360);let l=de(i.startAngleDeg,i.endAngleDeg);l>a&&(l=360-l,[i.startAngleDeg,i.endAngleDeg]=[i.endAngleDeg,i.startAngleDeg]);let g=2*Math.PI*t,f=-(i.startAngleDeg/360)*g,b=l/360*g,u=g-b;return i.strokeDasharray=[b,u],i.strokeOffset=f,i};var Me=(e,t,n,o)=>{let r=e.getPercent();r<0&&(r=0),r>100&&(r=100);let s=t%360,i=n%360;if(ss){let l=(i-s+360)%360;return S(t+r*l/100,360)}else{let l=(s-i+360)%360;return S(t-r*l/100,360)}};var be=T(M(),1),wr=(e,t,n,o,r)=>{if(e)return I(t,Dt);let s=I(n,Ge);return o?I(r,s):s},Lr=e=>{let{settings:t,pointers:n,$svg:o,svg:r,data:s,setPointer:i}=e,[a,l]=(0,w.useState)(null),[c,g]=(0,w.useState)(null),[f,b]=(0,w.useState)(Ge),[u,m]=(0,w.useState)(!1),D=(0,w.useRef)(),h=(0,w.useRef)(null),v=(0,w.useRef)(0),_=(0,w.useRef)(0);(0,w.useEffect)(()=>{b(wr(t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,u,t.connectionBgColorHover))},[t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,t.connectionBgColorHover,u]),(0,w.useEffect)(()=>{l(Ot(n,r.radius,r.cx,r.cy,r.startAngleDeg,r.endAngleDeg))},[n,r.radius,r.cx,r.cy,r.startAngleDeg,r.endAngleDeg]);let L=y=>{if(!o||t.disabled||c&&c.isAnimating())return;let C=re(o,y.clientX,y.clientY,r.cx,r.cy,r.radius,r.radius),E=_e(n.pointers,C,r.cx,r.cy,r.radius);E&&(t.animateOnClick?(h.current=E,v.current=E.angleDeg,_.current=C,c==null||c.start()):i(E,C))},A=(0,w.useCallback)(y=>{if(!o||t.disabled||!t.rangeDragging)return;let C=_t(n.pointers,r.startAngleDeg);if(!C)return;let[E,ne]=C,Y=re(o,y.clientX,y.clientY,r.cx,r.cy,r.radius,r.radius);if(D.current===void 0){D.current=Y;return}let q=Y-D.current;q===0||Math.abs(q){window.removeEventListener("mousemove",A),window.removeEventListener("mouseup",A),D.current=void 0},P=y=>{!t.rangeDragging||t.disabled||n.pointers.length<=1||(A(y),window.addEventListener("mousemove",A),window.addEventListener("mouseup",k))};(0,w.useEffect)(()=>{if(c&&c.stop(),!t.animateOnClick){g(null);return}let y=Te({callback:C=>{if(!h.current)return;let E=Me(C,v.current,_.current,r.startAngleDeg);i(h.current,E)},duration:d(t.animationDuration,200)});g(y)},[t.animateOnClick,t.animationDuration]);let te=()=>{m(!0)},G=()=>{m(!1)};return(0,be.jsx)(be.Fragment,{children:!V(t.hideConnection,!1)&&a&&(0,be.jsx)("circle",{"data-type":"connection",className:"mz-round-slider-connection",cx:a.cx,cy:a.cy,r:a.radius,strokeDasharray:a.strokeDasharray.join(" "),strokeDashoffset:a.strokeOffset,stroke:f,strokeWidth:r.thickness+1,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:t.disabled?"default":"pointer",onClick:L,onMouseDown:P,onMouseOver:te,onMouseOut:G,style:{transition:"0.2s stroke"}})})},Nt=Lr;var ke=T(K(),1),ve=T(M(),1),Nr=e=>{let{settings:t,pointers:n,svg:o,data:r}=e,{cx:s,cy:i}=o,[a,l]=(0,ke.useState)("");(0,ke.useEffect)(()=>{let g=n.pointers.map(u=>ae(r,u.angleDeg,o.startAngleDeg,o.endAngleDeg));g.sort((u,m)=>u.toString().localeCompare(m.toString(),"en",{numeric:!0}));let f=g.map(u=>`${t.textPrefix||""}${u}${t.textSuffix||""}`),b=I(t.textBetween," ");l(f.join(b))},[r,n.pointers,o.startAngleDeg,o.endAngleDeg,t.textPrefix,t.textSuffix,t.textBetween]);let c=V(t.hideText,!1);return(0,ve.jsx)(ve.Fragment,{children:!c&&(0,ve.jsx)("text",{"data-type":"text",className:"mz-round-slider-text",x:s+d(t.textOffsetX,0),y:i+d(t.textOffsetY,0),fill:I(t.textColor,xt),fontSize:d(t.textFontSize,16),fontFamily:t.textFontFamily,style:{userSelect:"none",whiteSpace:"pre"},textAnchor:"middle",children:a})})},Ft=Nr;var J=T(K(),1);var Bt=(e,t)=>{let n=d(e.ticksCount,0);n||(t.data&&t.data.length>0?n=t.data.length:n=t.max);let o=d(e.ticksHeight,10);return{ticksCount:n,enableTicks:V(e.enableTicks,!1),ticksWidth:d(e.ticksWidth,3),ticksHeight:o,longerTicksHeight:d(e.longerTicksHeight,o*2),ticksDistanceToPanel:d(e.ticksDistanceToPanel,0),tickValuesDistance:d(e.tickValuesDistance,15),ticksColor:I(e.ticksColor,St),tickValuesColor:I(e.tickValuesColor,It),tickValuesFontSize:d(e.tickValuesFontSize,12),ticksGroupSize:d(e.ticksGroupSize,10),longerTickValuesOnly:V(e.longerTickValuesOnly,!0),showTickValues:V(e.showTickValues,!0)}},$t=(e,t,n,o,r,s)=>{let i=[],a=Math.abs(o-n),l=t===0?0:a/t,c=t;s.isClosedShape||c++;for(let g=0;g0){let E=Math.round(C);C=s.data[E]}else C=U(C,s.round);P=(C!=null?C:"").toString()}let te=0,G=0,y=P!==void 0;if(y){let C=d(h+e.tickValuesDistance,h*1.5),E=Ce(v,C);te=u+E[0],G=m+E[1]}i.push({x:u,y:m,x1:A,y1:k,textX:te,textY:G,isLonger:D,tickValue:P,showText:y})}return i};var W=T(M(),1),zr=e=>{let{settings:t,svg:n,data:o}=e,[r,s]=(0,J.useState)(null),[i,a]=(0,J.useState)([]);return(0,J.useEffect)(()=>{s(Bt(t,o))},[t,o]),(0,J.useEffect)(()=>{if(!r)return;let l=n.endAngleDeg;l{let{x:g,y:f,x1:b,y1:u,textX:m,textY:D,showText:h}=l;return(0,W.jsxs)(J.Fragment,{children:[(0,W.jsx)("line",{x1:g,y1:f,x2:b,y2:u,strokeWidth:r.ticksWidth,stroke:r.ticksColor,"data-type":"tick",className:"mz-round-slider-tick"}),h&&(0,W.jsxs)("text",{"data-type":"tick-text",className:"mz-round-slider-tick-text",x:m,y:D,textAnchor:"middle",dominantBaseline:"middle",fill:r.tickValuesColor,fontSize:r.tickValuesFontSize,fontFamily:t.tickValuesFontFamily,style:{userSelect:"none",whiteSpace:"pre"},children:[t.tickValuesPrefix,l.tickValue,t.tickValuesSuffix]})]},c)})})})},Ut=zr;var z=T(K(),1);var ee=T(K(),1);var j=T(M(),1),Gr=e=>{let{svg:t,maskId:n,settings:o,circle:r}=e,[s,i]=(0,ee.useState)([0,0]),[a,l]=(0,ee.useState)([0,0]),[c,g]=(0,ee.useState)(0),[f,b]=(0,ee.useState)(!1);return(0,ee.useEffect)(()=>{if(S(t.startAngleDeg,360)===S(t.endAngleDeg,360)){b(!0);return}b(V(o.pathInnerBgFull,!1))},[o.pathInnerBgFull,t.startAngleDeg,t.endAngleDeg]),(0,ee.useEffect)(()=>{let u=R(t.startAngleDeg,0,Math.PI*2,0,Math.PI);i(B([t.cx,t.cy],F(u),t.radius));let m=R(t.endAngleDeg,0,Math.PI*2,0,Math.PI);l(B([t.cx,t.cy],F(m),t.radius));let D=t.endAngleDeg-t.startAngleDeg<=180?1:0;g(D)},[t.cx,t.cy,t.endAngleDeg,t.radius,t.startAngleDeg]),(0,j.jsxs)(j.Fragment,{children:[!f&&(0,j.jsxs)("mask",{id:n,children:[(0,j.jsx)("path",{fill:"black",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 1 ${c} 0 ${a[0]} ${a[1]}`}),(0,j.jsx)("path",{fill:"white",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 0 ${c===1?0:1} 1 ${a[0]} ${a[1]}`})]}),(0,j.jsx)("circle",{strokeDasharray:r.strokeDasharray,strokeDashoffset:r.strokeOffset,cx:t.cx,cy:t.cy,r:t.radius,stroke:"transparent",strokeWidth:t.thickness,fill:o.pathInnerBgColor,shapeRendering:"geometricPrecision",strokeLinecap:"round","data-type":"path-inner",className:"mz-round-slider-path-inner",mask:f?"":`url(#${n})`})]})},Vt=Gr;var le=T(M(),1),qr=e=>{let{settings:t,pointers:n,$svg:o,svg:r,setPointer:s}=e,[i,a]=(0,z.useState)(null),[l]=(0,z.useState)(ht()),[c,g]=(0,z.useState)({strokeDasharray:"0 1000000",strokeOffset:0}),f=(0,z.useRef)(null),b=(0,z.useRef)(0),u=(0,z.useRef)(0);(0,z.useEffect)(()=>{g(At(r.startAngleDeg,r.endAngleDeg,r.radius))},[r.startAngleDeg,r.endAngleDeg,r.radius]);let m=D=>{if(!o||t.disabled||i&&i.isAnimating())return;let h=re(o,D.clientX,D.clientY,r.cx,r.cy,r.radius,r.radius),v=_e(n.pointers,h,r.cx,r.cy,r.radius);v&&(t.animateOnClick?(f.current=v,b.current=v.angleDeg,u.current=h,i==null||i.start()):s(v,h))};return(0,z.useEffect)(()=>{if(i&&i.stop(),!t.animateOnClick){a(null);return}let D=Te({callback:h=>{if(!f.current)return;let v=Me(h,b.current,u.current,r.startAngleDeg);s(f.current,v)},duration:d(t.animationDuration,200)});a(D)},[t.animateOnClick,t.animationDuration]),(0,le.jsxs)("g",{onClick:m,children:[t.pathInnerBgColor&&(0,le.jsx)(Vt,{maskId:l,settings:t,svg:r,circle:c}),r.border>0&&(0,le.jsx)("circle",{strokeDasharray:c.strokeDasharray,strokeDashoffset:c.strokeOffset,cx:r.cx,cy:r.cy,r:r.radius,stroke:I(t.pathBorderColor,vt),strokeWidth:r.thickness+r.border*2,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path-border",className:"mz-round-slider-path-border"}),(0,le.jsx)("circle",{strokeDasharray:c.strokeDasharray,strokeDashoffset:c.strokeOffset,cx:r.cx,cy:r.cy,r:r.radius,stroke:I(t.pathBgColor,bt),strokeWidth:r.thickness,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path",className:"mz-round-slider-path"})]})},Ht=qr;var H=T(M(),1),Xo=e=>{let[t,n]=(0,$.useState)(null),[o,r]=(0,$.useState)(null),[s,i]=(0,$.useState)(null),[a,l]=(0,$.useState)(""),c=(0,$.useRef)(null),g=(0,$.useRef)(null);(0,$.useEffect)(()=>{let u=Lt(e);JSON.stringify(t)!==JSON.stringify(u)&&n(u)},[t,e]),(0,$.useEffect)(()=>{i(Tt(e,t))},[e.pointerRadius,e.pathStartAngle,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pointers,e.pointerRadius,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pathStartAngle,e.pathEndAngle,t]),(0,$.useEffect)(()=>{if(!s)return;let u=d(e.pathStartAngle,0),m=d(e.pathEndAngle,360);m<=u&&(m+=360),r(pt(d(e.pathRadius,150),d(e.pathThickness,5),d(e.pathBorder,0),s.maxRadius,u,m))},[e.pathRadius,e.pathThickness,e.pathBorder,e.pathStartAngle,e.pathEndAngle,s]),(0,$.useEffect)(()=>{let u=m=>{m.target.closest('[data-type="pointer"]')||l("")};return document.addEventListener("mousedown",u),()=>{document.removeEventListener("mousedown",u)}},[]);let f=(u,m)=>{if(e.disabled||!s.pointers||!u||u.disabled)return;if(m=qe(m,t.stepAngleDeg,o.startAngleDeg,o.endAngleDeg),t.isClosedShape&&S(m,360)===S(o.endAngleDeg,360)&&(m=o.startAngleDeg),u.angleDeg===m){b(u,m,!1);return}if(!e.pointersOverlap){let h,v;if(t.isClosedShape){let _=S(u.index-1,s.pointers.length),L=S(u.index+1,s.pointers.length),A=s.pointers[_],k=s.pointers[L];if(h=A.angleDeg,v=k.angleDeg,s.pointers.length===2&&h===v){let P=h;if(c.current===null)c.current=m;else{let G=P-150,y=P-.001;G<0&&(G+=360),y<0&&(y+=360);let C=Z(P+.001,P+150,m),E=Z(G,y,c.current),ne=C&&E,Y=P-150,q=P-.001;Y<0&&(Y+=360),q<0&&(q+=360);let Re=Z(Y,q,m),we=Z(P+.001,P+150,c.current);if(ne||Re&&we){b(u,P,!0);return}m!==P&&(c.current=m)}}}else h=u.index===0?o.startAngleDeg:s.pointers[u.index-1].angleDeg,v=u.index===s.pointers.length-1?o.endAngleDeg:s.pointers[u.index+1].angleDeg;v<=h&&(v+=360),Z(h,v,m)||(m=Pe(h,v,m,o.cx,o.cy,o.radius))}b(u,m,u.angleDeg!==m)},b=(u,m,D)=>{var v;if(D){let _=ce({},s);if(_.pointers=[...s.pointers],_.pointers[u.index].prevAngleDeg=_.pointers[u.index].angleDeg,_.pointers[u.index].angleDeg=m,s.pointers=_.pointers,i(_),typeof e.onChange=="function"){let L=_.pointers.map(A=>{let k=ae(t,A.angleDeg,o.startAngleDeg,o.endAngleDeg);return{radius:A.radius,value:k,bgColor:A.bgColor,bgColorSelected:A.bgColorSelected,bgColorDisabled:A.bgColorDisabled,border:A.border,borderColor:A.borderColor,disabled:A.disabled,ariaLabel:A.ariaLabel}});e.onChange(L)}}l(u.id);let h=(v=g.current)==null?void 0:v.querySelector(`[data-id="${u.id}"]`);h&&h.focus()};return(0,H.jsx)(H.Fragment,{children:o&&(0,H.jsxs)("svg",{ref:g,xmlns:"http://www.w3.org/2000/svg",width:o.size,height:o.size,tabIndex:0,focusable:!0,"aria-disabled":e.disabled?!0:void 0,style:e.svgBgColor?je(ce({},he),{backgroundColor:e.svgBgColor}):he,className:`mz-round-slider ${e.disabled?"mz-round-slider-disabled":""}`,children:[e.SvgDefs&&(0,H.jsx)("defs",{children:e.SvgDefs}),(0,H.jsx)(Ht,{settings:e,pointers:s,svg:o,$svg:g.current,setPointer:f}),(0,H.jsx)(Ut,{settings:e,svg:o,data:t}),(0,H.jsx)(Nt,{settings:e,pointers:s,svg:o,$svg:g.current,data:t,setPointer:f}),(0,H.jsx)(Rt,{settings:e,pointers:s,svg:o,$svg:g.current,data:t,setPointer:f,selectedPointerId:a}),(0,H.jsx)(Ft,{settings:e,pointers:s,svg:o,data:t})]})})};})(); +(()=>{var zt=Object.create;var Oe=Object.defineProperty,Gt=Object.defineProperties,qt=Object.getOwnPropertyDescriptor,Xt=Object.getOwnPropertyDescriptors,Yt=Object.getOwnPropertyNames,Ye=Object.getOwnPropertySymbols,Kt=Object.getPrototypeOf,We=Object.prototype.hasOwnProperty,Wt=Object.prototype.propertyIsEnumerable;var Ke=(e,t,n)=>t in e?Oe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,ce=(e,t)=>{for(var n in t||(t={}))We.call(t,n)&&Ke(e,n,t[n]);if(Ye)for(var n of Ye(t))Wt.call(t,n)&&Ke(e,n,t[n]);return e},je=(e,t)=>Gt(e,Xt(t));var xe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var jt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Yt(t))!We.call(e,r)&&r!==n&&Oe(e,r,{get:()=>t[r],enumerable:!(o=qt(t,r))||o.enumerable});return e};var T=(e,t,n)=>(n=e!=null?zt(Kt(e)):{},jt(t||!e||!e.__esModule?Oe(n,"default",{value:e,enumerable:!0}):n,e));var at=xe(p=>{"use strict";var me=Symbol.for("react.element"),Zt=Symbol.for("react.portal"),Qt=Symbol.for("react.fragment"),Jt=Symbol.for("react.strict_mode"),er=Symbol.for("react.profiler"),tr=Symbol.for("react.provider"),rr=Symbol.for("react.context"),nr=Symbol.for("react.forward_ref"),or=Symbol.for("react.suspense"),sr=Symbol.for("react.memo"),ir=Symbol.for("react.lazy"),Ze=Symbol.iterator;function ar(e){return e===null||typeof e!="object"?null:(e=Ze&&e[Ze]||e["@@iterator"],typeof e=="function"?e:null)}var et={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},tt=Object.assign,rt={};function se(e,t,n){this.props=e,this.context=t,this.refs=rt,this.updater=n||et}se.prototype.isReactComponent={};se.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};se.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function nt(){}nt.prototype=se.prototype;function Fe(e,t,n){this.props=e,this.context=t,this.refs=rt,this.updater=n||et}var Be=Fe.prototype=new nt;Be.constructor=Fe;tt(Be,se.prototype);Be.isPureReactComponent=!0;var Qe=Array.isArray,ot=Object.prototype.hasOwnProperty,$e={current:null},st={key:!0,ref:!0,__self:!0,__source:!0};function it(e,t,n){var o,r={},s=null,i=null;if(t!=null)for(o in t.ref!==void 0&&(i=t.ref),t.key!==void 0&&(s=""+t.key),t)ot.call(t,o)&&!st.hasOwnProperty(o)&&(r[o]=t[o]);var a=arguments.length-2;if(a===1)r.children=n;else if(1{"use strict";lt.exports=at()});var yt=xe(ye=>{"use strict";var xr=K(),Sr=Symbol.for("react.element"),Ir=Symbol.for("react.fragment"),Ar=Object.prototype.hasOwnProperty,Cr=xr.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Er={key:!0,ref:!0,__self:!0,__source:!0};function Pt(e,t,n){var o,r={},s=null,i=null;n!==void 0&&(s=""+n),t.key!==void 0&&(s=""+t.key),t.ref!==void 0&&(i=t.ref);for(o in t)Ar.call(t,o)&&!Er.hasOwnProperty(o)&&(r[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps,t)r[o]===void 0&&(r[o]=t[o]);return{$$typeof:Sr,type:e,key:s,ref:i,props:r,_owner:Cr.current}}ye.Fragment=Ir;ye.jsx=Pt;ye.jsxs=Pt});var M=xe((bn,Mt)=>{"use strict";Mt.exports=yt()});var $=T(K(),1);var gr=Math.pow,U=(e,t=1/0)=>{if(t===1/0)return e;t<0&&(t=0);let n=gr(10,t);return Math.round(e*n)/n},D=(e,t)=>(e%t+t)%t,R=(e,t,n,o,r)=>(r-o)*(e-t)/(n-t)+o;var ut=e=>!isNaN(parseFloat(e))&&isFinite(e);var ct=(e,t=1/0)=>{let n=e*(180/Math.PI);return U(n,t)},F=(e,t=1/0)=>{let n=e*(Math.PI/180);return U(n,t)};var mt=(e,t,n=1/0)=>{let o=[];for(let r=0;rmt(e,t,n);var dr=(e,t,n=1/0)=>{let o=[];for(let r=0;rdr(e,t,n);var dt=(e,t=1/0)=>{let n=0;for(let o=0;o{let o=mt(e,t);return dt(o,n)};var fr=(e,t=1/0)=>{let n=dt(e),o=[];for(let r=0;rfr(e,t);var B=(e,t,n)=>(t=t%Math.PI*2,[e[0]+Math.cos(t)*n,e[1]+Math.sin(t)*n]);var ht=()=>Math.random().toString(36).substring(2)+new Date().getTime().toString(36);var Te=e=>{let t=e.duration!==void 0?e.duration:1/0,n,o,r,s,i=!1,a,l=()=>{n=void 0,r=void 0,s=void 0,i=!1,o!==void 0&&window.cancelAnimationFrame(o)},c=()=>{l(),m()},g=()=>{i=!1},h=()=>{i=!0},b=k=>{n===void 0&&(n=k),r=k-n,i&&s!==k&&typeof e.callback=="function"&&e.callback(A()),r<=t?(s=k,o=window.requestAnimationFrame(b)):l()},u=(k,P)=>{c(),typeof e.resizeCallback=="function"&&e.resizeCallback(k,P)},m=()=>{n=void 0,r=void 0,s=void 0,i=!0,e.restartOnResize&&window.ResizeObserver&&a===void 0?(a=new ResizeObserver(u),a.observe(document.body,{box:"border-box"})):o=window.requestAnimationFrame(b)},x=()=>r,d=()=>i,v=()=>n,_=()=>{if(!(t===1/0||r===void 0))return r*100/t},L=()=>a,A=()=>({start:m,stop:l,pause:g,resume:h,restart:c,isAnimating:d,getElapsedTime:x,getStartTime:v,getPercent:_,getResizeObserver:L});return A()};var pt=(e,t,n,o,r,s)=>{let i=t+n*2,a=Math.max(0,o*2-i),l=e*2+i+a,[c,g]=hr(e,o,t,n);return{cx:c,cy:g,radius:e,size:l,thickness:t,border:n,startAngleDeg:r,endAngleDeg:s}},hr=(e,t,n,o)=>{let r=pr(e,t,n,o),s=U(r/2,2);return[s,s]},pr=(e,t,n,o)=>{let r=n+o*2,s=Math.max(0,t*2-r);return e*2+r+s};var bt="#efefef";var vt="#444444";var ge="#163a86",Ve="#000",He="#a8a8a8";var ze="#000",Ge="#5daed2",Dt="#97b0bb",xt="#000";var St="#efefef",It="#000";var f=(e,t)=>ut(e)?Number(e):t,I=(e,t)=>e==null?t:e,V=(e,t)=>e==null?t:e;var Z=(e,t,n)=>(e>t&&(t+=360),n>=e&&n<=t||n+360>=e&&n+360<=t),de=(e,t)=>{t0?360:o},At=(e,t,n)=>{e>t&&(t+=360);let o=2*Math.PI*n,r=t-e,s=-(e/360)*o,i=r/360*o,a=o-i;return{strokeDasharray:[i,a].join(" "),strokeOffset:s}};var re=(e,t,n,o,r,s,i)=>{let{left:a,top:l}=e.getBoundingClientRect(),c=[t-a,n-l],g=gt(c,[o,r]),h=Math.atan2(g[1]/i,g[0]/s);return h<0&&(h+=2*Math.PI),ct(h)},ae=(e,t,n,o)=>{o0){let s=Math.round(r);r=e.data[s]}else r=U(r,e.round);return r},br=(e,t,n,o)=>{let r;if(o0){let s=e.data.findIndex(i=>i===t);r=s===-1?0:s}else r=typeof t!="number"?e.min:t;return D(R(r,e.min,e.max,n,o),360)},vr=(e,t)=>{if(!e||!e.pointers||e.pointers.length<0||!t){let o=D(f(e.pathStartAngle,0),360),r=I(e.pointerBgColor,ge),s=I(e.pointerBgColorSelected,Ve),i=I(e.pointerBgColorDisabled,He),a=I(e.pointerBgColorHover,s);return[{id:"0",index:0,radius:f(e.pointerRadius,10),angleDeg:o,prevAngleDeg:o,bgColor:r,bgColorSelected:s,bgColorDisabled:i,bgColorHover:a,border:f(e.pointerBorder,0),borderColor:I(e.pointerBorderColor,ze),disabled:!!e.disabled}]}let n=[];for(let o=0;o{let n=vr(e,t);return{pointers:n,maxRadius:Dr(n)}},Dr=e=>{if(e.length<=0)return 0;let t=-1/0;for(let n of e)t=Math.max(t,Math.max(0,n.radius+n.border/2));return t},_e=(e,t,n,o,r)=>{if(!e||e.length<=0)return null;if(e.length===1)return e[0];let s=R(F(t),0,Math.PI*2,0,Math.PI),i=B([n,o],s,r),a,l=null,c=e.filter(g=>!g.disabled);for(let g of c){let h=R(F(g.angleDeg),0,Math.PI*2,0,Math.PI),b=B([n,o],h,r),u=Ee(i,b);(a===void 0||u{let i=R(F(n),0,Math.PI*2,0,Math.PI),a=B([o,r],i,s),l=R(F(e),0,Math.PI*2,0,Math.PI),c=B([o,r],l,s),g=R(F(t),0,Math.PI*2,0,Math.PI),h=B([o,r],g,s),b=Ee(a,c),u=Ee(a,h);return b<=u?e:t},_t=(e,t)=>{if(!e||e.length<=0)return null;let n,o,r=null,s=null;for(let i of e){let a=de(t,i.angleDeg);(n===void 0||ao)&&(s=i,o=a)}return r===null||s===null?null:[r,s]},qe=(e,t,n,o)=>D(e,360)===D(n,360)||D(e,360)===D(o,360)?e:t===0?0:Math.round(e/t)*t;var N=T(K(),1);var he={outline:"none"};var Q=T(M(),1),Tr=(e,t,n,o,r,s,i)=>e.disabled?r:i?s:e.id===t?o:n,_r=e=>{let t=(0,N.useRef)(null),{pointer:n,svg:o,$svg:r,data:s,settings:i,setPointer:a,selectedPointerId:l}=e,{radius:c,angleDeg:g,bgColor:h,bgColorSelected:b,bgColorDisabled:u,bgColorHover:m,border:x,borderColor:d}=e.pointer,{cx:v,cy:_}=o,[L,A]=(0,N.useState)(null),[k,P]=(0,N.useState)(""),[te,G]=(0,N.useState)(ge),[y,C]=(0,N.useState)(!1);(0,N.useEffect)(()=>{G(Tr(n,l,h,b,u,m,y))},[n,l,h,b,u,m,y]),(0,N.useEffect)(()=>{let S=ae(s,n.angleDeg,o.startAngleDeg,o.endAngleDeg);P(S===void 0?"":S.toString())},[s,n.angleDeg,o.startAngleDeg,o.endAngleDeg]),(0,N.useEffect)(()=>{let S=R(F(g),0,Math.PI*2,0,Math.PI),oe=B([v,_],S,o.radius);A(oe)},[g,v,_,o.radius]);let E=(0,N.useCallback)(S=>{if(!r||i.disabled||n.disabled)return;let oe=S.type.indexOf("mouse")!==-1?S.clientX:S.touches[0].clientX,De=S.type.indexOf("mouse")!==-1?S.clientY:S.touches[0].clientY,X=re(r,oe,De,o.cx,o.cy,o.radius,o.radius),ue;Z(o.startAngleDeg,o.endAngleDeg,X)?ue=X:ue=Pe(o.startAngleDeg,o.endAngleDeg,n.angleDeg,o.cx,o.cy,o.radius),a(n,ue)},[r,n,a,o.cx,o.cy,o.endAngleDeg,o.radius,o.startAngleDeg,i.disabled]),ne=()=>{window.removeEventListener("mousemove",E),window.removeEventListener("mouseup",E)},Y=S=>{i.disabled||n.disabled||(E(S),window.addEventListener("mousemove",E),window.addEventListener("mouseup",ne))},q=S=>{if(!(i.disabled||n.disabled||i.keyboardDisabled))switch(S.key){case"ArrowLeft":{S.preventDefault(),a(n,n.angleDeg+s.arrowStepAngleDeg);break}case"ArrowRight":{S.preventDefault(),a(n,n.angleDeg-s.arrowStepAngleDeg);break}case"ArrowUp":{S.preventDefault(),a(n,n.angleDeg-s.arrowStepAngleDeg);break}case"ArrowDown":{S.preventDefault(),a(n,n.angleDeg+s.arrowStepAngleDeg);break}}};(0,N.useEffect)(()=>{let S=t.current,oe=X=>{i.disabled||n.disabled||(X.preventDefault(),X.stopPropagation(),E(X))},De=X=>{if(i.disabled||n.disabled||i.mousewheelDisabled||document.activeElement!==S)return;X.stopPropagation(),X.preventDefault();let ue=X.deltaY<0,Le;ue?Le=n.angleDeg+s.arrowStepAngleDeg:Le=n.angleDeg-s.arrowStepAngleDeg,a(n,Le)};return S==null||S.addEventListener("touchmove",oe,{passive:!1}),document.addEventListener("wheel",De,{passive:!1}),()=>{S==null||S.removeEventListener("touchmove",oe),document.removeEventListener("wheel",De)}},[L,E,s.arrowStepAngleDeg,n,a,i.disabled,i.mousewheelDisabled]);let Re=()=>{C(!0)},we=()=>{C(!1)};return(0,Q.jsx)(Q.Fragment,{children:L&&(0,Q.jsxs)("g",{ref:t,transform:`translate(${L[0]-c/2}, ${L[1]-c/2})`,role:"slider","aria-disabled":n.disabled?!0:void 0,"aria-valuenow":n.angleDeg,"aria-valuetext":k,"aria-label":n.ariaLabel,"data-type":"pointer",className:`mz-round-slider-pointer ${n.disabled?"mz-round-slider-pointer-disabled":""}`,"data-angle":n.angleDeg,"data-id":n.id,"data-index":n.index,onMouseDown:Y,onKeyDown:q,onMouseOver:Re,onMouseOut:we,tabIndex:0,cursor:n.disabled?"default":"pointer",style:he,children:[!i.pointerSVG&&(0,Q.jsx)("circle",{cx:c/2,cy:c/2,r:c,fill:te,strokeWidth:x,stroke:d,style:{transition:"0.3s fill"}}),i.pointerSVG&&(0,Q.jsx)("g",{children:i.pointerSVG})]})})},kt=_r;var pe=T(M(),1),Pr=e=>{let{pointers:t,settings:n,svg:o,$svg:r,data:s,setPointer:i,selectedPointerId:a}=e;return(0,pe.jsx)(pe.Fragment,{children:t.pointers.map(l=>(0,pe.jsx)(kt,{pointer:l,svg:o,settings:n,$svg:r,data:s,setPointer:i,selectedPointerId:a},l.id))})},Rt=Pr;var Lt=e=>{let t=f(e.min,0),n=f(e.max,100),o=f(e.step,1),r=f(e.arrowStep,1),s=f(e.round,0),i=e.data||[];if(i.length>0){let b=i.findIndex(m=>m===t),u=i.findIndex(m=>m===n);t=b===-1?0:b,n=u===-1?i.length:u}else t>n&&(t=n+100);let a=f(e.pathStartAngle,0),l=f(e.pathEndAngle,360),c=D(a,360)===D(l,360),g=o*360/(n-t),h=r*360/(n-t);return{min:t,max:n,round:s,data:i,stepAngleDeg:g,arrowStepAngleDeg:h,isClosedShape:c}};var w=T(K(),1);var Ot=(e,t,n,o,r,s)=>{if(!e.pointers||e.pointers.length<=0)return null;let i={radius:t,cx:n,cy:o,startAngleDeg:r,endAngleDeg:r,strokeDasharray:[0,0],strokeOffset:0};e.pointers.length===1?(i.startAngleDeg=r,i.endAngleDeg=e.pointers[0].angleDeg):(i.startAngleDeg=e.pointers[0].angleDeg,i.endAngleDeg=e.pointers[e.pointers.length-1].angleDeg);let a=de(r,s);i.startAngleDeg>i.endAngleDeg&&(i.endAngleDeg+=360);let l=de(i.startAngleDeg,i.endAngleDeg);l>a&&(l=360-l,[i.startAngleDeg,i.endAngleDeg]=[i.endAngleDeg,i.startAngleDeg]);let g=2*Math.PI*t,h=-(i.startAngleDeg/360)*g,b=l/360*g,u=g-b;return i.strokeDasharray=[b,u],i.strokeOffset=h,i};var Me=(e,t,n,o)=>{let r=e.getPercent();r<0&&(r=0),r>100&&(r=100);let s=t%360,i=n%360;if(ss){let l=(i-s+360)%360;return D(t+r*l/100,360)}else{let l=(s-i+360)%360;return D(t-r*l/100,360)}};var be=T(M(),1),wr=(e,t,n,o,r)=>{if(e)return I(t,Dt);let s=I(n,Ge);return o?I(r,s):s},Lr=e=>{let{settings:t,pointers:n,$svg:o,svg:r,data:s,setPointer:i}=e,[a,l]=(0,w.useState)(null),[c,g]=(0,w.useState)(null),[h,b]=(0,w.useState)(Ge),[u,m]=(0,w.useState)(!1),x=(0,w.useRef)(),d=(0,w.useRef)(null),v=(0,w.useRef)(0),_=(0,w.useRef)(0);(0,w.useEffect)(()=>{b(wr(t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,u,t.connectionBgColorHover))},[t.disabled,t.connectionBgColorDisabled,t.connectionBgColor,t.connectionBgColorHover,u]),(0,w.useEffect)(()=>{l(Ot(n,r.radius,r.cx,r.cy,r.startAngleDeg,r.endAngleDeg))},[n,r.radius,r.cx,r.cy,r.startAngleDeg,r.endAngleDeg]);let L=y=>{if(!o||t.disabled||c&&c.isAnimating())return;let C=re(o,y.clientX,y.clientY,r.cx,r.cy,r.radius,r.radius),E=_e(n.pointers,C,r.cx,r.cy,r.radius);E&&(t.animateOnClick?(d.current=E,v.current=E.angleDeg,_.current=C,c==null||c.start()):i(E,C))},A=(0,w.useCallback)(y=>{if(!o||t.disabled||!t.rangeDragging)return;let C=_t(n.pointers,r.startAngleDeg);if(!C)return;let[E,ne]=C,Y=re(o,y.clientX,y.clientY,r.cx,r.cy,r.radius,r.radius);if(x.current===void 0){x.current=Y;return}let q=Y-x.current;q===0||Math.abs(q){window.removeEventListener("mousemove",A),window.removeEventListener("mouseup",A),x.current=void 0},P=y=>{!t.rangeDragging||t.disabled||n.pointers.length<=1||(A(y),window.addEventListener("mousemove",A),window.addEventListener("mouseup",k))};(0,w.useEffect)(()=>{if(c&&c.stop(),!t.animateOnClick){g(null);return}let y=Te({callback:C=>{if(!d.current)return;let E=Me(C,v.current,_.current,r.startAngleDeg);i(d.current,E)},duration:f(t.animationDuration,200)});g(y)},[t.animateOnClick,t.animationDuration]);let te=()=>{m(!0)},G=()=>{m(!1)};return(0,be.jsx)(be.Fragment,{children:!V(t.hideConnection,!1)&&a&&(0,be.jsx)("circle",{"data-type":"connection",className:"mz-round-slider-connection",cx:a.cx,cy:a.cy,r:a.radius,strokeDasharray:a.strokeDasharray.join(" "),strokeDashoffset:a.strokeOffset,stroke:h,strokeWidth:r.thickness+1,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:t.disabled?"default":"pointer",onClick:L,onMouseDown:P,onMouseOver:te,onMouseOut:G,style:{transition:"0.2s stroke"}})})},Nt=Lr;var ke=T(K(),1),ve=T(M(),1),Nr=e=>{let{settings:t,pointers:n,svg:o,data:r}=e,{cx:s,cy:i}=o,[a,l]=(0,ke.useState)("");(0,ke.useEffect)(()=>{let g=n.pointers.map(u=>ae(r,u.angleDeg,o.startAngleDeg,o.endAngleDeg));g.sort((u,m)=>u.toString().localeCompare(m.toString(),"en",{numeric:!0}));let h=g.map(u=>`${t.textPrefix||""}${u}${t.textSuffix||""}`),b=I(t.textBetween," ");l(h.join(b))},[r,n.pointers,o.startAngleDeg,o.endAngleDeg,t.textPrefix,t.textSuffix,t.textBetween]);let c=V(t.hideText,!1);return(0,ve.jsx)(ve.Fragment,{children:!c&&(0,ve.jsx)("text",{"data-type":"text",className:"mz-round-slider-text",x:s+f(t.textOffsetX,0),y:i+f(t.textOffsetY,0),fill:I(t.textColor,xt),fontSize:f(t.textFontSize,16),fontFamily:t.textFontFamily,style:{userSelect:"none",whiteSpace:"pre"},textAnchor:"middle",children:a})})},Ft=Nr;var J=T(K(),1);var Bt=(e,t)=>{let n=f(e.ticksCount,0);n||(t.data&&t.data.length>0?n=t.data.length:n=t.max);let o=f(e.ticksHeight,10);return{ticksCount:n,enableTicks:V(e.enableTicks,!1),ticksWidth:f(e.ticksWidth,3),ticksHeight:o,longerTicksHeight:f(e.longerTicksHeight,o*2),ticksDistanceToPanel:f(e.ticksDistanceToPanel,0),tickValuesDistance:f(e.tickValuesDistance,15),ticksColor:I(e.ticksColor,St),tickValuesColor:I(e.tickValuesColor,It),tickValuesFontSize:f(e.tickValuesFontSize,12),ticksGroupSize:f(e.ticksGroupSize,10),longerTickValuesOnly:V(e.longerTickValuesOnly,!0),showTickValues:V(e.showTickValues,!0)}},$t=(e,t,n,o,r,s)=>{let i=[],a=Math.abs(o-n),l=t===0?0:a/t,c=t;s.isClosedShape||c++;for(let g=0;g0){let E=Math.round(C);C=s.data[E]}else C=U(C,s.round);P=(C!=null?C:"").toString()}let te=0,G=0,y=P!==void 0;if(y){let C=f(d+e.tickValuesDistance,d*1.5),E=Ce(v,C);te=u+E[0],G=m+E[1]}i.push({x:u,y:m,x1:A,y1:k,textX:te,textY:G,isLonger:x,tickValue:P,showText:y})}return i};var W=T(M(),1),zr=e=>{let{settings:t,svg:n,data:o}=e,[r,s]=(0,J.useState)(null),[i,a]=(0,J.useState)([]);return(0,J.useEffect)(()=>{s(Bt(t,o))},[t,o]),(0,J.useEffect)(()=>{if(!r)return;let l=n.endAngleDeg;l{let{x:g,y:h,x1:b,y1:u,textX:m,textY:x,showText:d}=l;return(0,W.jsxs)(J.Fragment,{children:[(0,W.jsx)("line",{x1:g,y1:h,x2:b,y2:u,strokeWidth:r.ticksWidth,stroke:r.ticksColor,"data-type":"tick",className:"mz-round-slider-tick"}),d&&(0,W.jsxs)("text",{"data-type":"tick-text",className:"mz-round-slider-tick-text",x:m,y:x,textAnchor:"middle",dominantBaseline:"middle",fill:r.tickValuesColor,fontSize:r.tickValuesFontSize,fontFamily:t.tickValuesFontFamily,style:{userSelect:"none",whiteSpace:"pre"},children:[t.tickValuesPrefix,l.tickValue,t.tickValuesSuffix]})]},c)})})})},Ut=zr;var z=T(K(),1);var ee=T(K(),1);var j=T(M(),1),Gr=e=>{let{svg:t,maskId:n,settings:o,circle:r}=e,[s,i]=(0,ee.useState)([0,0]),[a,l]=(0,ee.useState)([0,0]),[c,g]=(0,ee.useState)(0),[h,b]=(0,ee.useState)(!1);return(0,ee.useEffect)(()=>{if(D(t.startAngleDeg,360)===D(t.endAngleDeg,360)){b(!0);return}b(V(o.pathInnerBgFull,!1))},[o.pathInnerBgFull,t.startAngleDeg,t.endAngleDeg]),(0,ee.useEffect)(()=>{let u=R(t.startAngleDeg,0,Math.PI*2,0,Math.PI);i(B([t.cx,t.cy],F(u),t.radius));let m=R(t.endAngleDeg,0,Math.PI*2,0,Math.PI);l(B([t.cx,t.cy],F(m),t.radius));let x=t.endAngleDeg-t.startAngleDeg<=180?1:0;g(x)},[t.cx,t.cy,t.endAngleDeg,t.radius,t.startAngleDeg]),(0,j.jsxs)(j.Fragment,{children:[!h&&(0,j.jsxs)("mask",{id:n,children:[(0,j.jsx)("path",{fill:"black",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 1 ${c} 0 ${a[0]} ${a[1]}`}),(0,j.jsx)("path",{fill:"white",d:`M ${s[0]} ${s[1]} A ${t.radius} ${t.radius} 0 ${c===1?0:1} 1 ${a[0]} ${a[1]}`})]}),(0,j.jsx)("circle",{strokeDasharray:r.strokeDasharray,strokeDashoffset:r.strokeOffset,cx:t.cx,cy:t.cy,r:t.radius,stroke:"transparent",strokeWidth:t.thickness,fill:o.pathInnerBgColor,shapeRendering:"geometricPrecision",strokeLinecap:"round","data-type":"path-inner",className:"mz-round-slider-path-inner",mask:h?"":`url(#${n})`})]})},Vt=Gr;var le=T(M(),1),qr=e=>{let{settings:t,pointers:n,$svg:o,svg:r,setPointer:s}=e,[i,a]=(0,z.useState)(null),[l]=(0,z.useState)(ht()),[c,g]=(0,z.useState)({strokeDasharray:"0 1000000",strokeOffset:0}),h=(0,z.useRef)(null),b=(0,z.useRef)(0),u=(0,z.useRef)(0);(0,z.useEffect)(()=>{g(At(r.startAngleDeg,r.endAngleDeg,r.radius))},[r.startAngleDeg,r.endAngleDeg,r.radius]);let m=x=>{if(!o||t.disabled||i&&i.isAnimating())return;let d=re(o,x.clientX,x.clientY,r.cx,r.cy,r.radius,r.radius),v=_e(n.pointers,d,r.cx,r.cy,r.radius);v&&(t.animateOnClick?(h.current=v,b.current=v.angleDeg,u.current=d,i==null||i.start()):s(v,d))};return(0,z.useEffect)(()=>{if(i&&i.stop(),!t.animateOnClick){a(null);return}let x=Te({callback:d=>{if(!h.current)return;let v=Me(d,b.current,u.current,r.startAngleDeg);s(h.current,v)},duration:f(t.animationDuration,200)});a(x)},[t.animateOnClick,t.animationDuration]),(0,le.jsxs)("g",{onClick:m,children:[t.pathInnerBgColor&&(0,le.jsx)(Vt,{maskId:l,settings:t,svg:r,circle:c}),r.border>0&&(0,le.jsx)("circle",{strokeDasharray:c.strokeDasharray,strokeDashoffset:c.strokeOffset,cx:r.cx,cy:r.cy,r:r.radius,stroke:I(t.pathBorderColor,vt),strokeWidth:r.thickness+r.border*2,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path-border",className:"mz-round-slider-path-border"}),(0,le.jsx)("circle",{strokeDasharray:c.strokeDasharray,strokeDashoffset:c.strokeOffset,cx:r.cx,cy:r.cy,r:r.radius,stroke:I(t.pathBgColor,bt),strokeWidth:r.thickness,fill:"none",shapeRendering:"geometricPrecision",strokeLinecap:"round",cursor:"pointer","data-type":"path",className:"mz-round-slider-path"})]})},Ht=qr;var H=T(M(),1),Xo=e=>{let[t,n]=(0,$.useState)(null),[o,r]=(0,$.useState)(null),[s,i]=(0,$.useState)(null),[a,l]=(0,$.useState)(""),c=(0,$.useRef)(null),g=(0,$.useRef)(null);(0,$.useEffect)(()=>{let u=Lt(e);JSON.stringify(t)!==JSON.stringify(u)&&n(u)},[t,e]),(0,$.useEffect)(()=>{i(Tt(e,t))},[e.pointerRadius,e.pathStartAngle,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pointers,e.pointerRadius,e.pointerBgColor,e.pointerBgColorSelected,e.pointerBgColorDisabled,e.pointerBorder,e.pointerBorderColor,e.disabled,e.pathStartAngle,e.pathEndAngle,t]),(0,$.useEffect)(()=>{if(!s)return;let u=f(e.pathStartAngle,0),m=f(e.pathEndAngle,360);m<=u&&(m+=360),r(pt(f(e.pathRadius,150),f(e.pathThickness,5),f(e.pathBorder,0),s.maxRadius,u,m))},[e.pathRadius,e.pathThickness,e.pathBorder,e.pathStartAngle,e.pathEndAngle,s]),(0,$.useEffect)(()=>{let u=m=>{m.target.closest('[data-type="pointer"]')||l("")};return document.addEventListener("mousedown",u),()=>{document.removeEventListener("mousedown",u)}},[]);let h=(u,m)=>{if(e.disabled||!s.pointers||!u||u.disabled)return;if(m=qe(m,t.stepAngleDeg,o.startAngleDeg,o.endAngleDeg),t.isClosedShape&&D(m,360)===D(o.endAngleDeg,360)&&(m=o.startAngleDeg),u.angleDeg===m){b(u,m,!1);return}if(!e.pointersOverlap){let d,v;if(t.isClosedShape){let _=D(u.index-1,s.pointers.length),L=D(u.index+1,s.pointers.length),A=s.pointers[_],k=s.pointers[L];if(d=A.angleDeg,v=k.angleDeg,s.pointers.length===2&&d===v){let P=d;if(c.current===null)c.current=m;else{let G=P-150,y=P-.001;G<0&&(G+=360),y<0&&(y+=360);let C=Z(P+.001,P+150,m),E=Z(G,y,c.current),ne=C&&E,Y=P-150,q=P-.001;Y<0&&(Y+=360),q<0&&(q+=360);let Re=Z(Y,q,m),we=Z(P+.001,P+150,c.current);if(ne||Re&&we){b(u,P,!0);return}m!==P&&(c.current=m)}}}else d=u.index===0?o.startAngleDeg:s.pointers[u.index-1].angleDeg,v=u.index===s.pointers.length-1?o.endAngleDeg:s.pointers[u.index+1].angleDeg;v<=d?v+=360:D(d,360)<=D(v,360)&&(d=D(d,360),v=D(v,360)),Z(d,v,m)||(m=Pe(d,v,m,o.cx,o.cy,o.radius))}b(u,m,u.angleDeg!==m)},b=(u,m,x)=>{var v;if(x){let _=ce({},s);if(_.pointers=[...s.pointers],_.pointers[u.index].prevAngleDeg=_.pointers[u.index].angleDeg,_.pointers[u.index].angleDeg=m,s.pointers=_.pointers,i(_),typeof e.onChange=="function"){let L=_.pointers.map(A=>{let k=ae(t,A.angleDeg,o.startAngleDeg,o.endAngleDeg);return{radius:A.radius,value:k,bgColor:A.bgColor,bgColorSelected:A.bgColorSelected,bgColorDisabled:A.bgColorDisabled,border:A.border,borderColor:A.borderColor,disabled:A.disabled,ariaLabel:A.ariaLabel}});e.onChange(L)}}l(u.id);let d=(v=g.current)==null?void 0:v.querySelector(`[data-id="${u.id}"]`);d&&d.focus()};return(0,H.jsx)(H.Fragment,{children:o&&(0,H.jsxs)("svg",{ref:g,xmlns:"http://www.w3.org/2000/svg",width:o.size,height:o.size,tabIndex:0,focusable:!0,"aria-disabled":e.disabled?!0:void 0,style:e.svgBgColor?je(ce({},he),{backgroundColor:e.svgBgColor}):he,className:`mz-round-slider ${e.disabled?"mz-round-slider-disabled":""}`,children:[e.SvgDefs&&(0,H.jsx)("defs",{children:e.SvgDefs}),(0,H.jsx)(Ht,{settings:e,pointers:s,svg:o,$svg:g.current,setPointer:h}),(0,H.jsx)(Ut,{settings:e,svg:o,data:t}),(0,H.jsx)(Nt,{settings:e,pointers:s,svg:o,$svg:g.current,data:t,setPointer:h}),(0,H.jsx)(Rt,{settings:e,pointers:s,svg:o,$svg:g.current,data:t,setPointer:h,selectedPointerId:a}),(0,H.jsx)(Ft,{settings:e,pointers:s,svg:o,data:t})]})})};})(); /*! Bundled license information: react/cjs/react.production.min.js: diff --git a/dist/mz-react-round-slider.min.js.map b/dist/mz-react-round-slider.min.js.map index d48df6e..1fa7a02 100644 --- a/dist/mz-react-round-slider.min.js.map +++ b/dist/mz-react-round-slider.min.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../node_modules/react/cjs/react.production.min.js", "../node_modules/react/index.js", "../node_modules/react/cjs/react-jsx-runtime.production.min.js", "../node_modules/react/jsx-runtime.js", "../src/core/index.tsx", "../node_modules/mz-math/src/main/format.ts", "../node_modules/mz-math/src/main/other.ts", "../node_modules/mz-math/src/main/angle.ts", "../node_modules/mz-math/src/main/linear-algebra/vector.ts", "../node_modules/mz-math/src/main/linear-algebra/matrix.ts", "../node_modules/mz-math/src/main/linear-algebra/matrix-transformations.ts", "../node_modules/mz-math/src/main/random.ts", "../node_modules/mz-math/src/main/convert.ts", "../node_modules/mz-math/src/main/derivative.ts", "../node_modules/mz-math/src/main/equations/linear-equations.ts", "../node_modules/mz-math/src/main/equations/quadratic-equations.ts", "../node_modules/mz-math/src/main/bezier-curves/bezier-curve.ts", "../node_modules/mz-math/src/main/path-movement.ts", "../node_modules/mz-math/src/main/color.ts", "../node_modules/mz-math/src/main/id.ts", "../node_modules/mz-math/src/main/collision-detection.ts", "../node_modules/mz-math/src/main/animation.ts", "../node_modules/mz-math/src/main/circle-ellipse.ts", "../src/core/domain/svg-provider.ts", "../src/core/domain/defaults-provider.ts", "../src/core/domain/common-provider.ts", "../src/core/domain/circle-provider.ts", "../src/core/domain/pointers-provider.ts", "../src/core/ui/Pointer.tsx", "../src/core/domain/style-provider.ts", "../src/core/ui/Pointers.tsx", "../src/core/domain/data-provider.ts", "../src/core/ui/Connection.tsx", "../src/core/domain/connection-provider.ts", "../src/core/domain/animation-provider.ts", "../src/core/ui/Text.tsx", "../src/core/ui/Ticks.tsx", "../src/core/domain/ticks-provider.ts", "../src/core/ui/Circle.tsx", "../src/core/ui/InnerCircle.tsx"], - "sourcesContent": ["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1 {\n\n const [ data, setData ] = useState(null);\n const [ svg, setSvg ] = useState(null);\n const [ pointers, setPointers ] = useState(null);\n const [ selectedPointerId, setSelectedPointerId ] = useState('');\n\n const prevAngleDegRef = useRef(null);\n const svgRef = useRef(null);\n\n useEffect(() => {\n const _data = getData(props);\n const hasChanged = JSON.stringify(data) !== JSON.stringify(_data);\n if(!hasChanged) return;\n\n setData(_data);\n }, [\n data,\n props\n ]);\n\n useEffect(() => {\n setPointers(getPointers(props, data));\n },\n // eslint-disable-next-line\n [\n props.pointerRadius,\n props.pathStartAngle,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pointers,\n props.pointerRadius,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pathStartAngle,\n props.pathEndAngle,\n data,\n ]);\n\n useEffect(() => {\n if(!pointers) return;\n\n const pathStartAngle = getNumber(props.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n let pathEndAngle = getNumber(props.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n\n if(pathEndAngle <= pathStartAngle) {\n pathEndAngle += 360;\n }\n\n setSvg(getSvg(\n getNumber(props.pathRadius, DEFAULT_PATH_RADIUS),\n getNumber(props.pathThickness, DEFAULT_PATH_THICKNESS),\n getNumber(props.pathBorder, DEFAULT_PATH_BORDER),\n pointers.maxRadius,\n pathStartAngle,\n pathEndAngle,\n ));\n }, [\n props.pathRadius,\n props.pathThickness,\n props.pathBorder,\n props.pathStartAngle,\n props.pathEndAngle,\n pointers,\n ]);\n\n useEffect(() => {\n const clearSelectedPointer = (evt: MouseEvent) => {\n const $target = evt.target as HTMLElement;\n const $pointer = $target.closest('[data-type=\"pointer\"]');\n if($pointer) return;\n\n setSelectedPointerId('');\n };\n\n document.addEventListener('mousedown', clearSelectedPointer);\n\n return () => {\n document.removeEventListener('mousedown', clearSelectedPointer);\n };\n }, []);\n\n const setPointersCallback = (pointer: IPointer, newAngleDeg: number) => {\n if(props.disabled || !pointers.pointers || !pointer || pointer.disabled) return;\n\n newAngleDeg = roundToStep(newAngleDeg, data.stepAngleDeg, svg.startAngleDeg, svg.endAngleDeg);\n if(data.isClosedShape && mod(newAngleDeg, 360) === mod(svg.endAngleDeg, 360)){\n newAngleDeg = svg.startAngleDeg;\n }\n\n if(pointer.angleDeg === newAngleDeg){\n updatePointer(pointer, newAngleDeg, false);\n return;\n }\n\n const handleOverlap = !props.pointersOverlap;\n if(handleOverlap) {\n\n let prevAngle, nextAngle;\n\n if(data.isClosedShape) {\n const prevIndex = mod(pointer.index - 1, pointers.pointers.length);\n const nextIndex = mod(pointer.index + 1, pointers.pointers.length);\n\n const prevPointer = pointers.pointers[prevIndex];\n const nextPointer = pointers.pointers[nextIndex];\n\n prevAngle = prevPointer.angleDeg;\n nextAngle = nextPointer.angleDeg;\n\n if(pointers.pointers.length === 2 && (prevAngle === nextAngle)) {\n\n const splitPointDeg = prevAngle; // === nextAngle\n\n if(prevAngleDegRef.current === null) {\n prevAngleDegRef.current = newAngleDeg;\n }\n else{\n // Clockwise: new angle in (splitPointDeg, splitPointDeg + 90]\n // Clockwise: prev angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: new angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: prev angle in (splitPointDeg, splitPointDeg + 90]\n\n const SAFE_ANGLE = 150;\n\n let t1 = splitPointDeg - SAFE_ANGLE;\n let t2 = splitPointDeg - 0.001;\n\n if(t1 < 0) t1 += 360;\n if(t2 < 0) t2 += 360;\n\n const clockwiseNew = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, newAngleDeg);\n const clockwisePrev = isAngleInArc(t1, t2, prevAngleDegRef.current);\n const clockwise = clockwiseNew && clockwisePrev;\n\n let t3 = splitPointDeg - SAFE_ANGLE;\n let t4 = splitPointDeg - 0.001;\n\n if(t3 < 0) t3 += 360;\n if(t4 < 0) t4 += 360;\n\n const counterClockwiseNew = isAngleInArc(t3, t4, newAngleDeg);\n const counterClockwisePrev = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, prevAngleDegRef.current);\n const counterClockwise = counterClockwiseNew && counterClockwisePrev;\n\n if(clockwise || counterClockwise) {\n updatePointer(pointer, splitPointDeg, true);\n return;\n }\n\n if(newAngleDeg !== splitPointDeg) {\n prevAngleDegRef.current = newAngleDeg;\n }\n }\n }\n }\n else{\n prevAngle = pointer.index === 0 ? svg.startAngleDeg : pointers.pointers[pointer.index - 1].angleDeg;\n nextAngle = pointer.index === pointers.pointers.length - 1 ? svg.endAngleDeg : pointers.pointers[pointer.index + 1].angleDeg;\n }\n\n if(nextAngle <= prevAngle) {\n nextAngle += 360;\n }\n\n if(!isAngleInArc(prevAngle, nextAngle, newAngleDeg)){\n newAngleDeg = getClosestEdge(\n prevAngle,\n nextAngle,\n newAngleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n }\n\n updatePointer(pointer, newAngleDeg, pointer.angleDeg !== newAngleDeg);\n };\n\n const updatePointer = (pointer: IPointer, newAngleDeg: number, angleChanged: boolean) => {\n\n if(angleChanged) {\n const _pointers = { ...pointers };\n _pointers.pointers = [...pointers.pointers];\n _pointers.pointers[pointer.index].prevAngleDeg = _pointers.pointers[pointer.index].angleDeg;\n _pointers.pointers[pointer.index].angleDeg = newAngleDeg;\n pointers.pointers = _pointers.pointers;\n\n setPointers(_pointers);\n\n if(typeof props.onChange === 'function') {\n\n const updatedPointers: ISettingsPointer[] = _pointers.pointers.map(pointer => {\n\n const val = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n\n return {\n radius: pointer.radius,\n value: val,\n bgColor: pointer.bgColor,\n bgColorSelected: pointer.bgColorSelected,\n bgColorDisabled: pointer.bgColorDisabled,\n border: pointer.border,\n borderColor: pointer.borderColor,\n disabled: pointer.disabled,\n ariaLabel: pointer.ariaLabel,\n };\n });\n\n props.onChange(updatedPointers);\n }\n }\n\n setSelectedPointerId(pointer.id);\n\n const $pointer = svgRef.current?.querySelector(`[data-id=\"${ pointer.id }\"]`) as HTMLElement;\n if($pointer) {\n $pointer.focus();\n }\n };\n\n return (\n <>\n {\n svg &&\n \n\n {\n (props.SvgDefs) &&\n \n { props.SvgDefs }\n \n }\n\n \n\n \n\n \n\n \n\n \n \n }\n \n )\n};", "export const setDecimalPlaces = (num: number, decimalPlaces: number | undefined = Infinity) => {\n if(decimalPlaces === Infinity) return num;\n\n if(decimalPlaces < 0){\n decimalPlaces = 0;\n }\n\n const coefficient = 10 ** decimalPlaces;\n return Math.round(num * coefficient) / coefficient;\n};", "import { Vector2 } from '../types';\nimport { setDecimalPlaces } from './format';\n\nexport const mod = (n: number, m: number) => {\n return ((n % m) + m) % m;\n};\n\n/**\n * Convert range [a, b] to [c, d].\n * f(x) = (d - c) * (x - a) / (b - a) + c\n */\nexport const convertRange = (x: number, a: number, b: number, c: number, d: number) => {\n return (d - c) * (x - a) / (b - a) + c;\n};\n\n/**\n * Check if 2 ranges [a,b] and [c,d] overlap.\n */\nexport const doRangesOverlap = (a: number, b: number, c: number, d: number) => {\n return Math.max(a, c) <= Math.min(b, d) ;\n};\n\n// eslint-disable-next-line\nexport const isNumber = (value: any) => {\n return !isNaN(parseFloat(value)) && isFinite(value);\n};\n\n/**\n * Convert polar coordinates to cartesian coordinates.\n */\nexport const polarToCartesian = (center: Vector2, radii: Vector2, angleInRad: number, decimalPlaces = Infinity) : Vector2 => {\n const [cx, cy] = center;\n const [rx, ry] = radii;\n\n return [\n setDecimalPlaces(cx + (rx * Math.cos(angleInRad)), decimalPlaces),\n setDecimalPlaces(cy + (ry * Math.sin(angleInRad)), decimalPlaces),\n ];\n};", "import { Vector, Vector2, Vector3 } from '../types';\nimport { setDecimalPlaces } from './format';\nimport { v2Length, vNormalize, vDotProduct, vSub } from './linear-algebra/vector';\nimport { mod } from './other';\n\nexport const getV2Angle = (v2: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1], v2[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleInEllipse = (v2: Vector2, radii: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1]/radii[1], v2[0]/radii[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const setV2Angle = (v2: Vector2, newAngleRad: number, decimalPlaces = Infinity): Vector2 => {\n const length = v2Length(v2);\n return [\n setDecimalPlaces(Math.cos(newAngleRad) * length, decimalPlaces),\n setDecimalPlaces(Math.sin(newAngleRad) * length, decimalPlaces),\n ];\n};\n\nexport const radiansToDegrees = (radians: number, decimalPlaces = Infinity) => {\n const res = radians * (180 / Math.PI);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\nexport const degreesToRadians = (degrees: number, decimalPlaces = Infinity) => {\n const res = degrees * (Math.PI / 180);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\n/**\n * Returns the range [0, Math.PI]\n * A = Math.acos( dot(v1, v2)/(v1.length()*v2.length()) );\n */\nexport const getVNAngleBetween = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n const unitVector1 = vNormalize(vector1);\n const unitVector2 = vNormalize(vector2);\n const dotProduct = vDotProduct(unitVector1, unitVector2);\n const angle = Math.acos(dotProduct);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleBetween = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) : number => {\n // return getVNAngleBetween(vector1, vector2, decimalPlaces);\n const diff = vSub(vector1, vector2);\n const angle = Math.atan2(diff[1], diff[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV3AngleBetween = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return getVNAngleBetween(vector1, vector2, decimalPlaces);\n};\n\nexport const isAngleBetween = (angleDegrees: number, startAngleDegrees: number, endAngleDegrees: number) : boolean => {\n const distance = getAnglesSub(startAngleDegrees, endAngleDegrees);\n const distance1 = getAnglesSub(startAngleDegrees, angleDegrees);\n const distance2 = getAnglesSub(endAngleDegrees, angleDegrees);\n const totalDistance = distance1 + distance2;\n\n // Use a small threshold for floating point errors\n return Math.abs(totalDistance - distance) <= 0.001;\n}\n\nexport const isClockwise = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n return angle2Deg >= angle1Deg;\n};\n\n/**\n * Shortest distance (angular) between two angles.\n */\nexport const getAnglesSub = (angleDegrees1: number, angleDegrees2: number, decimalPlaces = Infinity) : number => {\n const angleDistance = Math.abs(mod(angleDegrees1, 360) - mod(angleDegrees2, 360));\n return setDecimalPlaces(angleDistance <= 180 ? angleDistance : 360 - angleDistance, decimalPlaces);\n};\n\nexport const getAnglesDistance = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0, decimalPlaces = Infinity) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n if(isClockwise(angle1Deg, angle2Deg, startAngleDeg)) {\n return setDecimalPlaces((angle2Deg - angle1Deg + 360) % 360, decimalPlaces);\n }\n else{\n return setDecimalPlaces((angle1Deg - angle2Deg + 360) % 360, decimalPlaces);\n }\n};\n\nexport const percentToAngle = (percent: number, startAngleDeg: number, endAngleDeg: number, circleStartAngle = 0) => {\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n const distance = getAnglesDistance(startAngleDeg, endAngleDeg, circleStartAngle);\n\n const clockwise = isClockwise(startAngleDeg, endAngleDeg, circleStartAngle);\n if(clockwise) {\n return mod(circleStartAngle + (percent * distance / 100), 360);\n }\n else {\n return mod(circleStartAngle - (percent * distance / 100), 360);\n }\n};", "import { Vector, Vector2, Vector3, Vector4 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { getV2Angle, setV2Angle } from '../angle';\n\n// ------------ SUM ------------------------\n\nexport const vSum = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSum(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sum = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSum(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ SUB ------------------------\n\nexport const vSub = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSub(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sub = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSub(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ MUL SCALAR ------------------------\n\nexport const vMulScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n const vector: Vector = [];\n\n for(let i=0; i {\n return vMulScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3MulScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vMulScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ DIVIDE ------------------------\n\nexport const vDivideScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vDivideScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3DivideScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vDivideScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ LENGTH ------------------------\n\nexport const vLength = (vector: Vector, decimalPlaces = Infinity) => {\n let sum = 0;\n\n for(let i=0; i {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v3Length = (vector: Vector3, decimalPlaces = Infinity) => {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v2SetLength = (v2: Vector2, newLength: number, decimalPlaces = Infinity): Vector2 => {\n const angle = getV2Angle(v2);\n return [\n setDecimalPlaces(Math.cos(angle) * newLength, decimalPlaces),\n setDecimalPlaces(Math.sin(angle) * newLength, decimalPlaces),\n ];\n};\n\n// ----------- DISTANCE ------------------------\n\nexport const vDistance = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v2Distance = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v3Distance = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\n// ------------ NORMALIZE ------------------------\n\n/**\n * Normalization creates a unit vector, which is a vector of length 1.\n */\nexport const vNormalize = (v: Vector, decimalPlaces = Infinity) : Vector => {\n const length = vLength(v);\n const unitVector: Vector = [];\n\n for(let i=0; i {\n return vNormalize(v2, decimalPlaces) as Vector2;\n};\n\nexport const v3Normalize = (v3: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vNormalize(v3, decimalPlaces) as Vector3;\n};\n\n// ------------ DOT PRODUCT ------------------------\n\nexport const vDotProduct = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n let sum = 0;\n\n for(let i=0; i {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\nexport const v3DotProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\n// ------------ CROSS PRODUCT ------------------------\n\n/**\n * Cross product is possible on 3D vectors only.\n * The cross product a \u00D7 b is defined as a vector c that is perpendicular (orthogonal) to both a and b.\n */\nexport const v3CrossProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity): Vector3 => {\n return [\n setDecimalPlaces(vector1[1] * vector2[2] - vector1[2] * vector2[1], decimalPlaces),\n setDecimalPlaces(vector1[2] * vector2[0] - vector1[0] * vector2[2], decimalPlaces),\n setDecimalPlaces(vector1[0] * vector2[1] - vector1[1] * vector2[0], decimalPlaces),\n ];\n};\n\n// --------------- INIT VECTOR HELPER -----------------\n\nexport const v2 = (defaultValue = 0): Vector2 => {\n return [defaultValue, defaultValue];\n};\n\nexport const v3 = (defaultValue = 0): Vector3 => {\n return [defaultValue, defaultValue, defaultValue];\n};\n\nexport const v4 = (defaultValue = 0): Vector4 => {\n return [defaultValue, defaultValue, defaultValue, defaultValue];\n};\n\nexport const vN = (N: number, defaultValue = 0): Vector => {\n\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n const vector: Vector = [];\n for(let i=0; i {\n let vector: Vector2 = [0, 0];\n vector = v2SetLength(vector, distance);\n return setV2Angle(vector, angleRad);\n};\n\n// --------------- EQUALITY -------------------------\n\nexport const vEqual = (vector1: Vector, vector2: Vector): boolean => {\n if(vector1.length !== vector2.length) return false;\n\n for(let i=0; i {\n const sub = v2Sub(vector2, vector1);\n return [\n -setDecimalPlaces(sub[1], decimalPlaces),\n setDecimalPlaces(sub[0], decimalPlaces)\n ];\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector, Vector2, Vector3 } from '../../types';\nimport { vMulScalar, vSum, vSub, vDotProduct, vN, vEqual, vDivideScalar } from './vector';\n\n// --------------- SUM ----------------------\n\nexport const mSum = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sum = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- SUB ----------------------\n\nexport const mSub = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sub = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- MUL SCALAR ----------------------\n\nexport const mMulScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vMulScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2MulScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mMulScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3MulScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mMulScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n// --------------- DIVIDE SCALAR ----------------------\n\nexport const mDivideScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vDivideScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2DivideScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mDivideScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3DivideScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mDivideScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n\n// --------------- TRANSPOSE ----------------------\n\nexport const mTranspose = (m: Matrix): Matrix => {\n\n const vectorsCount = m.length;\n if(vectorsCount <= 0) return m;\n\n const vectorLength = m[0].length;\n if(vectorLength <= 0) return m;\n\n const matrix: Matrix = [];\n for(let i=0; i {\n return mTranspose(m2);\n};\n\nexport const m3Transpose = (m3: Matrix3): Matrix => {\n return mTranspose(m3);\n};\n\n// ----------------- RESET ----------------------\n\nexport const mReset = (m: Matrix, defaultValue = 0): Matrix => {\n\n if(m.length <= 0) return [];\n\n const res: Matrix = [];\n\n for(let i=0; i {\n return mReset(m2, defaultValue) as Matrix2;\n};\n\nexport const m3Reset = (m3: Matrix3, defaultValue = 0): Matrix3 => {\n return mReset(m3, defaultValue) as Matrix3;\n};\n\n// --------------- MATRIX INIT HELPERS -----------------\n\nexport const m2x2 = (defaultValue = 0): Matrix2 => {\n return [\n [defaultValue, defaultValue],\n [defaultValue, defaultValue],\n ];\n};\n\nexport const m3x3 = (defaultValue = 0): Matrix3 => {\n return [\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const m4x4 = (defaultValue = 0): Matrix4 => {\n return [\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const mNxM = (N: number, M: number, defaultValue = 0): Matrix => {\n if(N <= 0 || M <= 0){\n throw new Error('M and N must be positive numbers.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return [\n [1, 0],\n [0, 1],\n ];\n};\n\nexport const identity3 = (): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\nexport const identity4 = (): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Identity Matrix (I).\n * M x I = I x M = M for any matrix M.\n * Identity Matrix is a special case of scale matrix.\n */\nexport const identityN = (N: number): Matrix => {\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n if(N === 0) return [];\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mDeepCopy(m2) as Matrix2;\n};\n\nexport const m3DeepCopy = (m3: Matrix3): Matrix3 => {\n return mDeepCopy(m3) as Matrix3;\n};\n\n// -------------- APPEND / PREPEND ROW OR COLUMN ---------------\n\nexport const mAppendCol = (m: Matrix, col: Vector): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n const copy = mDeepCopy(m);\n copy.push(row);\n return copy;\n};\n\nexport const m2AppendRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.push(row);\n return copy;\n};\n\nexport const m3AppendRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.push(row);\n return copy;\n};\n\nexport const mPrependRow = (m: Matrix, row: Vector) : Matrix => {\n const copy = mDeepCopy(m);\n copy.unshift(row);\n return copy;\n};\n\nexport const m2PrependRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.unshift(row);\n return copy;\n};\n\nexport const m3PrependRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.unshift(row);\n return copy;\n};\n\n// ------------ DELETE ROW OR COLUMN ----------------------------\n\nexport const mDelLastRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.pop();\n return copy;\n};\n\nexport const mDelFirstRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.shift();\n return copy;\n};\n\nexport const mDelLastColumn = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const size = m[0].length;\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n\n const matrix: Matrix = [];\n for(let i=0; i {\n\n if(matrix.length < 0) return [];\n\n if(matrix[0].length !== vector.length){\n throw new Error('The number of columns in the matrix must be equal to the length of the vector.');\n }\n\n const res: Vector = [];\n\n for(let i=0; i {\n if(matrix1.length !== matrix2.length) return false;\n\n for(let i=0; i returns matrix N (m-1 x m-1)\n * The matrix must be square.\n */\nconst mMinorHelper = (m: Matrix, row: number, col: number) => {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // prepare the matrix without provided row and column\n const matrix = mMinorHelper(m, row, col);\n\n // calculate the matrix determinant\n return mDeterminant(matrix);\n};\n\n/**\n * Calculate determinant for NxN matrix.\n * Matrix should be square.\n */\nexport const mDeterminant = (matrix: Matrix): number => {\n const size = matrix.length;\n if(size === 0) return 1;\n\n if(size !== matrix[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return matrix[0][0];\n if(size === 2) return m2Determinant(matrix as Matrix2);\n\n let d = 0;\n\n for(let i=0; i {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return m2[0][0] * m2[1][1] - m2[1][0] * m2[0][1];\n};\n\n/**\n * Calculate determinant for 3x3 matrix.\n * Matrix should be square.\n */\nexport const m3Determinant = (m3: Matrix3): number => {\n if(m3.length !== m3[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return mDeterminant(m3);\n};\n\n// ------------------ INVERSE -----------------------\n\nexport const m2Adjugate = (m2: Matrix2): Matrix2|null => {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return [\n [m2[1][1], -m2[0][1]],\n [-m2[1][0], m2[0][0]],\n ];\n};\n\nexport const m3Adjugate = (m3: Matrix3) : Matrix3|null => {\n return mAdjugate(m3) as (Matrix3|null);\n};\n\n/**\n * Adjugate is a transpose of a cofactor matrix\n */\nexport const mAdjugate = (m: Matrix): Matrix|null => {\n\n const size = m.length;\n if(size <= 0) return null;\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return m;\n\n if(size === 2) return m2Adjugate(m as Matrix2);\n\n // build a cofactor matrix ----------------\n const cofactors: Matrix = [];\n\n for(let i=0; i {\n if(m.length > 0 && m.length !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = mDeterminant(m);\n return d === 0;\n};\n\n/**\n * Square matrix A (nxn) is invertible is there is another square matrix B (nxn) so AxB = BxA = I\n * For A (2x2) matrix, the inverse is:\n * (1 / (determinant(A))) * adj(A)\n */\nexport const m2Inverse = (m2: Matrix2, decimalPlaces = Infinity): (Matrix2 | null) => {\n if(m2.length > 0 && m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = m2Determinant(m2);\n if(d === 0) return null;\n\n const adj = m2Adjugate(m2);\n if(adj === null) return null;\n\n return m2DivideScalar(adj, d, decimalPlaces);\n};\n\nexport const m3Inverse = (m3: Matrix3, decimalPlaces = Infinity): (Matrix3 | null) => {\n return mInverse(m3, decimalPlaces) as (Matrix3|null);\n};\n\nexport const mInverse = (m: Matrix, decimalPlaces = Infinity): (Matrix | null) => {\n const size = m.length;\n\n if(size > 0 && size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // find a determinant ----------------------\n const d = mDeterminant(m);\n\n // find an Adjugate - a transpose of a cofactor matrix\n const adj = mAdjugate(m);\n if(adj === null) return null;\n\n return mDivideScalar(adj, d, decimalPlaces);\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector2, Vector3, Vector4 } from '../../types';\nimport { v2Normalize, v3MulScalar, v3Normalize } from './vector';\nimport { mMulVector, mMul } from './matrix';\nimport { setDecimalPlaces } from '../format';\n\n/*\nAny 2D affine transformation can be decomposed\ninto a rotation, followed by a scaling, followed by a\nshearing, and followed by a translation.\n---------------------------------------------------------\nAffine matrix = translation x shearing x scaling x rotation\n */\n\n// ----------------- CSS -------------------------------------\n\n/**\n * Matrix 2D in non-homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2ToCSS = (m: Matrix2) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, 0, 0)`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2hToCSS = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, ${ tx }, ${ ty })`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m2hToCSS3d = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix3d(${ a }, ${ b }, 0, 0, ${ c }, ${ d }, 0, 0, 0, 0, 1, 0, ${ tx }, ${ ty }, 0, 1)`;\n};\n\n/**\n * Matrix 3D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m3hToCSS3d = (m: Matrix4) : string => {\n\n return `matrix3d(\n ${ m[0][0] }, ${ m[0][1] }, ${ m[0][2] }, ${ m[0][3] },\n ${ m[1][0] }, ${ m[1][1] }, ${ m[1][2] }, ${ m[1][3] },\n ${ m[2][0] }, ${ m[2][1] }, ${ m[2][2] }, ${ m[2][3] },\n ${ m[3][0] }, ${ m[3][1] }, ${ m[3][2] }, ${ m[3][3] }\n )`;\n};\n\n// ---------------- TRANSLATION MATRICES ----------------------\n\nexport const m2Translation = (position: Vector2, decimalPlaces = Infinity): Matrix2 => {\n\n return [\n [1, 0],\n [0, 1],\n [setDecimalPlaces(position[0], decimalPlaces), setDecimalPlaces(position[1], decimalPlaces)],\n ];\n};\n\nexport const m3Translation = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n [\n setDecimalPlaces(position[0], decimalPlaces),\n setDecimalPlaces(position[1], decimalPlaces),\n setDecimalPlaces(position[2], decimalPlaces)\n ],\n ];\n};\n\n/**\n * 2D Translation matrix in homogeneous coordinates.\n */\nexport const m2TranslationH = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1],\n ];\n};\n\n/**\n * 3D Translation matrix in homogeneous coordinates.\n */\nexport const m3TranslationH = (position: Vector4, decimalPlaces = Infinity): Matrix4 => {\n\n return [\n [1, 0, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, 0, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1, setDecimalPlaces(position[2], decimalPlaces)],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- ROTATION MATRICES -------------------------\n\n/**\n * Rotation of an angle about the origin.\n */\nexport const m2Rotation = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix2 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin],\n [sin, cos],\n ] :\n [\n [cos, sin],\n [-sin, cos],\n ];\n};\n\n/**\n * Rotation of an angle about the origin in homogeneous coordinates (clockwise).\n */\nexport const m2RotationH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ]:\n [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation of an angle \"angleRad\" around the given point (transformOrigin) in homogeneous coordinates (clockwise).\n * result_vector = TranslationMatrix(x, y) * RotationMatrix() * TranslationMatrix(-x, -y) * position_vector\n */\nexport const m2RotationAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const rotation = m2RotationH(angleRad, isClockwise, decimalPlaces);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, rotation);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2RotateAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n position: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2RotationAroundPointH(angleRad, transformOrigin, isClockwise, decimalPlaces);\n return mMulVector(mat3h, position) as Vector3;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2Rotate = (angleRad: number, vector: Vector2, isClockwise = true, decimalPlaces = Infinity): Vector2 => {\n const unitVector = v2Normalize(vector);\n return mMulVector(m2Rotation(angleRad, isClockwise, decimalPlaces), unitVector) as Vector2;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2RotateH = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m2RotationH(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the X axis (clockwise).\n */\nexport const m3RotationX = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0],\n [0, cos, -sin],\n [0, sin, cos],\n ] :\n [\n [1, 0, 0],\n [0, cos, sin],\n [0, -sin, cos],\n ];\n};\n\n/**\n * Rotation around the X axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationXH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0, 0],\n [0, cos, -sin, 0],\n [0, sin, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [1, 0, 0, 0],\n [0, cos, sin, 0],\n [0, -sin, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateX = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationX(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Y axis (clockwise).\n */\nexport const m3RotationY = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin],\n [0, 1, 0],\n [-sin, 0, cos],\n ] :\n [\n [cos, 0, -sin],\n [0, 1, 0],\n [sin, 0, cos],\n ];\n};\n\n/**\n * Rotation around the Y axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationYH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin, 0],\n [0, 1, 0, 0],\n [-sin, 0, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [cos, 0, -sin, 0],\n [0, 1, 0, 0],\n [sin, 0, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateY = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationY(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Z axis (clockwise).\n */\nexport const m3RotationZ = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ] : [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation around the Z axis (clockwise)- in homogeneous coordinates\n */\nexport const m3RotationZH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0, 0],\n [sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ] : [\n [cos, sin, 0, 0],\n [-sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateZ = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationZ(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n// ---------------- SCALE MATRICES -------------\n\n/**\n * Get matrix for arbitrary scaling pivot point.\n * result_vector = TranslationMatrix(x, y) * ScaleMatrix() * TranslationMatrix(-x, -y) * scale_vector\n */\nexport const m2ScaleAtPointHMatrix = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const scale = m2ScaleH(scaleVector);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, scale);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2ScaleAtPointH = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n point: Vector3,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2ScaleAtPointHMatrix(scaleVector, transformOrigin, decimalPlaces);\n return mMulVector(mat3h, point) as Vector3;\n};\n\nexport const m2Scale = (scaleVector: Vector2): Matrix2 => {\n return [\n [scaleVector[0], 0],\n [0, scaleVector[1]],\n ];\n};\n\nexport const v2Scale = (scaleVector: Vector2, vector: Vector2): Vector2 => {\n return mMulVector(m2Scale(scaleVector), vector) as Vector2;\n};\n\n/**\n * homogeneous coordinates\n */\nexport const m2ScaleH = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, 1],\n ];\n};\n\nexport const m3Scale = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, scaleVector[2]],\n ];\n};\n\nexport const m3ScaleH = (scaleVector: Vector4): Matrix4 => {\n return [\n [scaleVector[0], 0, 0, 0],\n [0, scaleVector[1], 0, 0],\n [0, 0, scaleVector[2], 0],\n [0, 0, 0, 1]\n ];\n};\n\nexport const v3Scale = (scaleVector: Vector3, vector: Vector3): Vector3 => {\n return mMulVector(m3Scale(scaleVector), vector) as Vector3;\n};\n\n/**\n * Stretch, parallel to the x-axis.\n */\nexport const m2ScaleX = (scale: number): Matrix2 => {\n return [\n [scale, 0],\n [0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the x-axis - homogeneous coordinates\n */\nexport const m2ScaleXH = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleX = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleXH = (scale: number): Matrix4 => {\n return [\n [scale, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleY = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleYH = (scale: number): Matrix => {\n return [\n [1, 0, 0, 0],\n [0, scale, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZ = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, scale],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZH = (scale: number): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, scale, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis.\n */\nexport const m2ScaleY = (scale: number): Matrix2 => {\n return [\n [1, 0],\n [0, scale],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis - homogeneous coordinates\n */\nexport const m2ScaleYH = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n// ---------------- REFLECTION MATRICES -------------------------\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOrigin = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOriginH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection about the origin in non-homogeneous coordinates\n */\nexport const m3ReflectionOrigin = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection about the origin in homogeneous coordinates\n */\nexport const m3ReflectionOriginH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection about y=-x\n */\nexport const m2ReflectionYmX = (): Matrix2 => {\n\n return [\n [0, -1],\n [-1, 0],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionX = (): Matrix2 => {\n\n return [\n [1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionXH = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection in the y-axis.\n */\nexport const m2ReflectionY = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, 1],\n ];\n};\n\nexport const m2ReflectionYH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionYZ = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in homogeneous coordinates\n */\nexport const m3ReflectionYZH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXZ = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in homogeneous coordinates\n */\nexport const m3ReflectionXZH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXY = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in homogeneous coordinates\n */\nexport const m3ReflectionXYH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- SHEARING MATRICES -------------------------\n\n\n/**\n * Shearing in y-axis, with x-axis fixed with (0,1) moving to (factor, 1)\n */\nexport const m2ShearingY = (factor: number): Matrix2 => {\n\n return [\n [1, factor],\n [0, 1],\n ];\n};\n\n/**\n * Shearing in x-axis, with y-axis fixed with (1,0) moving to (1, factor)\n */\nexport const m2ShearingX = (factor: number): Matrix2 => {\n\n return [\n [1, 0],\n [factor, 1],\n ];\n};", "import { setDecimalPlaces } from './format';\n\n/**\n * Returns a random number in the [min,max] range.\n */\nexport const getRandom = (min: number, max: number, decimalPlaces = Infinity): number => {\n return setDecimalPlaces(Math.random() * (max - min) + min, decimalPlaces);\n};\n\n/**\n * Returns a random integer number in the [min,max] range.\n */\nexport const getRandomInt = (min: number, max: number): number => {\n return Math.floor(Math.random() * (max - min + 1) + min);\n};\n\nexport const getRandomBoolean = () => Math.random() < 0.5;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const getRandomItemFromArray = (array: any[]) => {\n const randomIndex = getRandomInt(0, array.length - 1);\n return array[randomIndex];\n};", "export const stringToNumber = (value: string|undefined|null|number, defaultNumber: number) => {\n if(value === undefined || value === null) return defaultNumber;\n const res = Number(value) ?? defaultNumber;\n return isNaN(res) ? defaultNumber : res;\n};", "import { setDecimalPlaces } from './format';\nimport { Vector2, Vector3 } from '../types';\n\n/**\n * u(x) and v(x) are functions ---------->\n *\n * dx(u + v) = dx(u) + dx(v)\n * dx(u - v) = dx(u) - dx(v)\n * dx(u * v) = dx(u) * v + u * dx(v)\n * dx(u / v) = (dx(u) * v - u * dx(v)) / (v ^ 2), when v(x) != 0\n */\n\n// ------------------ Derivatives of Polynomial ---------------------------\n\n/**\n * y = 3x+2\n * dxPolynomial(10, [[3, 1], [2, 0]])\n */\nexport const dxPolynomial = (x: number, polynomial: number[][], decimalPlaces = Infinity) => {\n let res = 0;\n\n for(const part of polynomial){\n if(part.length !== 2) return NaN;\n\n const coeff = part[0];\n const power = part[1];\n res += coeff * power * Math.pow(x, power - 1);\n }\n\n return setDecimalPlaces(res, decimalPlaces);\n}\n\n// ---------------------- Bezier Curves ---------------------------\n\n/**\n * Derivative of Bezier Curve is another Bezier Curve.\n * t must min in range [0, 1]\n */\nexport const dxV2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n // The derivative: P1 * (2t-2) + (2*P3-4*P2) * t + 2 * P2\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\nexport const dxV2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n\n// ----------------- Derivatives of trigonometry functions ---------------------------\n\nexport const dxSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(Math.cos(x), decimalPlaces);\n};\n\nexport const dxCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-Math.sin(x), decimalPlaces);\n};\n\nexport const dxTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.cos(x) ** 2), decimalPlaces);\n};\n\n/**\n * x != Math.PI * n, where n is an integer\n */\nexport const dxCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sin(x) ** 2), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\nexport const dxArcTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (1 + x ** 2), decimalPlaces);\n};\n\nexport const dxArcCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (1 + x ** 2), decimalPlaces);\n};\n", "import { Matrix, Matrix2, Matrix3, Vector, Vector2, Vector3 } from '../../types';\nimport { m2Inverse, m3Inverse, mInverse, mMulVector, mDelLastColumn, mGetLastColumn } from '../linear-algebra/matrix';\nimport { setDecimalPlaces } from '../format';\nimport { v2Sub } from '../linear-algebra/vector';\n\n/**\n * Linear equation\n * ax + b = c\n * x = (c - b) / a; a != 0\n */\nexport const linearEquation = (equation: Vector3, decimalPlaces = Infinity) : number => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n\n const diff = c - b;\n\n if(a === 0 && diff === 0) return Infinity; // any number is a solution\n if(a === 0) return NaN; // no solution\n\n return setDecimalPlaces(diff / a, decimalPlaces);\n};\n\n/**\n * System of 2 linear equations.\n * [x, y] = inverse(Matrix of equation parameters) x (vector of equation results)\n * ---------------\n * 3x + 2y = 7\n * -6x + 6y = 6\n */\nexport const linearEquationSystem2 = (equation1: Vector3, equation2: Vector3, decimalPlaces = Infinity) : Vector2 | null => {\n const equationParams: Matrix2 = [\n [equation1[0], equation1[1]],\n [equation2[0], equation2[1]],\n ];\n\n const inversed = m2Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector2 = [\n equation1[2],\n equation2[2]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector2;\n};\n\n/**\n * System of 3 linear equations.\n * ---------------------------------------\n * 3x + 2y + 5z = 7\n * -6x + 6y + 6z = 6\n * 2x + 7y - z = 4\n */\nexport const linearEquationSystem3 = (\n equation1: Vector,\n equation2: Vector,\n equation3: Vector,\n decimalPlaces = Infinity) : Vector3 | null => {\n const equationParams: Matrix3 = [\n [equation1[0], equation1[1], equation1[2]],\n [equation2[0], equation2[1], equation2[2]],\n [equation3[0], equation3[1], equation3[2]],\n ];\n\n const inversed = m3Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector3 = [\n equation1[3],\n equation2[3],\n equation3[3]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector3;\n};\n\n/**\n * System of N linear equations.\n */\nexport const linearEquationSystemN = (equations: Matrix, decimalPlaces = Infinity) : Vector | null => {\n if(equations.length <= 0) return null;\n\n const equationParams = mDelLastColumn(equations);\n\n const inversed = mInverse(equationParams);\n if(inversed === null) return null; // no results\n\n // the last column of the equations matrix\n const equationResults = mGetLastColumn(equations);\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector;\n};\n\n/**\n * Calculate the equation of a line given two points in a 2D space.\n * y = ax + b\n * y - y1 = m(x - x1)\n * m = (y2 - y1) / (x2 - x1)\n */\nexport const getLinearEquationBy2Points = (point1: Vector2, point2: Vector2) : {\n slope: number|undefined,\n yIntercept: number|undefined,\n xIntercept: number|undefined,\n formula: string,\n} => {\n const [deltaX, deltaY] = v2Sub(point2, point1);\n const [x, y] = point1;\n\n if(deltaX === 0) {\n return {\n slope: undefined,\n xIntercept: x,\n yIntercept: undefined,\n formula: `x = ${ x }`,\n };\n }\n\n const m = deltaY / deltaX;\n const b = y - m * x;\n let formula = '';\n\n if(m === 0) {\n formula = `y = ${ b }`;\n }\n else{\n formula = `y = ${ m === 1 ? '' : m }x`;\n\n if(b !== 0) {\n formula += ` ${ b < 0 ? '-' : '+' } ${ Math.abs(b) }`;\n }\n }\n\n return {\n slope: m,\n xIntercept: undefined,\n yIntercept: b,\n formula,\n };\n};", "import { Vector } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { linearEquation } from './linear-equations';\nimport { isNumber } from '../other';\n\n/**\n * Quadratic Equation.\n * ax^2 + bx + c = d\n */\nexport const quadraticEquation = (equation: Vector, decimalPlaces = Infinity) : Vector => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n const d = equation[3];\n\n if(a === 0){\n // it's a linear equation -------------------------------------------\n const res = linearEquation([b, c, d], decimalPlaces);\n if(isNumber(res)) return [res];\n return [];\n }\n\n const diff = c - d;\n\n const discriminant = b * b - (4 * a * diff);\n\n if(discriminant < 0){\n return []; // no results\n }\n\n if(discriminant === 0){\n return [ setDecimalPlaces(-b / (2 * a), decimalPlaces) ]; // 1 result\n }\n\n // if(determinant > 0) ---> 2 results\n const t1 = 2 * a;\n const t2 = Math.sqrt(discriminant);\n\n return [\n setDecimalPlaces((-b + t2) / t1, decimalPlaces),\n setDecimalPlaces((-b - t2) / t1, decimalPlaces),\n ];\n};", "import { IBBox, Vector, Vector2, Vector3 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport {\n dxV2CubicBezierCurve,\n dxV2QuadraticBezierCurve,\n dxV3CubicBezierCurve,\n dxV3QuadraticBezierCurve\n} from '../derivative';\nimport { v2Normalize, v3Normalize } from '../linear-algebra/vector';\nimport { linearEquation } from '../equations/linear-equations';\nimport { quadraticEquation } from '../equations/quadratic-equations';\nimport { isNumber } from '../other';\n\n/**\n * B\u00E9zier Curves\n * quadratic: y = P1 * (1-t)\u00B2 + P2 * 2 * (1-t)t + P3 * t\u00B2\n * t in range [0, 1]\n */\n\n// -------------------- GET POINT ON CURVE --------------------------\n\n/**\n * Get a point on a quadratic B\u00E9zier curve as a function of time.\n */\nexport const v2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n/**\n * Get a point on a cubic B\u00E9zier curve as a function of time.\n */\nexport const v2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n// -------------------- TANGENT --------------------------\n\n/**\n * Tangent indicates the direction of travel at specific points along the B\u00E9zier curve,\n * and is literally just the first derivative of our curve.\n */\nexport const v2QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\nexport const v2CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\n// -------------------- NORMAL --------------------------\n\n/**\n * Normal is a vector that runs at a right angle to the direction of the curve, and is typically of length 1.\n * To find it, we take the normalised tangent vector, and then rotate it by a 90 degrees.\n */\nexport const v2QuadraticBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2QuadraticBezierCurveTangent(t, startControlPoint, centerControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\nexport const v2CubicBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2CubicBezierCurveTangent(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\n// -------------------- EXTREMA --------------------------\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2QuadraticBezierCurveExtrema = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector => {\n\n /*\n (-2 * (1 - t)) * startControlPoint[0] + (2 - 4 * t) * centerControlPoint[0] + (2 * t) * endControlPoint[0]\n 2 * t * startControlPoint[0] - 4 * t * centerControlPoint[0] + 2 * t * endControlPoint[0] - 2 * startControlPoint[0] + 2 * centerControlPoint[0]\n t * (2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0]) + (- 2 * startControlPoint[0] + 2 * centerControlPoint[0])\n */\n\n const a1 = 2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0];\n const b1 = -2 * startControlPoint[0] + 2 * centerControlPoint[0];\n const equation1: Vector3 = [a1, b1, 0];\n const res1 = linearEquation(equation1, decimalPlaces);\n\n const a2 = 2 * startControlPoint[1] - 4 * centerControlPoint[1] + 2 * endControlPoint[1];\n const b2 = -2 * startControlPoint[1] + 2 * centerControlPoint[1];\n const equation2: Vector3 = [a2, b2, 0];\n const res2 = linearEquation(equation2, decimalPlaces);\n\n const res: Vector = [];\n\n if(isNumber(res1)){\n res.push(res1);\n }\n\n if(isNumber(res2)){\n res.push(res2);\n }\n\n return res;\n};\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2CubicBezierCurveExtrema = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2|null => {\n\n const a1 = -3 * startControlPoint[0] + 9 * center1ControlPoint[0] - 9 * center2ControlPoint[0] + 3 * endControlPoint[0];\n const b1 = 6 * startControlPoint[0] - 12 * center1ControlPoint[0] + 6 * center2ControlPoint[0];\n const c1 = -3 * startControlPoint[0] + 3 * center1ControlPoint[0];\n const equation1: Vector = [a1, b1, c1, 0];\n\n const a2 = -3 * startControlPoint[1] + 9 * center1ControlPoint[1] - 9 * center2ControlPoint[1] + 3 * endControlPoint[1];\n const b2 = 6 * startControlPoint[1] - 12 * center1ControlPoint[1] + 6 * center2ControlPoint[1];\n const c2 = -3 * startControlPoint[1] + 3 * center1ControlPoint[1];\n const equation2: Vector = [a2, b2, c2, 0];\n\n // Any value between 0 and 1 is a root that matters for B\u00E9zier curves, anything below or above that is irrelevant (because B\u00E9zier curves are only defined over the interval [0,1]).\n const res1 = quadraticEquation(equation1, decimalPlaces).filter(num => num >= 0 && num <= 1);\n const res2 = quadraticEquation(equation2, decimalPlaces).filter(num => num >= 0 && num <= 1);\n\n const res = [...res1, ...res2];\n if(res.length === 2){\n return [...res1, ...res2] as Vector2;\n }\n\n return null;\n};\n\n// -------------------- BOUNDING BOX --------------------------\n\nexport const v2QuadraticBezierBBox = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2QuadraticBezierCurveExtrema(startControlPoint, centerControlPoint, endControlPoint);\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2QuadraticBezierCurve(percent, startControlPoint, centerControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\nexport const v2CubicBezierBBox = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2CubicBezierCurveExtrema(startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint) || [];\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2CubicBezierCurve(percent, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x ?? Infinity);\n maxX = Math.max(maxX, x ?? -Infinity);\n\n minY = Math.min(minY, y ?? Infinity);\n maxY = Math.max(maxY, y ?? -Infinity);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\n\n", "import { Vector2 } from '../types';\nimport { v2Sub } from './linear-algebra/vector';\nimport { getV2Angle } from './angle';\nimport { convertRange } from './other';\n\n/**\n * Circle Equation\n * x^2 + y^2 = radius^2\n * ----------------------\n * Circle Parametric Equation\n * x(t) = radius * cos(t)\n * y(t) = radius * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const circleMovement = (center: Vector2, angle: number, radius: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius,\n center[1] + Math.sin(angle) * radius\n ];\n};\n\n/**\n * Circle Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const circleMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radius: number\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return circleMovement(center, angle, radius);\n};\n\n/**\n * Ellipse Equation\n * (x - centerX)^2 / (radius1^2) + (y - centerY)^2 / (radius2^2) = 1\n * -----------------------------------------------------------------\n * Ellipse Parametric Equation\n * x(t) = radius1 * cos(t)\n * y(t) = radius2 * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const ellipseMovement = (center: Vector2, angle: number, radius1: number, radius2: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius1,\n center[1] + Math.sin(angle) * radius2\n ];\n};\n\n/**\n * Ellipse Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const ellipseMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radii: Vector2\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return ellipseMovement(center, angle, radii[0], radii[1]);\n};\n\n/**\n * Sine Wave Equation (Sinusoid)\n * -----------------------------\n * const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n * amplitude = the peak deviation of the function from zero\n * frequency = number of cycles\n * phase = specifies (in radians) where in its cycle the oscillation is at t = 0.\n * think of it as \"shifting\" the starting point of the function to the right (positive p) or left (negative)\n */\nexport const sineWaveMovement = (x: number, amplitude: number, frequency: number, phase: number) : Vector2 => {\n /*\n example values:\n const amplitude = 50;\n const frequency = 0.005;\n const phase = 0;\n x: [0, 1000]\n */\n const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n\n return [x, y];\n};\n\n/**\n * Lissajous curve (Lissajous figure or Bowditch curve)\n * Parametric equation #1\n * f(t) = A * sin(k * t + m)\n * f(t) = B * sin(n * t)\n * 0 <= m <= PI/2\n * k, n >= 1\n * -----------------------\n * Parametric equation #2\n * f(t) = A * cos(k * t - m)\n * f(t) = B * cos(n * t - p)\n * -----------------------------\n * Shapes:\n * k = 1, n = 1, m = 0, p = 0 ---> line\n * A = B, k = 1, n = 1, m = PI/2, p = PI/2 ----> circle\n * A != B, k = 1, n = 1, m = PI/2, p = PI/2 ----> ellipse\n * k = 2, n = 2, m = PI/2, p = PI/2 ----> section of a parabola\n */\nexport const lissajousCurve = (\n width: number,\n height: number,\n t: number,\n k: number,\n n: number,\n m: number,\n p: number\n) :Vector2 => {\n return [\n width * Math.cos(k * t - m),\n height * Math.cos(n * t - p),\n ];\n};\n", "import { getRandom } from './random';\nimport { HSLColor, RGBColor } from '../types';\nimport { mod } from './other';\nimport { setDecimalPlaces } from './format';\n\n// ------------------------ RANDOM COLOR -------------------------------------\n\nexport const getRandomRGBColor = () : RGBColor => {\n const hslColor = getRandomHSLColor();\n return hslToRgb(hslColor);\n};\n\nexport const getRandomHexColor = () : string => {\n const hslColor = getRandomHSLColor();\n return hslToHex(hslColor);\n};\n\nexport const getRandomHSLColor = () : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given hue\n */\nexport const getRandomHSLColorWithHue = (h: number) : HSLColor => {\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given saturation\n */\nexport const getRandomHSLColorWithSaturation = (s: number) : HSLColor => {\n const h = getRandom(1, 360);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given lightness\n */\nexport const getRandomHSLColorWithLightness = (l: number) : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n return [h, s, l];\n};\n\nexport const getRandomGrayscaleHSLColor = () : HSLColor => {\n const l = getRandom(0, 100);\n return [0, 0, l];\n};\n\nexport const getRandomHSLColorWithinRanges = (\n hueStart = 1, hueEnd = 360,\n saturationStart = 0, saturationEnd = 100,\n lightStart = 0, lightEnd = 100\n) : HSLColor => {\n const h = getRandom(hueStart, hueEnd);\n const s = getRandom(saturationStart, saturationEnd);\n const l = getRandom(lightStart, lightEnd);\n return [h, s, l];\n};\n\n// ----------------------- CONVERT COLORS --------------------------------------\n\n/**\n * helper: convert hue value to %\n * @param {number} h\n * @return {number} [0, 100] %\n */\nconst convertHueToPercent = (h : number) : number => {\n\n // the hue value needs to be multiplied by 60 to convert it to degrees\n h *= 60;\n\n // if hue becomes negative, you need to add 360 to, because a circle has 360 degrees\n if(h < 0){\n h += 360;\n }\n\n // convert huw to %\n return h * 100 / 360;\n};\n\n/**\n * get hue from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] % - we use here % instead of [0, 359] degrees\n */\nconst getHue = (r : number, g : number, b : number, min : number | undefined = undefined, max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no hue, as it's gray\n if(min === max) return 0;\n\n // if red is max\n if(max === r){\n return convertHueToPercent((g - b) / (max - min));\n }\n\n // if green is max\n if(max === g){\n return convertHueToPercent(2.0 + (b - r) / (max - min));\n }\n\n // if blue is max\n if(max === b){\n return convertHueToPercent(4.0 + (r - g) / (max - min));\n }\n\n return 0;\n};\n\n/**\n * get luminance from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] %\n */\nconst getLuminance = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // calculate the luminance value\n // @ts-ignore\n const l = (min + max) / 2; // [0, 1]\n\n // return l value in %\n return l * 100;\n};\n\n/**\n * get saturation from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @param {number|undefined=} l - luminance in [0, 100] %\n * @return {number} [0, 100] %\n */\nconst getSaturation = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined,\n l : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no saturation, as it's gray\n if(min === max) return 0;\n\n // calculate luminance if it's not provided\n l = (l === undefined) ? getLuminance(r, g, b) : l;\n\n // check the level of luminance\n const s = (l <= 50) ?\n // @ts-ignore\n ((max - min) / (max + min)) : // this formula is used when luminance <= 50%\n // @ts-ignore\n (max - min) / (2.0 - max - min); // this formula is used when luminance > 50%\n\n // return saturation in %\n return s * 100;\n};\n\nexport const rgbToHsl = (rgb: RGBColor, decimalPlaces = Infinity): HSLColor => {\n\n // convert rgb values to the range [0, 1]\n const r = rgb[0] / 255;\n const g = rgb[1] / 255;\n const b = rgb[2] / 255;\n\n // find the minimum and maximum values of r, g, and b\n const min = Math.min(r, g, b);\n const max = Math.max(r, g, b);\n\n // calculate the luminance value in %\n const l = getLuminance(r, g, b, min, max);\n\n // calculate the saturation in %\n const s = getSaturation(r, g, b, min, max, l);\n\n // calculate the hue in % (not in degrees!)\n const h = getHue(r, g, b, min, max);\n\n if(h > 360 || s > 100 || l > 100){\n return [0, 0, 100];\n }\n\n if(h < 0 || s < 0 || l < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(h, decimalPlaces),\n setDecimalPlaces(s, decimalPlaces),\n setDecimalPlaces(l, decimalPlaces),\n ];\n};\n\n/**\n * helper: HSL to RGB\n */\nconst hslToRgbHelper = (helper1 : number, helper2 : number, colorHelper : number) : number => {\n\n // all values need to be between 0 and 1\n // if you get a negative value you need to add 1 to it\n if(colorHelper < 0) colorHelper += 1;\n\n // if you get a value above 1 you need to subtract 1 from it.\n if(colorHelper > 1) colorHelper -= 1;\n\n if(colorHelper * 6 < 1) return helper2 + (helper1 - helper2) * 6 * colorHelper;\n\n if(colorHelper * 2 < 1) return helper1;\n\n if(colorHelper * 3 < 2){\n return helper2 + (helper1 - helper2) * (0.666 - colorHelper) * 6;\n }\n else{\n return helper2;\n }\n};\n\nexport const hslToRgb = (hsl: HSLColor, decimalPlaces = Infinity): RGBColor => {\n\n // convert all values to [0, 1] from %\n const h = hsl[0] / 100;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n // if there is no saturation -> it\u2019s grey\n if(s === 0){\n // convert the luminance from [0, 1] to [0, 255]\n const gray = l * 255;\n return [gray, gray, gray];\n }\n\n // check the level of luminance\n const helper1 = (l < 0.5) ?\n (l * (1.0 + s)) :\n (l + s - l * s);\n\n const helper2 = 2 * l - helper1;\n\n const rHelper = h + 0.333;\n const gHelper = h;\n const bHelper = h - 0.333;\n\n let r = hslToRgbHelper(helper1, helper2, rHelper);\n let g = hslToRgbHelper(helper1, helper2, gHelper);\n let b = hslToRgbHelper(helper1, helper2, bHelper);\n\n // convert rgb to [0, 255]\n r *= 255;\n g *= 255;\n b *= 255;\n\n if(r > 255 || g > 255 || b > 255){\n return [255, 255, 255];\n }\n\n if(r < 0 || g < 0 || b < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(r, decimalPlaces),\n setDecimalPlaces(g, decimalPlaces),\n setDecimalPlaces(b, decimalPlaces),\n ];\n};\n\n/**\n * HSL to hex\n * hslToHex(360, 100, 50) // [360, 100, 5] ==> \"#ff0000\" (red)\n */\nexport const hslToHex = (hsl: HSLColor) => {\n\n if(hsl[0] > 360 || hsl[1] > 100 || hsl[2] > 100){\n return '#ffffff';\n }\n\n if(hsl[0] < 0 || hsl[1] < 0 || hsl[2] < 0){\n return '#000000';\n }\n\n const h = hsl[0] / 360;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n let r, g, b;\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n};\n\n// ----------------------- GET SHIFTED COLORS --------------------------------------\n\nexport const getShiftedHue = (color: HSLColor, shift = 180) : HSLColor => {\n let hue = color[0];\n hue += shift;\n\n if (hue > 360 || hue < 0) {\n hue = mod(hue, 360);\n }\n\n return [hue, color[1], color[2]];\n};\n\nexport const getShiftedLightness = (color: HSLColor, shift = 10) : HSLColor => {\n let lightness = color[2];\n lightness += shift;\n\n if (lightness > 100 || lightness < 0) {\n lightness = mod(lightness, 100);\n }\n\n return [color[0], color[1], lightness];\n};\n\nexport const getShiftedSaturation = (color: HSLColor, shift = 10) : HSLColor => {\n let saturation = color[1];\n saturation += shift;\n\n if (saturation > 100) {\n saturation -= 100;\n }\n\n if(saturation < 0){\n saturation += 100;\n }\n\n return [color[0], saturation, color[2]];\n};\n", "/**\n * guid like '932ade5e-c515-4807-ac01-73b20ab3fb66'\n */\nexport const guid = () => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);\n });\n};\n\n/**\n * id like 'df4unio1opulby2uqh4'\n */\nexport const newId = () => {\n return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);\n};\n", "import { ICircle, IPolygon, IRect, Matrix2, Vector2 } from '../types';\nimport { mod } from './other';\nimport { v2GetNormal, v2DotProduct } from './linear-algebra/vector';\n\n/**\n * Rectangles collision detection.\n * Rectangles should not be rotated.\n * The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles.\n * Any gap means a collision does not exist.\n * Returns true if collision is detected.\n */\nexport const rectCollide = (rect1: IRect, rect2: IRect) : boolean => {\n return rect1.x <= rect2.x + rect2.w &&\n rect1.x + rect1.w >= rect2.x &&\n rect1.y <= rect2.y + rect2.h &&\n rect1.h + rect1.y >= rect2.y;\n};\n\n/**\n * Circles collision detection.\n * This algorithm works by taking the center points of the two circles\n * and ensuring the distance between the center points\n * are less than the two radii added together.\n * Returns true if collision is detected.\n */\nexport const circleCollide = (circle1: ICircle, circle2: ICircle) => {\n const dx = Math.abs(circle1.cx - circle2.cx);\n const dy = Math.abs(circle1.cy - circle2.cy);\n const distance = Math.sqrt(dx * dx + dy * dy);\n return distance <= circle1.r + circle2.r;\n};\n\n//-------------------- Separating Axis Theorem (SAT) Collision detection -------------------------\n\nconst getEdges = (poly: IPolygon) : Matrix2[] => {\n const edges: Matrix2[] = [];\n\n for(let i= 0; i {\n const edges: Matrix2[] = [];\n\n // collect polygon edges, and combine then into a single array\n edges.push(...getEdges(poly1));\n edges.push(...getEdges(poly2));\n\n // for each edge, find the normal vector and project both polygons onto it\n for (const edge of edges) {\n const normal = v2GetNormal(edge[0], edge[1]);\n const p1Proj = projectPolygon(poly1, normal);\n const p2Proj = projectPolygon(poly2, normal);\n\n // Check if the projections overlap\n const isOverlap = p1Proj.max >= p2Proj.min && p2Proj.max >= p1Proj.min;\n\n // Check if the projections overlap; if not, the polygons do not collide\n if (!isOverlap) return false;\n }\n\n // If all tests pass, the polygons overlap and collide\n return true;\n};\n\n/**\n * Project every polygon point onto the normal.\n * Then find min and max.\n */\nconst projectPolygon = (polygon: IPolygon, normal: Vector2): { min: number, max: number } => {\n let min = Infinity;\n let max = -Infinity;\n\n // Project each vertex of the polygon onto the axis\n for (const vertex of polygon) {\n const projection = v2DotProduct(vertex, normal);\n min = Math.min(min, projection);\n max = Math.max(max, projection);\n }\n\n return { min, max };\n};", "export interface IAnimationProps {\n duration?: number;\n callback: (result: IAnimationResult) => void;\n restartOnResize?: boolean;\n resizeCallback?: (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => void;\n}\n\nexport interface IAnimationResult {\n start: () => void;\n stop: () => void;\n pause: () => void;\n resume: () => void;\n restart: () => void;\n isAnimating: () => boolean;\n getStartTime: () => number|undefined;\n getElapsedTime: () => number|undefined;\n getPercent: () => number|undefined;\n getResizeObserver: () => ResizeObserver|undefined;\n}\n\nexport const animate = (props: IAnimationProps) : IAnimationResult => {\n\n const _duration = props.duration !== undefined ? props.duration : Infinity;\n\n let startTime: number|undefined = undefined; // in milliseconds\n let animationId: number|undefined = undefined;\n\n // the time elapsed since the start of the animation (in milliseconds)\n let elapsed: number|undefined = undefined;\n let previousTimeStamp: number|undefined = undefined;\n\n let animating = false;\n let observer: ResizeObserver|undefined = undefined;\n\n // -------------------- COMMANDS ---------------------\n\n const stop = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = false;\n\n /*if(observer !== undefined){\n observer.disconnect();\n observer = undefined;\n }*/\n\n if(animationId === undefined) return;\n window.cancelAnimationFrame(animationId);\n };\n\n const restart = () => {\n stop();\n start();\n };\n\n const pause = () => {\n animating = false;\n };\n\n const resume = () => {\n animating = true;\n };\n\n /**\n * Animation Step.\n * @param {number} timeStamp in milliseconds\n */\n const step = (timeStamp: DOMHighResTimeStamp) => {\n\n if (startTime === undefined) {\n startTime = timeStamp;\n }\n\n // the time elapsed since the start of the animation (in milliseconds)\n elapsed = timeStamp - startTime;\n\n if (animating && previousTimeStamp !== timeStamp && typeof props.callback === 'function') {\n\n // do the rendering .............\n props.callback(getResult());\n }\n\n if(elapsed <= _duration){\n previousTimeStamp = timeStamp;\n animationId = window.requestAnimationFrame(step);\n }\n else{\n stop();\n }\n };\n\n const observerHandler = (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => {\n restart();\n\n if(typeof props.resizeCallback === 'function'){\n props.resizeCallback(_entries, _observer);\n }\n };\n\n const start = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = true;\n\n if(props.restartOnResize && window.ResizeObserver && observer === undefined){\n observer = new ResizeObserver(observerHandler);\n observer.observe(document.body, { box: 'border-box' });\n }\n else{\n animationId = window.requestAnimationFrame(step);\n }\n };\n\n // --------------- GET INFO ----------------------\n\n /**\n * the time elapsed since the start of the animation (in milliseconds)\n */\n const getElapsedTime = () : number|undefined => {\n return elapsed;\n };\n\n const isAnimating = () => {\n return animating;\n };\n\n const getStartTime = () => {\n return startTime;\n };\n\n const getPercent = () => {\n if(_duration === Infinity || elapsed === undefined) return undefined;\n return elapsed * 100 / _duration;\n };\n\n const getResizeObserver = () => {\n return observer;\n };\n\n const getResult = () : IAnimationResult => {\n return {\n\n // commands --------------\n start,\n stop,\n pause,\n resume,\n restart,\n\n // information -------\n isAnimating,\n getElapsedTime,\n getStartTime,\n getPercent,\n getResizeObserver,\n };\n };\n\n return getResult();\n};\n", "import { setDecimalPlaces } from './format';\n\nexport const getCircleCircumference = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * radius, decimalPlaces);\n};\n\nexport const getEllipseCircumference = (radius1: number, radius2: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * Math.sqrt((radius1 ** 2 + radius2 ** 2) / 2), decimalPlaces);\n};\n\nexport const isAngleInCircleArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg ||\n (currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg;\n};\n\n/**\n * get the side of a square inscribed in a circle\n */\nexport const getSquareInCircleSide = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(radius * 2 / Math.sqrt(2), decimalPlaces);\n};\n", "import { setDecimalPlaces, Vector2 } from 'mz-math';\n\nexport interface ISvg {\n cx: number;\n cy: number;\n radius: number;\n size: number;\n thickness: number;\n border: number;\n startAngleDeg: number;\n endAngleDeg: number;\n}\n\nexport const getSvg = (\n circleRadius: number,\n circleThickness: number,\n circleBorder: number,\n maxPointerRadius: number,\n startAngleDeg: number,\n endAngleDeg: number\n) : ISvg => {\n\n const thickness = circleThickness + circleBorder * 2;\n\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n const size = circleRadius * 2 + thickness + diff;\n\n const [ cx, cy ] = getSVGCenter(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n return {\n cx,\n cy,\n radius: circleRadius,\n size,\n thickness: circleThickness,\n border: circleBorder,\n startAngleDeg,\n endAngleDeg\n } as ISvg;\n};\n\nconst getSVGCenter = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : Vector2 => {\n\n const size = getSVGSize(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n const val = setDecimalPlaces(size/2, 2);\n\n return [\n val,\n val,\n ];\n};\n\nconst getSVGSize = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : number => {\n const thickness = circleThickness + circleBorder * 2;\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n return circleRadius * 2 + thickness + diff;\n};", "// Data Defaults --------------------\nexport const DEFAULT_MIN = 0;\nexport const DEFAULT_MAX = 100;\nexport const DEFAULT_STEP = 1;\nexport const DEFAULT_ARROW_STEP = 1;\nexport const DEFAULT_ROUND = 0;\n\n// Path Defaults ---------------------\nexport const DEFAULT_PATH_START_ANGLE = 0;\nexport const DEFAULT_PATH_END_ANGLE = 360;\nexport const DEFAULT_PATH_RADIUS = 150;\nexport const DEFAULT_PATH_THICKNESS = 5;\nexport const DEFAULT_PATH_BG_COLOR = '#efefef';\nexport const DEFAULT_PATH_BORDER = 0;\nexport const DEFAULT_PATH_BORDER_COLOR = '#444444';\n\n// Pointer Defaults ------------------\nexport const DEFAULT_POINTER_RADIUS = 10;\nexport const DEFAULT_POINTER_BG_COLOR = '#163a86';\nexport const DEFAULT_POINTER_BG_COLOR_SELECTED = '#000';\nexport const DEFAULT_POINTER_BG_COLOR_DISABLED = '#a8a8a8';\nexport const DEFAULT_POINTER_BORDER = 0;\nexport const DEFAULT_POINTER_BORDER_COLOR = '#000';\n\n// Connection Defaults ------------------\nexport const DEFAULT_CONNECTION_BG_COLOR = '#5daed2';\nexport const DEFAULT_CONNECTION_BG_COLOR_DISABLED = '#97b0bb';\n\n// Text Defaults ------------------------\nexport const DEFAULT_TEXT_COLOR = '#000';\nexport const DEFAULT_TEXT_FONT_SIZE = 16;\n\n// Ticks Defaults -----------------------\nexport const DEFAULT_TICKS_ENABLED = false;\nexport const DEFAULT_TICKS_WIDTH = 3;\nexport const DEFAULT_TICKS_HEIGHT = 10;\nexport const DEFAULT_TICKS_COLOR = '#efefef';\nexport const DEFAULT_TICKS_VALUES_COLOR = '#000';\nexport const DEFAULT_TICKS_VALUES_FONT_SIZE = 12;\nexport const DEFAULT_TICKS_GROUP_SIZE = 10;\nexport const DEFAULT_TICKS_VALUES_DISTANCE = 15;\n\n// Animation Defaults -----------------------\nexport const DEFAULT_ANIMATION_DURATION = 200;\n\n\n", "import { isNumber } from 'mz-math';\n\nexport const getNumber = (value: number|string|undefined|null, defaultValue: number) : number => {\n return isNumber(value) ? Number(value) : defaultValue;\n};\n\nexport const getString = (value: string|undefined|null, defaultValue: string) : string => {\n return value === undefined || value === null ? defaultValue : value;\n};\n\nexport const getBoolean = (value: boolean|undefined|null, defaultValue: boolean) : boolean => {\n return value === undefined || value === null ? defaultValue : value;\n};", "import { mod } from 'mz-math';\n\nexport interface ICircle {\n strokeDasharray: string;\n strokeOffset: number;\n}\n\nexport const isAngleInArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return (currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg) ||\n ((currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg);\n};\n\nexport const getAnglesDistance = (startAngle: number, endAngle: number) => {\n if(endAngle < startAngle) {\n endAngle += 360;\n }\n\n const diff = endAngle - startAngle;\n const diffMod = mod(diff, 360);\n\n return diffMod === 0 && diff > 0 ? 360 : diffMod;\n};\n\nexport const getCircle = (\n startAngleDeg: number,\n endAngleDeg: number,\n radius: number,\n) : ICircle => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n const circumference = 2 * Math.PI * radius;\n const angleDiff = endAngleDeg - startAngleDeg;\n const strokeOffset = -(startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDiff / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n return {\n strokeDasharray: [ strokeDasharray, complement ].join(' '),\n strokeOffset,\n } as ICircle;\n};", "import {\n Vector2,\n convertRange,\n mod,\n setDecimalPlaces,\n v2Sub,\n radiansToDegrees,\n degreesToRadians, circleMovement, v2Distance\n} from 'mz-math';\nimport { ISettings } from './settings-provider';\nimport {\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_POINTER_BG_COLOR,\n DEFAULT_POINTER_BG_COLOR_DISABLED,\n DEFAULT_POINTER_BG_COLOR_SELECTED,\n DEFAULT_POINTER_BORDER,\n DEFAULT_POINTER_BORDER_COLOR,\n DEFAULT_POINTER_RADIUS,\n} from './defaults-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport { IData } from './data-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IPointer {\n id: string;\n index: number;\n radius: number;\n angleDeg: number;\n prevAngleDeg: number;\n\n bgColor: string;\n bgColorSelected: string;\n bgColorDisabled: string;\n bgColorHover: string;\n\n border: number;\n borderColor: string;\n\n disabled: boolean;\n ariaLabel?: string;\n}\n\nexport interface IPointers {\n pointers: IPointer[];\n maxRadius: number;\n}\n\nexport const getAngleByMouse = (\n $svg: SVGSVGElement,\n clientX: number,\n clientY: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number\n) => {\n const { left, top } = $svg.getBoundingClientRect();\n\n const relativeMouse: Vector2 = [\n clientX - left,\n clientY - top,\n ];\n\n const vector = v2Sub(relativeMouse, [ cx, cy ]);\n\n let angleRad = Math.atan2(vector[1] / ry, vector[0] / rx);\n if(angleRad < 0){\n angleRad += 2 * Math.PI;\n }\n\n return radiansToDegrees(angleRad);\n};\n\nexport const angle2value = (data: IData, angle: number, pathStartAngle: number, pathEndAngle: number) : string | number => {\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(angle < pathStartAngle){\n angle += 360;\n }\n\n let value: string|number = convertRange(angle, pathStartAngle, pathEndAngle, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n return value;\n};\n\nconst value2angle = (data: IData, value: string | number, pathStartAngle: number, pathEndAngle: number) => {\n let _value: number;\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(data.data.length > 0) {\n const valueIndex = data.data.findIndex(item => item === value);\n _value = valueIndex === -1 ? 0 : valueIndex;\n }\n else{\n _value = typeof value !== 'number' ? data.min : value;\n }\n\n return mod(convertRange(_value, data.min, data.max, pathStartAngle, pathEndAngle), 360);\n};\n\nconst initPointers = (\n settings: ISettings,\n data: IData\n) : IPointer[] => {\n\n if(!settings || !settings.pointers || settings.pointers.length < 0 || !data) {\n const angleDeg = mod(getNumber(settings.pathStartAngle, DEFAULT_PATH_START_ANGLE), 360);\n\n const bgColor = getString(settings.pointerBgColor, DEFAULT_POINTER_BG_COLOR);\n const bgColorSelected = getString(settings.pointerBgColorSelected, DEFAULT_POINTER_BG_COLOR_SELECTED);\n const bgColorDisabled = getString(settings.pointerBgColorDisabled, DEFAULT_POINTER_BG_COLOR_DISABLED);\n const bgColorHover = getString(settings.pointerBgColorHover, bgColorSelected);\n\n return [{\n id: '0',\n index: 0,\n radius: getNumber(settings.pointerRadius, DEFAULT_POINTER_RADIUS),\n angleDeg,\n prevAngleDeg: angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border: getNumber(settings.pointerBorder, DEFAULT_POINTER_BORDER),\n borderColor: getString(settings.pointerBorderColor, DEFAULT_POINTER_BORDER_COLOR),\n disabled: !!settings.disabled,\n }]\n }\n\n const pointers: IPointer[] = [];\n\n for(let i=0; i {\n\n const pointers = initPointers(settings, data);\n\n return {\n pointers,\n maxRadius: getMaxRadius(pointers),\n }\n};\n\nconst getMaxRadius = (pointers: IPointer[]) : number => {\n if(pointers.length <= 0) return 0;\n\n let max = -Infinity;\n\n for(const pointer of pointers){\n max = Math.max(max, Math.max(0, pointer.radius + pointer.border/2));\n }\n\n return max;\n};\n\nexport const getClosestPointer = (\n pointers: IPointer[],\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n if(!pointers || pointers.length <= 0) return null;\n\n if(pointers.length === 1) return pointers[0];\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n let min: number|undefined = undefined;\n let closestPointer: IPointer = null;\n\n const enabledPointers = pointers.filter(p => !p.disabled);\n\n for(const pointer of enabledPointers) {\n const pointerAngleRad = convertRange(degreesToRadians(pointer.angleDeg), 0, Math.PI * 2, 0, Math.PI);\n const pointOnArc = circleMovement([ cx, cy ], pointerAngleRad, pathRadius);\n const distance = v2Distance(currentPointOnArc, pointOnArc);\n\n if(min === undefined || distance < min) {\n min = distance;\n closestPointer = pointer;\n }\n }\n\n return { ...closestPointer };\n};\n\nexport const getClosestEdge = (\n startAngleDegrees: number,\n endAngleDegrees: number,\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n const startAngleRad = convertRange(degreesToRadians(startAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const startPointOnArc = circleMovement([ cx, cy ], startAngleRad, pathRadius);\n\n const endAngleRad = convertRange(degreesToRadians(endAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const endPointOnArc = circleMovement([ cx, cy ], endAngleRad, pathRadius);\n\n const distance1 = v2Distance(currentPointOnArc, startPointOnArc);\n const distance2 = v2Distance(currentPointOnArc, endPointOnArc);\n\n return distance1 <= distance2 ? startAngleDegrees : endAngleDegrees;\n};\n\nexport const getMinMaxDistancePointers = (pointers: IPointer[], pathStartAngle: number) : [IPointer, IPointer] | null => {\n if(!pointers || pointers.length <= 0) return null;\n\n let minDistance = undefined;\n let maxDistance = undefined;\n let minPointer = null;\n let maxPointer = null;\n\n for(const pointer of pointers) {\n\n const distance = getAnglesDistance(pathStartAngle, pointer.angleDeg);\n\n if(minDistance === undefined || distance < minDistance) {\n minPointer = pointer;\n minDistance = distance;\n }\n\n if(maxDistance === undefined || distance > maxDistance) {\n maxPointer = pointer;\n maxDistance = distance;\n }\n }\n\n if(minPointer === null || maxPointer === null) return null;\n\n return [\n minPointer,\n maxPointer\n ];\n};\n\nexport const roundToStep = (angleDeg: number, step: number, pathStartAngle: number, pathEndAngle: number) : number => {\n if((mod(angleDeg, 360) === mod(pathStartAngle, 360)) ||\n (mod(angleDeg, 360) === mod(pathEndAngle, 360))) return angleDeg;\n return step === 0 ? 0 : Math.round(angleDeg / step) * step;\n};\n", "import { angle2value, getAngleByMouse, getClosestEdge, IPointer } from '../domain/pointers-provider';\nimport {\n useEffect,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n KeyboardEvent,\n useRef, useCallback,\n} from 'react';\nimport { circleMovement, convertRange, degreesToRadians, Vector2 } from 'mz-math';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { isAngleInArc } from '../domain/circle-provider';\nimport { IData } from '../domain/data-provider';\nimport { outlineNoneStyle } from '../domain/style-provider';\nimport { DEFAULT_POINTER_BG_COLOR } from '../domain/defaults-provider';\n\nexport interface IPointerProps {\n settings: ISettings;\n pointer: IPointer;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst getPointerFill = (\n pointer: IPointer,\n selectedPointerId: string,\n bgColor: string,\n bgColorSelected: string,\n bgColorDisabled: string,\n bgColorHover: string,\n isMouseOver: boolean\n) => {\n if(pointer.disabled) return bgColorDisabled;\n\n if(isMouseOver) return bgColorHover;\n\n if(pointer.id === selectedPointerId) {\n return bgColorSelected;\n }\n\n return bgColor;\n};\n\nconst Pointer = (props: IPointerProps) => {\n\n const pointerRef = useRef(null);\n\n const {\n pointer, svg, $svg, data, settings,\n setPointer, selectedPointerId,\n } = props;\n\n const {\n radius,\n angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border,\n borderColor,\n } = props.pointer;\n\n const { cx, cy } = svg;\n\n const [ center, setCenter ] = useState(null);\n const [ value, setValue ] = useState('');\n const [ fill, setFill ] = useState(DEFAULT_POINTER_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n useEffect(() => {\n setFill(getPointerFill(\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ));\n }, [\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ]);\n\n useEffect(() => {\n const value = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n setValue(value === undefined ? '' : value.toString())\n }, [\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const angleRad = convertRange(degreesToRadians(angleDeg), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const pointerCenter = circleMovement([cx, cy], angleRad, svg.radius);\n setCenter(pointerCenter);\n }, [\n angleDeg,\n cx,\n cy,\n svg.radius,\n ]);\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent | TouchEvent | ReactTouchEvent) => {\n if(!$svg || settings.disabled || pointer.disabled) return;\n\n const mouseX = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientX : (evt as TouchEvent).touches[0].clientX;\n const mouseY = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientY : (evt as TouchEvent).touches[0].clientY;\n\n const degrees = getAngleByMouse(\n $svg,\n mouseX,\n mouseY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n let newAngleDeg;\n\n if(!isAngleInArc(\n svg.startAngleDeg,\n svg.endAngleDeg,\n degrees\n )){\n newAngleDeg = getClosestEdge(\n svg.startAngleDeg,\n svg.endAngleDeg,\n pointer.angleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n else{\n newAngleDeg = degrees;\n }\n\n setPointer(pointer, newAngleDeg);\n }, [\n $svg,\n pointer,\n setPointer,\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n settings.disabled,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n const onKeyDown = (evt: KeyboardEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.keyboardDisabled) return;\n\n switch (evt.key) {\n case 'ArrowLeft': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowRight': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowUp': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowDown': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n }\n };\n\n useEffect(() => {\n const $current = pointerRef.current;\n\n const onTouch = (evt: TouchEvent | ReactTouchEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n onValueChange(evt);\n };\n\n const onWheel = (evt: WheelEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.mousewheelDisabled || document.activeElement !== $current) return;\n\n evt.stopPropagation();\n evt.preventDefault();\n\n const scrollTop = evt.deltaY < 0;\n\n let newAngleDeg;\n if(scrollTop) {\n newAngleDeg = pointer.angleDeg + data.arrowStepAngleDeg;\n }\n else{\n newAngleDeg = pointer.angleDeg - data.arrowStepAngleDeg;\n }\n\n setPointer(pointer, newAngleDeg);\n };\n\n $current?.addEventListener('touchmove', onTouch, {\n passive: false,\n });\n\n document.addEventListener('wheel', onWheel, {\n passive: false,\n });\n\n return () => {\n $current?.removeEventListener('touchmove', onTouch);\n document.removeEventListener('wheel', onWheel);\n };\n }, [\n center,\n onValueChange,\n data.arrowStepAngleDeg,\n pointer,\n setPointer,\n settings.disabled,\n settings.mousewheelDisabled,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n center &&\n \n\n {\n !settings.pointerSVG &&\n \n }\n\n {\n settings.pointerSVG &&\n \n { settings.pointerSVG }\n \n }\n \n }\n \n )\n};\n\nexport default Pointer;", "export const outlineNoneStyle = {\n outline: 'none',\n};", "import { IPointer, IPointers } from '../domain/pointers-provider';\nimport Pointer from './Pointer';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\nexport interface IPointersProps {\n pointers: IPointers;\n settings: ISettings;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst Pointers = (props: IPointersProps) => {\n\n const {\n pointers, settings, svg, $svg, data,\n setPointer, selectedPointerId,\n } = props;\n\n return (\n <>\n {\n pointers.pointers.map(pointer => {\n\n return (\n \n )\n })\n }\n \n )\n};\n\nexport default Pointers;", "import { ISettings } from './settings-provider';\nimport { getNumber } from './common-provider';\nimport {\n DEFAULT_ARROW_STEP,\n DEFAULT_MAX,\n DEFAULT_MIN,\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_ROUND,\n DEFAULT_STEP\n} from './defaults-provider';\nimport { mod } from 'mz-math';\n\nexport interface IData {\n min: number;\n max: number;\n stepAngleDeg: number;\n arrowStepAngleDeg: number;\n round: number;\n data: (string | number)[];\n isClosedShape: boolean;\n}\n\nexport const getData = (setting: ISettings) : IData => {\n\n let min = getNumber(setting.min, DEFAULT_MIN);\n let max = getNumber(setting.max, DEFAULT_MAX);\n const step = getNumber(setting.step, DEFAULT_STEP);\n const arrowStep = getNumber(setting.arrowStep, DEFAULT_ARROW_STEP);\n const round = getNumber(setting.round, DEFAULT_ROUND);\n const data = setting.data || [];\n\n if(data.length > 0) {\n const minIndex = data.findIndex(item => item === min);\n const maxIndex = data.findIndex(item => item === max);\n\n min = minIndex === -1 ? 0 : minIndex;\n max = maxIndex === -1 ? data.length : maxIndex;\n }\n else{\n if(min > max) {\n min = max + DEFAULT_MAX;\n }\n }\n\n const pathStartAngle = getNumber(setting.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n const pathEndAngle = getNumber(setting.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n const isClosedShape = mod(pathStartAngle, 360) === mod(pathEndAngle, 360);\n\n const stepAngleDeg = step * 360 / (max - min);\n const arrowStepAngleDeg = arrowStep * 360 / (max - min);\n\n return {\n min,\n max,\n round,\n data,\n stepAngleDeg,\n arrowStepAngleDeg,\n isClosedShape,\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_CONNECTION_BG_COLOR,\n DEFAULT_CONNECTION_BG_COLOR_DISABLED\n} from '../domain/defaults-provider';\nimport {\n getAngleByMouse,\n getClosestPointer,\n getMinMaxDistancePointers,\n IPointer,\n IPointers\n} from '../domain/pointers-provider';\nimport {\n MouseEvent as ReactMouseEvent,\n useCallback,\n useEffect, useRef,\n useState\n} from 'react';\nimport { getConnection, IConnection } from '../domain/connection-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\nimport { animate, IAnimationResult, mod } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\n\ninterface IConnectionProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst getStroke = (\n disabled: boolean,\n connectionBgColorDisabled: string,\n connectionBgColor: string,\n isMouseOver: boolean,\n connectionBgColorHover: string\n) => {\n if(disabled) return getString(connectionBgColorDisabled, DEFAULT_CONNECTION_BG_COLOR_DISABLED);\n\n const bgColor = getString(connectionBgColor, DEFAULT_CONNECTION_BG_COLOR);\n\n if(isMouseOver) {\n return getString(connectionBgColorHover, bgColor);\n }\n\n return bgColor;\n};\n\nconst Connection = (props: IConnectionProps) => {\n\n const { settings, pointers, $svg, svg, data, setPointer } = props;\n\n const [ connection, setConnection ] = useState(null);\n const [ animation, setAnimation ] = useState(null);\n const [ stroke, setStroke ] = useState(DEFAULT_CONNECTION_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n const rangeDraggingLastAngle = useRef();\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setStroke(getStroke(\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n isMouseOver,\n settings.connectionBgColorHover\n ));\n }, [\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n settings.connectionBgColorHover,\n isMouseOver,\n ]);\n\n useEffect(() => {\n setConnection(getConnection(\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n }, [\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ]);\n\n const onClick = (evt: ReactMouseEvent) => {\n\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // RANGE DRAGGING -------------------------------------------\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent) => {\n if(!$svg || settings.disabled || !settings.rangeDragging) return;\n\n const minMaxResult = getMinMaxDistancePointers(pointers.pointers, svg.startAngleDeg);\n if(!minMaxResult) return;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n const mouseDegrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n if(rangeDraggingLastAngle.current === undefined) {\n rangeDraggingLastAngle.current = mouseDegrees;\n return;\n }\n\n const diff = (mouseDegrees - rangeDraggingLastAngle.current);\n if(diff === 0 || Math.abs(diff) < data.stepAngleDeg) return;\n\n setPointer(minPointer, mod(minPointer.angleDeg + diff, 360));\n setPointer(maxPointer, mod(maxPointer.angleDeg + diff, 360));\n\n rangeDraggingLastAngle.current = mouseDegrees;\n }, [\n $svg,\n svg.cx,\n svg.cy,\n svg.radius,\n data.stepAngleDeg,\n pointers.pointers,\n setPointer,\n settings.disabled,\n settings.rangeDragging,\n svg.startAngleDeg,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n\n rangeDraggingLastAngle.current = undefined;\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(!settings.rangeDragging || settings.disabled || pointers.pointers.length <= 1) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n !getBoolean(settings.hideConnection, false) && connection &&\n \n }\n \n )\n};\n\nexport default Connection;", "import { IPointers } from './pointers-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IConnection {\n radius: number;\n cx: number;\n cy: number;\n\n // calculated properties ---------\n startAngleDeg: number;\n endAngleDeg: number;\n strokeDasharray: number[];\n strokeOffset: number;\n}\n\nexport const getConnection = (\n pointers: IPointers,\n radius: number,\n cx: number,\n cy: number,\n pathStartAngle: number,\n pathEndAngle: number,\n) : IConnection => {\n\n if(!pointers.pointers || pointers.pointers.length <= 0) return null;\n\n const result : IConnection = {\n radius,\n cx,\n cy,\n\n // calculated properties ---------\n startAngleDeg: pathStartAngle,\n endAngleDeg: pathStartAngle,\n strokeDasharray: [0, 0],\n strokeOffset: 0,\n };\n\n // Define start/end angles.\n if(pointers.pointers.length === 1) {\n result.startAngleDeg = pathStartAngle;\n result.endAngleDeg = pointers.pointers[0].angleDeg;\n }\n else{\n result.startAngleDeg = pointers.pointers[0].angleDeg;\n result.endAngleDeg = pointers.pointers[pointers.pointers.length - 1].angleDeg;\n\n /*const minMaxResult = getMinMaxDistancePointers(pointers.pointers, pathStartAngle);\n if(!minMaxResult) return null;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n result.startAngleDeg = minPointer.angleDeg;\n result.endAngleDeg = maxPointer.angleDeg;*/\n }\n\n const pathAnglesDistance = getAnglesDistance(pathStartAngle, pathEndAngle);\n\n if(result.startAngleDeg > result.endAngleDeg) {\n result.endAngleDeg += 360;\n }\n\n let angleDistance = getAnglesDistance(result.startAngleDeg, result.endAngleDeg);\n\n const shouldSwitch = angleDistance > pathAnglesDistance;\n\n if(shouldSwitch) {\n angleDistance = 360 - angleDistance;\n [result.startAngleDeg, result.endAngleDeg] = [result.endAngleDeg, result.startAngleDeg];\n }\n\n const circumference = 2 * Math.PI * radius;\n const strokeOffset = -(result.startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDistance / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n result.strokeDasharray = [ strokeDasharray, complement ];\n result.strokeOffset = strokeOffset;\n\n return result;\n};", "import { IAnimationResult, mod } from 'mz-math';\n\nexport const getAnimationProgressAngle = (\n progress: IAnimationResult,\n animationSourceDegrees: number,\n animationTargetDegrees: number,\n startPathAngleDeg: number\n) => {\n let percent = progress.getPercent();\n\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n let angle1 = animationSourceDegrees % 360;\n let angle2 = animationTargetDegrees % 360;\n\n if(angle1 < startPathAngleDeg) {\n angle1 += 360;\n }\n\n if(angle2 < startPathAngleDeg) {\n angle2 += 360;\n }\n\n const isClockwise = angle2 > angle1;\n\n if(isClockwise) {\n const clockwiseDistance = (angle2 - angle1 + 360) % 360;\n return mod(animationSourceDegrees + (percent * clockwiseDistance / 100), 360);\n }\n else {\n const counterclockwiseDistance = (angle1 - angle2 + 360) % 360;\n return mod(animationSourceDegrees - (percent * counterclockwiseDistance / 100), 360);\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { angle2value, IPointers } from '../domain/pointers-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE\n} from '../domain/defaults-provider';\nimport { useEffect, useState } from 'react';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITextProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n data: IData;\n}\n\nconst Text = (props: ITextProps) => {\n\n const { settings, pointers, svg, data } = props;\n\n const { cx, cy } = svg;\n const [ value, setValue ] = useState('');\n\n useEffect(() => {\n\n const values = pointers.pointers.map(pointer => angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n\n values.sort((value1, value2) => {\n return value1.toString().localeCompare(\n value2.toString(),\n 'en',\n { numeric: true }\n );\n });\n\n const texts = values.map(value => `${ settings.textPrefix || '' }${ value }${ settings.textSuffix || '' }`);\n\n const textBetween = getString(settings.textBetween, ' ');\n setValue(texts.join(textBetween));\n\n }, [\n data,\n pointers.pointers,\n svg.startAngleDeg,\n svg.endAngleDeg,\n settings.textPrefix,\n settings.textSuffix,\n settings.textBetween,\n ]);\n\n const hideText = getBoolean(settings.hideText, false);\n\n return (\n <>\n {\n !hideText &&\n \n\n { value }\n\n \n }\n \n )\n};\n\nexport default Text;", "import { useEffect, useState, Fragment } from 'react';\nimport { getTicks, getTicksSettings, ITick, ITicks } from '../domain/ticks-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITicksProps {\n settings: ISettings;\n svg: ISvg;\n data: IData;\n}\n\nconst Ticks = (props: ITicksProps) => {\n\n const { settings, svg, data } = props;\n\n const [ ticksSettings, setTicksSettings ] = useState(null);\n const [ ticks, setTicks ] = useState([]);\n\n useEffect(() => {\n setTicksSettings(getTicksSettings(settings, data));\n }, [\n settings,\n data,\n ]);\n\n useEffect(() => {\n if(!ticksSettings) return;\n\n let endAngleDeg = svg.endAngleDeg;\n if(endAngleDeg < svg.startAngleDeg) {\n endAngleDeg += 360;\n }\n\n setTicks(getTicks(\n ticksSettings,\n ticksSettings.ticksCount,\n svg.startAngleDeg,\n endAngleDeg,\n svg,\n data\n ));\n }, [\n data,\n svg,\n ticksSettings,\n ]);\n\n return (\n <>\n {\n ticksSettings && ticksSettings.enableTicks &&\n \n {\n ticks.map((tick, i) => {\n const { x, y, x1, y1, textX, textY, showText } = tick;\n\n return (\n \n \n\n {\n showText &&\n \n { settings.tickValuesPrefix }{ tick.tickValue }{ settings.tickValuesSuffix }\n \n }\n \n );\n })\n }\n \n }\n \n )\n};\n\nexport default Ticks;", "import {\n circleMovement,\n convertRange,\n degreesToRadians,\n setDecimalPlaces,\n v2MulScalar,\n v2Normalize\n} from 'mz-math';\nimport { ISvg } from './svg-provider';\nimport { IData } from './data-provider';\nimport { ISettings } from './settings-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport {\n DEFAULT_TICKS_COLOR, DEFAULT_TICKS_ENABLED, DEFAULT_TICKS_GROUP_SIZE,\n DEFAULT_TICKS_HEIGHT, DEFAULT_TICKS_VALUES_COLOR,\n DEFAULT_TICKS_VALUES_DISTANCE, DEFAULT_TICKS_VALUES_FONT_SIZE,\n DEFAULT_TICKS_WIDTH\n} from './defaults-provider';\n\nexport interface ITicks {\n ticksCount: number;\n enableTicks: boolean;\n ticksWidth: number;\n ticksHeight: number;\n longerTicksHeight: number;\n ticksDistanceToPanel: number;\n tickValuesDistance: number;\n ticksColor: string;\n tickValuesColor: string;\n tickValuesFontSize: number;\n ticksGroupSize: number;\n longerTickValuesOnly: boolean;\n showTickValues: boolean;\n}\n\nexport interface ITick {\n x: number;\n y: number;\n x1: number;\n y1: number;\n textX: number;\n textY: number;\n isLonger: boolean;\n showText: boolean;\n tickValue?: string;\n}\n\nexport const getTicksSettings = (settings: ISettings, data: IData) : ITicks => {\n\n let ticksCount = getNumber(settings.ticksCount, 0);\n if(!ticksCount) {\n if(data.data && data.data.length > 0) {\n ticksCount = data.data.length;\n }\n else{\n ticksCount = data.max;\n }\n }\n\n const ticksHeight = getNumber(settings.ticksHeight, DEFAULT_TICKS_HEIGHT);\n\n return {\n ticksCount,\n enableTicks: getBoolean(settings.enableTicks, DEFAULT_TICKS_ENABLED),\n ticksWidth: getNumber(settings.ticksWidth, DEFAULT_TICKS_WIDTH),\n ticksHeight,\n longerTicksHeight: getNumber(settings.longerTicksHeight, ticksHeight * 2),\n ticksDistanceToPanel: getNumber(settings.ticksDistanceToPanel, 0),\n tickValuesDistance: getNumber(settings.tickValuesDistance, DEFAULT_TICKS_VALUES_DISTANCE),\n ticksColor: getString(settings.ticksColor, DEFAULT_TICKS_COLOR),\n tickValuesColor: getString(settings.tickValuesColor, DEFAULT_TICKS_VALUES_COLOR),\n tickValuesFontSize: getNumber(settings.tickValuesFontSize, DEFAULT_TICKS_VALUES_FONT_SIZE),\n ticksGroupSize: getNumber(settings.ticksGroupSize, DEFAULT_TICKS_GROUP_SIZE),\n longerTickValuesOnly: getBoolean(settings.longerTickValuesOnly, true),\n showTickValues: getBoolean(settings.showTickValues, true),\n };\n};\n\nexport const getTicks = (\n ticksSettings: ITicks,\n ticksCount: number,\n pathStartAngle: number,\n pathEndAngle: number,\n svg: ISvg,\n data: IData\n) : ITick[] => {\n\n const ticks: ITick[] = [];\n\n const deltaAngle = Math.abs(pathEndAngle - pathStartAngle);\n const oneTickAngleSize = ticksCount === 0 ? 0 : deltaAngle / ticksCount;\n\n let count = ticksCount;\n if(!data.isClosedShape) {\n count++;\n }\n\n for(let i=0; i [0, Math.PI]\n\n let [x, y] = circleMovement([svg.cx, svg.cy], angleRad, svg.radius);\n\n const isLonger = ticksSettings.ticksGroupSize !== undefined && (i % ticksSettings.ticksGroupSize === 0 );\n\n let desiredDistance = ticksSettings.ticksHeight;\n\n if(isLonger) {\n desiredDistance = ticksSettings.longerTicksHeight;\n }\n\n const normalizedDirectionVector = v2Normalize([svg.cx - x, svg.cy - y]);\n const tickEndVector = v2MulScalar(normalizedDirectionVector, desiredDistance);\n\n const tickStartVector = v2MulScalar(normalizedDirectionVector, ticksSettings.ticksDistanceToPanel + svg.thickness/2);\n x += tickStartVector[0];\n y += tickStartVector[1];\n\n const x1 = x + tickEndVector[0];\n const y1 = y + tickEndVector[1];\n\n // ------- Define tick value. ---------------------\n let tickValue: string|undefined = undefined;\n if(ticksSettings.showTickValues && (!ticksSettings.longerTickValuesOnly || ticksSettings.longerTickValuesOnly && (isLonger || ticksSettings.ticksGroupSize === undefined))) {\n\n let value: string|number = convertRange(i, 0, ticksCount, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n tickValue = (value ?? '').toString();\n }\n\n let textX = 0;\n let textY = 0;\n const showText = tickValue !== undefined;\n\n if(showText) {\n const _tickValuesDistance = getNumber(desiredDistance + ticksSettings.tickValuesDistance, desiredDistance * 1.5);\n const tickTextVector = v2MulScalar(normalizedDirectionVector, _tickValuesDistance);\n textX = x + tickTextVector[0];\n textY = y + tickTextVector[1];\n }\n\n ticks.push({\n x,\n y,\n x1,\n y1,\n textX,\n textY,\n isLonger,\n tickValue,\n showText,\n });\n }\n\n return ticks;\n};", "import { useEffect, useState, MouseEvent, useRef } from 'react';\nimport { getCircle, ICircle } from '../domain/circle-provider';\nimport { getNumber, getString } from '../domain/common-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_PATH_BG_COLOR,\n DEFAULT_PATH_BORDER_COLOR,\n} from '../domain/defaults-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { getAngleByMouse, getClosestPointer, IPointer, IPointers } from '../domain/pointers-provider';\nimport { animate, IAnimationResult, newId } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\nimport InnerCircle from './InnerCircle';\n\ninterface ICircleProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst Circle = (props: ICircleProps) => {\n\n const { settings, pointers, $svg, svg, setPointer } = props;\n\n const [ animation, setAnimation ] = useState(null);\n const [ maskId ] = useState(newId());\n const [ circle, setCircle ] = useState({\n strokeDasharray: '0 1000000',\n strokeOffset: 0,\n });\n\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setCircle(getCircle(\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius\n ));\n }, [\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius,\n ]);\n\n const onClick = (evt: MouseEvent) => {\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n return (\n \n\n {\n settings.pathInnerBgColor &&\n \n }\n\n {\n svg.border > 0 &&\n \n }\n\n \n \n )\n};\n\nexport default Circle;\n", "import { ISvg } from '../domain/svg-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ICircle } from '../domain/circle-provider';\nimport { useEffect, useState } from 'react';\nimport { circleMovement, convertRange, degreesToRadians, mod, Vector2 } from 'mz-math';\nimport { getBoolean } from '../domain/common-provider';\n\ninterface IInnerCircleProps {\n maskId: string;\n settings: ISettings;\n svg: ISvg;\n circle: ICircle;\n}\n\nconst InnerCircle = (props: IInnerCircleProps) => {\n\n const { svg, maskId, settings, circle } = props;\n\n const [ startPoint, setStartPoint ] = useState([0, 0]);\n const [ endPoint, setEndPoint ] = useState([0, 0]);\n const [ largeArcFlag, setLargeArcFlag ] = useState(0);\n const [ pathInnerBgFull, setPathInnerBgFull] = useState(false);\n\n useEffect(() => {\n if(mod(svg.startAngleDeg, 360) === mod(svg.endAngleDeg, 360)) {\n setPathInnerBgFull(true);\n return;\n }\n\n setPathInnerBgFull(getBoolean(settings.pathInnerBgFull, false));\n }, [\n settings.pathInnerBgFull,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const startAngleDeg = convertRange(svg.startAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setStartPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(startAngleDeg), svg.radius));\n\n const endAngleDeg = convertRange(svg.endAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setEndPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(endAngleDeg), svg.radius));\n\n const largeArcFlag = svg.endAngleDeg - svg.startAngleDeg <= 180 ? 1 : 0;\n setLargeArcFlag(largeArcFlag);\n }, [\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n ]);\n\n return (\n <>\n {\n !pathInnerBgFull &&\n \n \n \n \n }\n\n \n \n )\n};\n\nexport default InnerCircle;"], - "mappings": "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", + "sourcesContent": ["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1 {\n\n const [ data, setData ] = useState(null);\n const [ svg, setSvg ] = useState(null);\n const [ pointers, setPointers ] = useState(null);\n const [ selectedPointerId, setSelectedPointerId ] = useState('');\n\n const prevAngleDegRef = useRef(null);\n const svgRef = useRef(null);\n\n useEffect(() => {\n const _data = getData(props);\n const hasChanged = JSON.stringify(data) !== JSON.stringify(_data);\n if(!hasChanged) return;\n\n setData(_data);\n }, [\n data,\n props\n ]);\n\n useEffect(() => {\n setPointers(getPointers(props, data));\n },\n // eslint-disable-next-line\n [\n props.pointerRadius,\n props.pathStartAngle,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pointers,\n props.pointerRadius,\n props.pointerBgColor,\n props.pointerBgColorSelected,\n props.pointerBgColorDisabled,\n props.pointerBorder,\n props.pointerBorderColor,\n props.disabled,\n props.pathStartAngle,\n props.pathEndAngle,\n data,\n ]);\n\n useEffect(() => {\n if(!pointers) return;\n\n const pathStartAngle = getNumber(props.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n let pathEndAngle = getNumber(props.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n\n if(pathEndAngle <= pathStartAngle) {\n pathEndAngle += 360;\n }\n\n setSvg(getSvg(\n getNumber(props.pathRadius, DEFAULT_PATH_RADIUS),\n getNumber(props.pathThickness, DEFAULT_PATH_THICKNESS),\n getNumber(props.pathBorder, DEFAULT_PATH_BORDER),\n pointers.maxRadius,\n pathStartAngle,\n pathEndAngle,\n ));\n }, [\n props.pathRadius,\n props.pathThickness,\n props.pathBorder,\n props.pathStartAngle,\n props.pathEndAngle,\n pointers,\n ]);\n\n useEffect(() => {\n const clearSelectedPointer = (evt: MouseEvent) => {\n const $target = evt.target as HTMLElement;\n const $pointer = $target.closest('[data-type=\"pointer\"]');\n if($pointer) return;\n\n setSelectedPointerId('');\n };\n\n document.addEventListener('mousedown', clearSelectedPointer);\n\n return () => {\n document.removeEventListener('mousedown', clearSelectedPointer);\n };\n }, []);\n\n const setPointersCallback = (pointer: IPointer, newAngleDeg: number) => {\n if(props.disabled || !pointers.pointers || !pointer || pointer.disabled) return;\n\n newAngleDeg = roundToStep(newAngleDeg, data.stepAngleDeg, svg.startAngleDeg, svg.endAngleDeg);\n if(data.isClosedShape && mod(newAngleDeg, 360) === mod(svg.endAngleDeg, 360)){\n newAngleDeg = svg.startAngleDeg;\n }\n\n if(pointer.angleDeg === newAngleDeg){\n updatePointer(pointer, newAngleDeg, false);\n return;\n }\n\n const handleOverlap = !props.pointersOverlap;\n if(handleOverlap) {\n\n let prevAngle, nextAngle;\n\n if(data.isClosedShape) {\n const prevIndex = mod(pointer.index - 1, pointers.pointers.length);\n const nextIndex = mod(pointer.index + 1, pointers.pointers.length);\n\n const prevPointer = pointers.pointers[prevIndex];\n const nextPointer = pointers.pointers[nextIndex];\n\n prevAngle = prevPointer.angleDeg;\n nextAngle = nextPointer.angleDeg;\n\n if(pointers.pointers.length === 2 && (prevAngle === nextAngle)) {\n\n const splitPointDeg = prevAngle; // === nextAngle\n\n if(prevAngleDegRef.current === null) {\n prevAngleDegRef.current = newAngleDeg;\n }\n else{\n // Clockwise: new angle in (splitPointDeg, splitPointDeg + 90]\n // Clockwise: prev angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: new angle in [splitPointDeg - 90, splitPointDeg)\n // CounterClockwise: prev angle in (splitPointDeg, splitPointDeg + 90]\n\n const SAFE_ANGLE = 150;\n\n let t1 = splitPointDeg - SAFE_ANGLE;\n let t2 = splitPointDeg - 0.001;\n\n if(t1 < 0) t1 += 360;\n if(t2 < 0) t2 += 360;\n\n const clockwiseNew = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, newAngleDeg);\n const clockwisePrev = isAngleInArc(t1, t2, prevAngleDegRef.current);\n const clockwise = clockwiseNew && clockwisePrev;\n\n let t3 = splitPointDeg - SAFE_ANGLE;\n let t4 = splitPointDeg - 0.001;\n\n if(t3 < 0) t3 += 360;\n if(t4 < 0) t4 += 360;\n\n const counterClockwiseNew = isAngleInArc(t3, t4, newAngleDeg);\n const counterClockwisePrev = isAngleInArc(splitPointDeg + 0.001, splitPointDeg + SAFE_ANGLE, prevAngleDegRef.current);\n const counterClockwise = counterClockwiseNew && counterClockwisePrev;\n\n if(clockwise || counterClockwise) {\n updatePointer(pointer, splitPointDeg, true);\n return;\n }\n\n if(newAngleDeg !== splitPointDeg) {\n prevAngleDegRef.current = newAngleDeg;\n }\n }\n }\n }\n else{\n prevAngle = pointer.index === 0 ? svg.startAngleDeg : pointers.pointers[pointer.index - 1].angleDeg;\n nextAngle = pointer.index === pointers.pointers.length - 1 ? svg.endAngleDeg : pointers.pointers[pointer.index + 1].angleDeg;\n }\n\n if(nextAngle <= prevAngle) {\n nextAngle += 360;\n }\n else{\n if(mod(prevAngle, 360) <= mod(nextAngle, 360)) {\n prevAngle = mod(prevAngle, 360);\n nextAngle = mod(nextAngle, 360);\n }\n }\n\n if(!isAngleInArc(prevAngle, nextAngle, newAngleDeg)){\n newAngleDeg = getClosestEdge(\n prevAngle,\n nextAngle,\n newAngleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n }\n\n updatePointer(pointer, newAngleDeg, pointer.angleDeg !== newAngleDeg);\n };\n\n const updatePointer = (pointer: IPointer, newAngleDeg: number, angleChanged: boolean) => {\n\n if(angleChanged) {\n const _pointers = { ...pointers };\n _pointers.pointers = [...pointers.pointers];\n _pointers.pointers[pointer.index].prevAngleDeg = _pointers.pointers[pointer.index].angleDeg;\n _pointers.pointers[pointer.index].angleDeg = newAngleDeg;\n pointers.pointers = _pointers.pointers;\n\n setPointers(_pointers);\n\n if(typeof props.onChange === 'function') {\n\n const updatedPointers: ISettingsPointer[] = _pointers.pointers.map(pointer => {\n\n const val = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n\n return {\n radius: pointer.radius,\n value: val,\n bgColor: pointer.bgColor,\n bgColorSelected: pointer.bgColorSelected,\n bgColorDisabled: pointer.bgColorDisabled,\n border: pointer.border,\n borderColor: pointer.borderColor,\n disabled: pointer.disabled,\n ariaLabel: pointer.ariaLabel,\n };\n });\n\n props.onChange(updatedPointers);\n }\n }\n\n setSelectedPointerId(pointer.id);\n\n const $pointer = svgRef.current?.querySelector(`[data-id=\"${ pointer.id }\"]`) as HTMLElement;\n if($pointer) {\n $pointer.focus();\n }\n };\n\n return (\n <>\n {\n svg &&\n \n\n {\n (props.SvgDefs) &&\n \n { props.SvgDefs }\n \n }\n\n \n\n \n\n \n\n \n\n \n \n }\n \n )\n};", "export const setDecimalPlaces = (num: number, decimalPlaces: number | undefined = Infinity) => {\n if(decimalPlaces === Infinity) return num;\n\n if(decimalPlaces < 0){\n decimalPlaces = 0;\n }\n\n const coefficient = 10 ** decimalPlaces;\n return Math.round(num * coefficient) / coefficient;\n};", "import { Vector2 } from '../types';\nimport { setDecimalPlaces } from './format';\n\nexport const mod = (n: number, m: number) => {\n return ((n % m) + m) % m;\n};\n\n/**\n * Convert range [a, b] to [c, d].\n * f(x) = (d - c) * (x - a) / (b - a) + c\n */\nexport const convertRange = (x: number, a: number, b: number, c: number, d: number) => {\n return (d - c) * (x - a) / (b - a) + c;\n};\n\n/**\n * Check if 2 ranges [a,b] and [c,d] overlap.\n */\nexport const doRangesOverlap = (a: number, b: number, c: number, d: number) => {\n return Math.max(a, c) <= Math.min(b, d) ;\n};\n\n// eslint-disable-next-line\nexport const isNumber = (value: any) => {\n return !isNaN(parseFloat(value)) && isFinite(value);\n};\n\n/**\n * Convert polar coordinates to cartesian coordinates.\n */\nexport const polarToCartesian = (center: Vector2, radii: Vector2, angleInRad: number, decimalPlaces = Infinity) : Vector2 => {\n const [cx, cy] = center;\n const [rx, ry] = radii;\n\n return [\n setDecimalPlaces(cx + (rx * Math.cos(angleInRad)), decimalPlaces),\n setDecimalPlaces(cy + (ry * Math.sin(angleInRad)), decimalPlaces),\n ];\n};", "import { Vector, Vector2, Vector3 } from '../types';\nimport { setDecimalPlaces } from './format';\nimport { v2Length, vNormalize, vDotProduct, vSub } from './linear-algebra/vector';\nimport { mod } from './other';\n\nexport const getV2Angle = (v2: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1], v2[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleInEllipse = (v2: Vector2, radii: Vector2, decimalPlaces = Infinity) => {\n const angle = Math.atan2(v2[1]/radii[1], v2[0]/radii[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const setV2Angle = (v2: Vector2, newAngleRad: number, decimalPlaces = Infinity): Vector2 => {\n const length = v2Length(v2);\n return [\n setDecimalPlaces(Math.cos(newAngleRad) * length, decimalPlaces),\n setDecimalPlaces(Math.sin(newAngleRad) * length, decimalPlaces),\n ];\n};\n\nexport const radiansToDegrees = (radians: number, decimalPlaces = Infinity) => {\n const res = radians * (180 / Math.PI);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\nexport const degreesToRadians = (degrees: number, decimalPlaces = Infinity) => {\n const res = degrees * (Math.PI / 180);\n return setDecimalPlaces(res, decimalPlaces);\n};\n\n/**\n * Returns the range [0, Math.PI]\n * A = Math.acos( dot(v1, v2)/(v1.length()*v2.length()) );\n */\nexport const getVNAngleBetween = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n const unitVector1 = vNormalize(vector1);\n const unitVector2 = vNormalize(vector2);\n const dotProduct = vDotProduct(unitVector1, unitVector2);\n const angle = Math.acos(dotProduct);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV2AngleBetween = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) : number => {\n // return getVNAngleBetween(vector1, vector2, decimalPlaces);\n const diff = vSub(vector1, vector2);\n const angle = Math.atan2(diff[1], diff[0]);\n return setDecimalPlaces(angle, decimalPlaces);\n};\n\nexport const getV3AngleBetween = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return getVNAngleBetween(vector1, vector2, decimalPlaces);\n};\n\nexport const isAngleBetween = (angleDegrees: number, startAngleDegrees: number, endAngleDegrees: number) : boolean => {\n const distance = getAnglesSub(startAngleDegrees, endAngleDegrees);\n const distance1 = getAnglesSub(startAngleDegrees, angleDegrees);\n const distance2 = getAnglesSub(endAngleDegrees, angleDegrees);\n const totalDistance = distance1 + distance2;\n\n // Use a small threshold for floating point errors\n return Math.abs(totalDistance - distance) <= 0.001;\n}\n\nexport const isClockwise = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n return angle2Deg >= angle1Deg;\n};\n\n/**\n * Shortest distance (angular) between two angles.\n */\nexport const getAnglesSub = (angleDegrees1: number, angleDegrees2: number, decimalPlaces = Infinity) : number => {\n const angleDistance = Math.abs(mod(angleDegrees1, 360) - mod(angleDegrees2, 360));\n return setDecimalPlaces(angleDistance <= 180 ? angleDistance : 360 - angleDistance, decimalPlaces);\n};\n\nexport const getAnglesDistance = (angle1Deg: number, angle2Deg: number, startAngleDeg = 0, decimalPlaces = Infinity) => {\n angle1Deg = angle1Deg % 360;\n angle2Deg = angle2Deg % 360;\n\n if(angle1Deg < startAngleDeg) {\n angle1Deg += 360;\n }\n\n if(angle2Deg < startAngleDeg) {\n angle2Deg += 360;\n }\n\n if(isClockwise(angle1Deg, angle2Deg, startAngleDeg)) {\n return setDecimalPlaces((angle2Deg - angle1Deg + 360) % 360, decimalPlaces);\n }\n else{\n return setDecimalPlaces((angle1Deg - angle2Deg + 360) % 360, decimalPlaces);\n }\n};\n\nexport const percentToAngle = (percent: number, startAngleDeg: number, endAngleDeg: number, circleStartAngle = 0) => {\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n const distance = getAnglesDistance(startAngleDeg, endAngleDeg, circleStartAngle);\n\n const clockwise = isClockwise(startAngleDeg, endAngleDeg, circleStartAngle);\n if(clockwise) {\n return mod(circleStartAngle + (percent * distance / 100), 360);\n }\n else {\n return mod(circleStartAngle - (percent * distance / 100), 360);\n }\n};", "import { Vector, Vector2, Vector3, Vector4 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { getV2Angle, setV2Angle } from '../angle';\n\n// ------------ SUM ------------------------\n\nexport const vSum = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSum(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sum = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSum(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ SUB ------------------------\n\nexport const vSub = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : Vector => {\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vSub(vector1, vector2, decimalPlaces) as Vector2;\n};\n\nexport const v3Sub = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vSub(vector1, vector2, decimalPlaces) as Vector3;\n};\n\n// ------------ MUL SCALAR ------------------------\n\nexport const vMulScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n const vector: Vector = [];\n\n for(let i=0; i {\n return vMulScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3MulScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vMulScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ DIVIDE ------------------------\n\nexport const vDivideScalar = (v: Vector, scalar: number, decimalPlaces = Infinity): Vector => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const vector: Vector = [];\n\n for(let i=0; i {\n return vDivideScalar(v2, scalar, decimalPlaces) as Vector2;\n};\n\nexport const v3DivideScalar = (v3: Vector3, scalar: number, decimalPlaces = Infinity): Vector3 => {\n return vDivideScalar(v3, scalar, decimalPlaces) as Vector3;\n};\n\n// ------------ LENGTH ------------------------\n\nexport const vLength = (vector: Vector, decimalPlaces = Infinity) => {\n let sum = 0;\n\n for(let i=0; i {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v3Length = (vector: Vector3, decimalPlaces = Infinity) => {\n return vLength(vector, decimalPlaces);\n};\n\nexport const v2SetLength = (v2: Vector2, newLength: number, decimalPlaces = Infinity): Vector2 => {\n const angle = getV2Angle(v2);\n return [\n setDecimalPlaces(Math.cos(angle) * newLength, decimalPlaces),\n setDecimalPlaces(Math.sin(angle) * newLength, decimalPlaces),\n ];\n};\n\n// ----------- DISTANCE ------------------------\n\nexport const vDistance = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v2Distance = (vector1: Vector2, vector2: Vector2, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\nexport const v3Distance = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) => {\n const diff = vSub(vector1, vector2);\n return vLength(diff, decimalPlaces);\n};\n\n// ------------ NORMALIZE ------------------------\n\n/**\n * Normalization creates a unit vector, which is a vector of length 1.\n */\nexport const vNormalize = (v: Vector, decimalPlaces = Infinity) : Vector => {\n const length = vLength(v);\n const unitVector: Vector = [];\n\n for(let i=0; i {\n return vNormalize(v2, decimalPlaces) as Vector2;\n};\n\nexport const v3Normalize = (v3: Vector3, decimalPlaces = Infinity) : Vector3 => {\n return vNormalize(v3, decimalPlaces) as Vector3;\n};\n\n// ------------ DOT PRODUCT ------------------------\n\nexport const vDotProduct = (vector1: Vector, vector2: Vector, decimalPlaces = Infinity) : number => {\n let sum = 0;\n\n for(let i=0; i {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\nexport const v3DotProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity) : number => {\n return vDotProduct(vector1, vector2, decimalPlaces);\n};\n\n// ------------ CROSS PRODUCT ------------------------\n\n/**\n * Cross product is possible on 3D vectors only.\n * The cross product a \u00D7 b is defined as a vector c that is perpendicular (orthogonal) to both a and b.\n */\nexport const v3CrossProduct = (vector1: Vector3, vector2: Vector3, decimalPlaces = Infinity): Vector3 => {\n return [\n setDecimalPlaces(vector1[1] * vector2[2] - vector1[2] * vector2[1], decimalPlaces),\n setDecimalPlaces(vector1[2] * vector2[0] - vector1[0] * vector2[2], decimalPlaces),\n setDecimalPlaces(vector1[0] * vector2[1] - vector1[1] * vector2[0], decimalPlaces),\n ];\n};\n\n// --------------- INIT VECTOR HELPER -----------------\n\nexport const v2 = (defaultValue = 0): Vector2 => {\n return [defaultValue, defaultValue];\n};\n\nexport const v3 = (defaultValue = 0): Vector3 => {\n return [defaultValue, defaultValue, defaultValue];\n};\n\nexport const v4 = (defaultValue = 0): Vector4 => {\n return [defaultValue, defaultValue, defaultValue, defaultValue];\n};\n\nexport const vN = (N: number, defaultValue = 0): Vector => {\n\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n const vector: Vector = [];\n for(let i=0; i {\n let vector: Vector2 = [0, 0];\n vector = v2SetLength(vector, distance);\n return setV2Angle(vector, angleRad);\n};\n\n// --------------- EQUALITY -------------------------\n\nexport const vEqual = (vector1: Vector, vector2: Vector): boolean => {\n if(vector1.length !== vector2.length) return false;\n\n for(let i=0; i {\n const sub = v2Sub(vector2, vector1);\n return [\n -setDecimalPlaces(sub[1], decimalPlaces),\n setDecimalPlaces(sub[0], decimalPlaces)\n ];\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector, Vector2, Vector3 } from '../../types';\nimport { vMulScalar, vSum, vSub, vDotProduct, vN, vEqual, vDivideScalar } from './vector';\n\n// --------------- SUM ----------------------\n\nexport const mSum = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sum = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSum(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- SUB ----------------------\n\nexport const mSub = (matrix1: Matrix, matrix2: Matrix, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix2;\n};\n\nexport const m3Sub = (matrix1: Matrix3, matrix2: Matrix3, decimalPlaces = Infinity): Matrix3 => {\n return mSub(matrix1, matrix2, decimalPlaces) as Matrix3;\n};\n\n// --------------- MUL SCALAR ----------------------\n\nexport const mMulScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vMulScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2MulScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mMulScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3MulScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mMulScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n// --------------- DIVIDE SCALAR ----------------------\n\nexport const mDivideScalar = (m: Matrix, scalar: number, decimalPlaces = Infinity): Matrix => {\n if(scalar === 0){\n throw new Error('Division by zero error.');\n }\n\n const matrix: Matrix = [];\n\n for(const v of m){\n matrix.push(vDivideScalar(v, scalar, decimalPlaces));\n }\n\n return matrix;\n};\n\nexport const m2DivideScalar = (m2: Matrix2, scalar: number, decimalPlaces = Infinity): Matrix2 => {\n return mDivideScalar(m2, scalar, decimalPlaces) as Matrix2;\n};\n\nexport const m3DivideScalar = (m3: Matrix3, scalar: number, decimalPlaces = Infinity): Matrix3 => {\n return mDivideScalar(m3, scalar, decimalPlaces) as Matrix3;\n};\n\n\n// --------------- TRANSPOSE ----------------------\n\nexport const mTranspose = (m: Matrix): Matrix => {\n\n const vectorsCount = m.length;\n if(vectorsCount <= 0) return m;\n\n const vectorLength = m[0].length;\n if(vectorLength <= 0) return m;\n\n const matrix: Matrix = [];\n for(let i=0; i {\n return mTranspose(m2);\n};\n\nexport const m3Transpose = (m3: Matrix3): Matrix => {\n return mTranspose(m3);\n};\n\n// ----------------- RESET ----------------------\n\nexport const mReset = (m: Matrix, defaultValue = 0): Matrix => {\n\n if(m.length <= 0) return [];\n\n const res: Matrix = [];\n\n for(let i=0; i {\n return mReset(m2, defaultValue) as Matrix2;\n};\n\nexport const m3Reset = (m3: Matrix3, defaultValue = 0): Matrix3 => {\n return mReset(m3, defaultValue) as Matrix3;\n};\n\n// --------------- MATRIX INIT HELPERS -----------------\n\nexport const m2x2 = (defaultValue = 0): Matrix2 => {\n return [\n [defaultValue, defaultValue],\n [defaultValue, defaultValue],\n ];\n};\n\nexport const m3x3 = (defaultValue = 0): Matrix3 => {\n return [\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const m4x4 = (defaultValue = 0): Matrix4 => {\n return [\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n [defaultValue, defaultValue, defaultValue, defaultValue],\n ];\n};\n\nexport const mNxM = (N: number, M: number, defaultValue = 0): Matrix => {\n if(N <= 0 || M <= 0){\n throw new Error('M and N must be positive numbers.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return [\n [1, 0],\n [0, 1],\n ];\n};\n\nexport const identity3 = (): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\nexport const identity4 = (): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Identity Matrix (I).\n * M x I = I x M = M for any matrix M.\n * Identity Matrix is a special case of scale matrix.\n */\nexport const identityN = (N: number): Matrix => {\n if(N < 0){\n throw new Error('N must be a non-negative number.');\n }\n\n if(N === 0) return [];\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const matrix: Matrix = [];\n\n for(let i=0; i {\n return mDeepCopy(m2) as Matrix2;\n};\n\nexport const m3DeepCopy = (m3: Matrix3): Matrix3 => {\n return mDeepCopy(m3) as Matrix3;\n};\n\n// -------------- APPEND / PREPEND ROW OR COLUMN ---------------\n\nexport const mAppendCol = (m: Matrix, col: Vector): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n const copy = mDeepCopy(m);\n copy.push(row);\n return copy;\n};\n\nexport const m2AppendRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.push(row);\n return copy;\n};\n\nexport const m3AppendRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.push(row);\n return copy;\n};\n\nexport const mPrependRow = (m: Matrix, row: Vector) : Matrix => {\n const copy = mDeepCopy(m);\n copy.unshift(row);\n return copy;\n};\n\nexport const m2PrependRow = (m2: Matrix2, row: Vector2) : Matrix2 => {\n const copy = m2DeepCopy(m2);\n copy.unshift(row);\n return copy;\n};\n\nexport const m3PrependRow = (m3: Matrix3, row: Vector3) : Matrix3 => {\n const copy = m3DeepCopy(m3);\n copy.unshift(row);\n return copy;\n};\n\n// ------------ DELETE ROW OR COLUMN ----------------------------\n\nexport const mDelLastRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.pop();\n return copy;\n};\n\nexport const mDelFirstRow = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n copy.shift();\n return copy;\n};\n\nexport const mDelLastColumn = (m: Matrix): Matrix => {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const copy = mDeepCopy(m);\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const size = m[0].length;\n\n const vector: Vector = [];\n for(let i=0; i {\n if(m.length <= 0) return [];\n\n const vector: Vector = [];\n for(let i=0; i {\n\n const matrix: Matrix = [];\n for(let i=0; i {\n\n if(matrix.length < 0) return [];\n\n if(matrix[0].length !== vector.length){\n throw new Error('The number of columns in the matrix must be equal to the length of the vector.');\n }\n\n const res: Vector = [];\n\n for(let i=0; i {\n if(matrix1.length !== matrix2.length) return false;\n\n for(let i=0; i returns matrix N (m-1 x m-1)\n * The matrix must be square.\n */\nconst mMinorHelper = (m: Matrix, row: number, col: number) => {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const matrix: Matrix = [];\n\n for(let i=0; i {\n const size = m.length;\n\n if(size <= 0){\n throw new Error('The matrix should not be empty.');\n }\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // prepare the matrix without provided row and column\n const matrix = mMinorHelper(m, row, col);\n\n // calculate the matrix determinant\n return mDeterminant(matrix);\n};\n\n/**\n * Calculate determinant for NxN matrix.\n * Matrix should be square.\n */\nexport const mDeterminant = (matrix: Matrix): number => {\n const size = matrix.length;\n if(size === 0) return 1;\n\n if(size !== matrix[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return matrix[0][0];\n if(size === 2) return m2Determinant(matrix as Matrix2);\n\n let d = 0;\n\n for(let i=0; i {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return m2[0][0] * m2[1][1] - m2[1][0] * m2[0][1];\n};\n\n/**\n * Calculate determinant for 3x3 matrix.\n * Matrix should be square.\n */\nexport const m3Determinant = (m3: Matrix3): number => {\n if(m3.length !== m3[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return mDeterminant(m3);\n};\n\n// ------------------ INVERSE -----------------------\n\nexport const m2Adjugate = (m2: Matrix2): Matrix2|null => {\n if(m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n return [\n [m2[1][1], -m2[0][1]],\n [-m2[1][0], m2[0][0]],\n ];\n};\n\nexport const m3Adjugate = (m3: Matrix3) : Matrix3|null => {\n return mAdjugate(m3) as (Matrix3|null);\n};\n\n/**\n * Adjugate is a transpose of a cofactor matrix\n */\nexport const mAdjugate = (m: Matrix): Matrix|null => {\n\n const size = m.length;\n if(size <= 0) return null;\n\n if(size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n if(size === 1) return m;\n\n if(size === 2) return m2Adjugate(m as Matrix2);\n\n // build a cofactor matrix ----------------\n const cofactors: Matrix = [];\n\n for(let i=0; i {\n if(m.length > 0 && m.length !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = mDeterminant(m);\n return d === 0;\n};\n\n/**\n * Square matrix A (nxn) is invertible is there is another square matrix B (nxn) so AxB = BxA = I\n * For A (2x2) matrix, the inverse is:\n * (1 / (determinant(A))) * adj(A)\n */\nexport const m2Inverse = (m2: Matrix2, decimalPlaces = Infinity): (Matrix2 | null) => {\n if(m2.length > 0 && m2.length !== m2[0].length){\n throw new Error('The matrix must be square.');\n }\n\n const d = m2Determinant(m2);\n if(d === 0) return null;\n\n const adj = m2Adjugate(m2);\n if(adj === null) return null;\n\n return m2DivideScalar(adj, d, decimalPlaces);\n};\n\nexport const m3Inverse = (m3: Matrix3, decimalPlaces = Infinity): (Matrix3 | null) => {\n return mInverse(m3, decimalPlaces) as (Matrix3|null);\n};\n\nexport const mInverse = (m: Matrix, decimalPlaces = Infinity): (Matrix | null) => {\n const size = m.length;\n\n if(size > 0 && size !== m[0].length){\n throw new Error('The matrix must be square.');\n }\n\n // find a determinant ----------------------\n const d = mDeterminant(m);\n\n // find an Adjugate - a transpose of a cofactor matrix\n const adj = mAdjugate(m);\n if(adj === null) return null;\n\n return mDivideScalar(adj, d, decimalPlaces);\n};", "import { Matrix2, Matrix3, Matrix4, Matrix, Vector2, Vector3, Vector4 } from '../../types';\nimport { v2Normalize, v3MulScalar, v3Normalize } from './vector';\nimport { mMulVector, mMul } from './matrix';\nimport { setDecimalPlaces } from '../format';\n\n/*\nAny 2D affine transformation can be decomposed\ninto a rotation, followed by a scaling, followed by a\nshearing, and followed by a translation.\n---------------------------------------------------------\nAffine matrix = translation x shearing x scaling x rotation\n */\n\n// ----------------- CSS -------------------------------------\n\n/**\n * Matrix 2D in non-homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2ToCSS = (m: Matrix2) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, 0, 0)`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix\n */\nexport const m2hToCSS = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix(${ a }, ${ b }, ${ c }, ${ d }, ${ tx }, ${ ty })`;\n};\n\n/**\n * Matrix 2D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m2hToCSS3d = (m: Matrix3) : string => {\n const a = m[0][0];\n const b = m[1][0];\n const c = m[0][1];\n const d = m[1][1];\n const tx = m[0][2];\n const ty = m[1][2];\n\n return `matrix3d(${ a }, ${ b }, 0, 0, ${ c }, ${ d }, 0, 0, 0, 0, 1, 0, ${ tx }, ${ ty }, 0, 1)`;\n};\n\n/**\n * Matrix 3D in homogeneous coordinates to CSS matrix3d() function\n * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d\n */\nexport const m3hToCSS3d = (m: Matrix4) : string => {\n\n return `matrix3d(\n ${ m[0][0] }, ${ m[0][1] }, ${ m[0][2] }, ${ m[0][3] },\n ${ m[1][0] }, ${ m[1][1] }, ${ m[1][2] }, ${ m[1][3] },\n ${ m[2][0] }, ${ m[2][1] }, ${ m[2][2] }, ${ m[2][3] },\n ${ m[3][0] }, ${ m[3][1] }, ${ m[3][2] }, ${ m[3][3] }\n )`;\n};\n\n// ---------------- TRANSLATION MATRICES ----------------------\n\nexport const m2Translation = (position: Vector2, decimalPlaces = Infinity): Matrix2 => {\n\n return [\n [1, 0],\n [0, 1],\n [setDecimalPlaces(position[0], decimalPlaces), setDecimalPlaces(position[1], decimalPlaces)],\n ];\n};\n\nexport const m3Translation = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n [\n setDecimalPlaces(position[0], decimalPlaces),\n setDecimalPlaces(position[1], decimalPlaces),\n setDecimalPlaces(position[2], decimalPlaces)\n ],\n ];\n};\n\n/**\n * 2D Translation matrix in homogeneous coordinates.\n */\nexport const m2TranslationH = (position: Vector3, decimalPlaces = Infinity): Matrix3 => {\n\n return [\n [1, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1],\n ];\n};\n\n/**\n * 3D Translation matrix in homogeneous coordinates.\n */\nexport const m3TranslationH = (position: Vector4, decimalPlaces = Infinity): Matrix4 => {\n\n return [\n [1, 0, 0, setDecimalPlaces(position[0], decimalPlaces)],\n [0, 1, 0, setDecimalPlaces(position[1], decimalPlaces)],\n [0, 0, 1, setDecimalPlaces(position[2], decimalPlaces)],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- ROTATION MATRICES -------------------------\n\n/**\n * Rotation of an angle about the origin.\n */\nexport const m2Rotation = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix2 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin],\n [sin, cos],\n ] :\n [\n [cos, sin],\n [-sin, cos],\n ];\n};\n\n/**\n * Rotation of an angle about the origin in homogeneous coordinates (clockwise).\n */\nexport const m2RotationH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ]:\n [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation of an angle \"angleRad\" around the given point (transformOrigin) in homogeneous coordinates (clockwise).\n * result_vector = TranslationMatrix(x, y) * RotationMatrix() * TranslationMatrix(-x, -y) * position_vector\n */\nexport const m2RotationAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const rotation = m2RotationH(angleRad, isClockwise, decimalPlaces);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, rotation);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2RotateAroundPointH = (\n angleRad: number,\n transformOrigin: Vector3,\n position: Vector3,\n isClockwise = true,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2RotationAroundPointH(angleRad, transformOrigin, isClockwise, decimalPlaces);\n return mMulVector(mat3h, position) as Vector3;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2Rotate = (angleRad: number, vector: Vector2, isClockwise = true, decimalPlaces = Infinity): Vector2 => {\n const unitVector = v2Normalize(vector);\n return mMulVector(m2Rotation(angleRad, isClockwise, decimalPlaces), unitVector) as Vector2;\n};\n\n/**\n * Rotate vector around the origin by angle \"angleRad\" (clockwise).\n */\nexport const v2RotateH = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m2RotationH(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the X axis (clockwise).\n */\nexport const m3RotationX = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0],\n [0, cos, -sin],\n [0, sin, cos],\n ] :\n [\n [1, 0, 0],\n [0, cos, sin],\n [0, -sin, cos],\n ];\n};\n\n/**\n * Rotation around the X axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationXH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [1, 0, 0, 0],\n [0, cos, -sin, 0],\n [0, sin, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [1, 0, 0, 0],\n [0, cos, sin, 0],\n [0, -sin, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateX = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationX(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Y axis (clockwise).\n */\nexport const m3RotationY = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin],\n [0, 1, 0],\n [-sin, 0, cos],\n ] :\n [\n [cos, 0, -sin],\n [0, 1, 0],\n [sin, 0, cos],\n ];\n};\n\n/**\n * Rotation around the Y axis (clockwise) - in homogeneous coordinates\n */\nexport const m3RotationYH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, 0, sin, 0],\n [0, 1, 0, 0],\n [-sin, 0, cos, 0],\n [0, 0, 0, 1],\n ] :\n [\n [cos, 0, -sin, 0],\n [0, 1, 0, 0],\n [sin, 0, cos, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateY = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationY(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n/**\n * Rotation around the Z axis (clockwise).\n */\nexport const m3RotationZ = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix3 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1],\n ] : [\n [cos, sin, 0],\n [-sin, cos, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Rotation around the Z axis (clockwise)- in homogeneous coordinates\n */\nexport const m3RotationZH = (angleRad: number, isClockwise = true, decimalPlaces = Infinity): Matrix4 => {\n\n const cos = setDecimalPlaces(Math.cos(angleRad), decimalPlaces);\n const sin = setDecimalPlaces(Math.sin(angleRad), decimalPlaces);\n\n return isClockwise ? [\n [cos, -sin, 0, 0],\n [sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ] : [\n [cos, sin, 0, 0],\n [-sin, cos, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\nexport const v3RotateZ = (angleRad: number, vector: Vector3, isClockwise = true, decimalPlaces = Infinity): Vector3 => {\n const unitVector = v3Normalize(vector);\n return mMulVector(m3RotationZ(angleRad, isClockwise, decimalPlaces), unitVector) as Vector3;\n};\n\n// ---------------- SCALE MATRICES -------------\n\n/**\n * Get matrix for arbitrary scaling pivot point.\n * result_vector = TranslationMatrix(x, y) * ScaleMatrix() * TranslationMatrix(-x, -y) * scale_vector\n */\nexport const m2ScaleAtPointHMatrix = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n decimalPlaces = Infinity): Matrix3 => {\n\n const translation = m2TranslationH(transformOrigin, decimalPlaces);\n const scale = m2ScaleH(scaleVector);\n const translationBack = m2TranslationH(v3MulScalar(transformOrigin, -1), decimalPlaces);\n const temp1 = mMul(translation, scale);\n return mMul(temp1, translationBack) as Matrix3;\n};\n\nexport const m2ScaleAtPointH = (\n scaleVector: Vector3,\n transformOrigin: Vector3,\n point: Vector3,\n decimalPlaces = Infinity): Vector3 => {\n\n const mat3h = m2ScaleAtPointHMatrix(scaleVector, transformOrigin, decimalPlaces);\n return mMulVector(mat3h, point) as Vector3;\n};\n\nexport const m2Scale = (scaleVector: Vector2): Matrix2 => {\n return [\n [scaleVector[0], 0],\n [0, scaleVector[1]],\n ];\n};\n\nexport const v2Scale = (scaleVector: Vector2, vector: Vector2): Vector2 => {\n return mMulVector(m2Scale(scaleVector), vector) as Vector2;\n};\n\n/**\n * homogeneous coordinates\n */\nexport const m2ScaleH = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, 1],\n ];\n};\n\nexport const m3Scale = (scaleVector: Vector3): Matrix3 => {\n return [\n [scaleVector[0], 0, 0],\n [0, scaleVector[1], 0],\n [0, 0, scaleVector[2]],\n ];\n};\n\nexport const m3ScaleH = (scaleVector: Vector4): Matrix4 => {\n return [\n [scaleVector[0], 0, 0, 0],\n [0, scaleVector[1], 0, 0],\n [0, 0, scaleVector[2], 0],\n [0, 0, 0, 1]\n ];\n};\n\nexport const v3Scale = (scaleVector: Vector3, vector: Vector3): Vector3 => {\n return mMulVector(m3Scale(scaleVector), vector) as Vector3;\n};\n\n/**\n * Stretch, parallel to the x-axis.\n */\nexport const m2ScaleX = (scale: number): Matrix2 => {\n return [\n [scale, 0],\n [0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the x-axis - homogeneous coordinates\n */\nexport const m2ScaleXH = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleX = (scale: number): Matrix3 => {\n return [\n [scale, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in x-direction\n */\nexport const m3ScaleXH = (scale: number): Matrix4 => {\n return [\n [scale, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleY = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Stretch in y-direction\n */\nexport const m3ScaleYH = (scale: number): Matrix => {\n return [\n [1, 0, 0, 0],\n [0, scale, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZ = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, scale],\n ];\n};\n\n/**\n * Stretch in z-direction\n */\nexport const m3ScaleZH = (scale: number): Matrix4 => {\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, scale, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis.\n */\nexport const m2ScaleY = (scale: number): Matrix2 => {\n return [\n [1, 0],\n [0, scale],\n ];\n};\n\n/**\n * Stretch, parallel to the y-axis - homogeneous coordinates\n */\nexport const m2ScaleYH = (scale: number): Matrix3 => {\n return [\n [1, 0, 0],\n [0, scale, 0],\n [0, 0, 1],\n ];\n};\n\n// ---------------- REFLECTION MATRICES -------------------------\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOrigin = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection about the origin.\n */\nexport const m2ReflectionOriginH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection about the origin in non-homogeneous coordinates\n */\nexport const m3ReflectionOrigin = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, -1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection about the origin in homogeneous coordinates\n */\nexport const m3ReflectionOriginH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection about y=-x\n */\nexport const m2ReflectionYmX = (): Matrix2 => {\n\n return [\n [0, -1],\n [-1, 0],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionX = (): Matrix2 => {\n\n return [\n [1, 0],\n [0, -1],\n ];\n};\n\n/**\n * Reflection in the x-axis.\n */\nexport const m2ReflectionXH = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection in the y-axis.\n */\nexport const m2ReflectionY = (): Matrix2 => {\n\n return [\n [-1, 0],\n [0, 1],\n ];\n};\n\nexport const m2ReflectionYH = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionYZ = (): Matrix3 => {\n\n return [\n [-1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to YZ plane in homogeneous coordinates\n */\nexport const m3ReflectionYZH = (): Matrix4 => {\n\n return [\n [-1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXZ = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, -1, 0],\n [0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XZ plane in homogeneous coordinates\n */\nexport const m3ReflectionXZH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, -1, 0, 0],\n [0, 0, 1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in non-homogeneous coordinates\n */\nexport const m3ReflectionXY = (): Matrix3 => {\n\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, -1],\n ];\n};\n\n/**\n * Reflection relative to XY plane in homogeneous coordinates\n */\nexport const m3ReflectionXYH = (): Matrix4 => {\n\n return [\n [1, 0, 0, 0],\n [0, 1, 0, 0],\n [0, 0, -1, 0],\n [0, 0, 0, 1],\n ];\n};\n\n// ---------------- SHEARING MATRICES -------------------------\n\n\n/**\n * Shearing in y-axis, with x-axis fixed with (0,1) moving to (factor, 1)\n */\nexport const m2ShearingY = (factor: number): Matrix2 => {\n\n return [\n [1, factor],\n [0, 1],\n ];\n};\n\n/**\n * Shearing in x-axis, with y-axis fixed with (1,0) moving to (1, factor)\n */\nexport const m2ShearingX = (factor: number): Matrix2 => {\n\n return [\n [1, 0],\n [factor, 1],\n ];\n};", "import { setDecimalPlaces } from './format';\n\n/**\n * Returns a random number in the [min,max] range.\n */\nexport const getRandom = (min: number, max: number, decimalPlaces = Infinity): number => {\n return setDecimalPlaces(Math.random() * (max - min) + min, decimalPlaces);\n};\n\n/**\n * Returns a random integer number in the [min,max] range.\n */\nexport const getRandomInt = (min: number, max: number): number => {\n return Math.floor(Math.random() * (max - min + 1) + min);\n};\n\nexport const getRandomBoolean = () => Math.random() < 0.5;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const getRandomItemFromArray = (array: any[]) => {\n const randomIndex = getRandomInt(0, array.length - 1);\n return array[randomIndex];\n};", "export const stringToNumber = (value: string|undefined|null|number, defaultNumber: number) => {\n if(value === undefined || value === null) return defaultNumber;\n const res = Number(value) ?? defaultNumber;\n return isNaN(res) ? defaultNumber : res;\n};", "import { setDecimalPlaces } from './format';\nimport { Vector2, Vector3 } from '../types';\n\n/**\n * u(x) and v(x) are functions ---------->\n *\n * dx(u + v) = dx(u) + dx(v)\n * dx(u - v) = dx(u) - dx(v)\n * dx(u * v) = dx(u) * v + u * dx(v)\n * dx(u / v) = (dx(u) * v - u * dx(v)) / (v ^ 2), when v(x) != 0\n */\n\n// ------------------ Derivatives of Polynomial ---------------------------\n\n/**\n * y = 3x+2\n * dxPolynomial(10, [[3, 1], [2, 0]])\n */\nexport const dxPolynomial = (x: number, polynomial: number[][], decimalPlaces = Infinity) => {\n let res = 0;\n\n for(const part of polynomial){\n if(part.length !== 2) return NaN;\n\n const coeff = part[0];\n const power = part[1];\n res += coeff * power * Math.pow(x, power - 1);\n }\n\n return setDecimalPlaces(res, decimalPlaces);\n}\n\n// ---------------------- Bezier Curves ---------------------------\n\n/**\n * Derivative of Bezier Curve is another Bezier Curve.\n * t must min in range [0, 1]\n */\nexport const dxV2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n // The derivative: P1 * (2t-2) + (2*P3-4*P2) * t + 2 * P2\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -2 * (1 - t); // Math.pow(1 - t, 2)\n const temp2 = 2 - 4 * t; // (1 - t) * 2 * t\n const temp3 = 2 * t; //t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\nexport const dxV2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const dxV3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = -3 * Math.pow(1 - t, 2); //Math.pow(1 - t, 3);\n const temp2 = 3 * (t - 1) * (3 * t - 1); //Math.pow(1 - t, 2) * 3 * t;\n const temp3 = 6 * t - 9 * t * t; // (1 - t) * 3 * t * t;\n const temp4 = 3 * t * t; //t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n\n// ----------------- Derivatives of trigonometry functions ---------------------------\n\nexport const dxSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(Math.cos(x), decimalPlaces);\n};\n\nexport const dxCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-Math.sin(x), decimalPlaces);\n};\n\nexport const dxTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.cos(x) ** 2), decimalPlaces);\n};\n\n/**\n * x != Math.PI * n, where n is an integer\n */\nexport const dxCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sin(x) ** 2), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcSin = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\n/**\n * -1 < x < 1\n */\nexport const dxArcCos = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (Math.sqrt(1 - x ** 2)), decimalPlaces);\n};\n\nexport const dxArcTan = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(1 / (1 + x ** 2), decimalPlaces);\n};\n\nexport const dxArcCot = (x: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(-1 / (1 + x ** 2), decimalPlaces);\n};\n", "import { Matrix, Matrix2, Matrix3, Vector, Vector2, Vector3 } from '../../types';\nimport { m2Inverse, m3Inverse, mInverse, mMulVector, mDelLastColumn, mGetLastColumn } from '../linear-algebra/matrix';\nimport { setDecimalPlaces } from '../format';\nimport { v2Sub } from '../linear-algebra/vector';\n\n/**\n * Linear equation\n * ax + b = c\n * x = (c - b) / a; a != 0\n */\nexport const linearEquation = (equation: Vector3, decimalPlaces = Infinity) : number => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n\n const diff = c - b;\n\n if(a === 0 && diff === 0) return Infinity; // any number is a solution\n if(a === 0) return NaN; // no solution\n\n return setDecimalPlaces(diff / a, decimalPlaces);\n};\n\n/**\n * System of 2 linear equations.\n * [x, y] = inverse(Matrix of equation parameters) x (vector of equation results)\n * ---------------\n * 3x + 2y = 7\n * -6x + 6y = 6\n */\nexport const linearEquationSystem2 = (equation1: Vector3, equation2: Vector3, decimalPlaces = Infinity) : Vector2 | null => {\n const equationParams: Matrix2 = [\n [equation1[0], equation1[1]],\n [equation2[0], equation2[1]],\n ];\n\n const inversed = m2Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector2 = [\n equation1[2],\n equation2[2]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector2;\n};\n\n/**\n * System of 3 linear equations.\n * ---------------------------------------\n * 3x + 2y + 5z = 7\n * -6x + 6y + 6z = 6\n * 2x + 7y - z = 4\n */\nexport const linearEquationSystem3 = (\n equation1: Vector,\n equation2: Vector,\n equation3: Vector,\n decimalPlaces = Infinity) : Vector3 | null => {\n const equationParams: Matrix3 = [\n [equation1[0], equation1[1], equation1[2]],\n [equation2[0], equation2[1], equation2[2]],\n [equation3[0], equation3[1], equation3[2]],\n ];\n\n const inversed = m3Inverse(equationParams);\n if(inversed === null) return null; // no results\n\n const equationResults: Vector3 = [\n equation1[3],\n equation2[3],\n equation3[3]\n ];\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector3;\n};\n\n/**\n * System of N linear equations.\n */\nexport const linearEquationSystemN = (equations: Matrix, decimalPlaces = Infinity) : Vector | null => {\n if(equations.length <= 0) return null;\n\n const equationParams = mDelLastColumn(equations);\n\n const inversed = mInverse(equationParams);\n if(inversed === null) return null; // no results\n\n // the last column of the equations matrix\n const equationResults = mGetLastColumn(equations);\n\n return mMulVector(inversed, equationResults, decimalPlaces) as Vector;\n};\n\n/**\n * Calculate the equation of a line given two points in a 2D space.\n * y = ax + b\n * y - y1 = m(x - x1)\n * m = (y2 - y1) / (x2 - x1)\n */\nexport const getLinearEquationBy2Points = (point1: Vector2, point2: Vector2) : {\n slope: number|undefined,\n yIntercept: number|undefined,\n xIntercept: number|undefined,\n formula: string,\n} => {\n const [deltaX, deltaY] = v2Sub(point2, point1);\n const [x, y] = point1;\n\n if(deltaX === 0) {\n return {\n slope: undefined,\n xIntercept: x,\n yIntercept: undefined,\n formula: `x = ${ x }`,\n };\n }\n\n const m = deltaY / deltaX;\n const b = y - m * x;\n let formula = '';\n\n if(m === 0) {\n formula = `y = ${ b }`;\n }\n else{\n formula = `y = ${ m === 1 ? '' : m }x`;\n\n if(b !== 0) {\n formula += ` ${ b < 0 ? '-' : '+' } ${ Math.abs(b) }`;\n }\n }\n\n return {\n slope: m,\n xIntercept: undefined,\n yIntercept: b,\n formula,\n };\n};", "import { Vector } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport { linearEquation } from './linear-equations';\nimport { isNumber } from '../other';\n\n/**\n * Quadratic Equation.\n * ax^2 + bx + c = d\n */\nexport const quadraticEquation = (equation: Vector, decimalPlaces = Infinity) : Vector => {\n const a = equation[0];\n const b = equation[1];\n const c = equation[2];\n const d = equation[3];\n\n if(a === 0){\n // it's a linear equation -------------------------------------------\n const res = linearEquation([b, c, d], decimalPlaces);\n if(isNumber(res)) return [res];\n return [];\n }\n\n const diff = c - d;\n\n const discriminant = b * b - (4 * a * diff);\n\n if(discriminant < 0){\n return []; // no results\n }\n\n if(discriminant === 0){\n return [ setDecimalPlaces(-b / (2 * a), decimalPlaces) ]; // 1 result\n }\n\n // if(determinant > 0) ---> 2 results\n const t1 = 2 * a;\n const t2 = Math.sqrt(discriminant);\n\n return [\n setDecimalPlaces((-b + t2) / t1, decimalPlaces),\n setDecimalPlaces((-b - t2) / t1, decimalPlaces),\n ];\n};", "import { IBBox, Vector, Vector2, Vector3 } from '../../types';\nimport { setDecimalPlaces } from '../format';\nimport {\n dxV2CubicBezierCurve,\n dxV2QuadraticBezierCurve,\n dxV3CubicBezierCurve,\n dxV3QuadraticBezierCurve\n} from '../derivative';\nimport { v2Normalize, v3Normalize } from '../linear-algebra/vector';\nimport { linearEquation } from '../equations/linear-equations';\nimport { quadraticEquation } from '../equations/quadratic-equations';\nimport { isNumber } from '../other';\n\n/**\n * B\u00E9zier Curves\n * quadratic: y = P1 * (1-t)\u00B2 + P2 * 2 * (1-t)t + P3 * t\u00B2\n * t in range [0, 1]\n */\n\n// -------------------- GET POINT ON CURVE --------------------------\n\n/**\n * Get a point on a quadratic B\u00E9zier curve as a function of time.\n */\nexport const v2QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3QuadraticBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 2);\n const temp2 = (1 - t) * 2 * t;\n const temp3 = t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * centerControlPoint[0] + temp3 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * centerControlPoint[1] + temp3 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * centerControlPoint[2] + temp3 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n/**\n * Get a point on a cubic B\u00E9zier curve as a function of time.\n */\nexport const v2CubicBezierCurve = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n ];\n};\n\nexport const v3CubicBezierCurve = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n\n const temp1 = Math.pow(1 - t, 3);\n const temp2 = Math.pow(1 - t, 2) * 3 * t;\n const temp3 = (1 - t) * 3 * t * t;\n const temp4 = t * t * t;\n\n return [\n setDecimalPlaces(temp1 * startControlPoint[0] + temp2 * center1ControlPoint[0] + temp3 * center2ControlPoint[0] + temp4 * endControlPoint[0], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[1] + temp2 * center1ControlPoint[1] + temp3 * center2ControlPoint[1] + temp4 * endControlPoint[1], decimalPlaces),\n setDecimalPlaces(temp1 * startControlPoint[2] + temp2 * center1ControlPoint[2] + temp3 * center2ControlPoint[2] + temp4 * endControlPoint[2], decimalPlaces),\n ];\n};\n\n// -------------------- TANGENT --------------------------\n\n/**\n * Tangent indicates the direction of travel at specific points along the B\u00E9zier curve,\n * and is literally just the first derivative of our curve.\n */\nexport const v2QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3QuadraticBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n centerControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3QuadraticBezierCurve(t, startControlPoint, centerControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\nexport const v2CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n const dxVector = dxV2CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v2Normalize(dxVector, decimalPlaces);\n};\n\nexport const v3CubicBezierCurveTangent = (\n t: number,\n startControlPoint: Vector3,\n center1ControlPoint: Vector3,\n center2ControlPoint: Vector3,\n endControlPoint: Vector3,\n decimalPlaces = Infinity\n) : Vector3 => {\n const dxVector = dxV3CubicBezierCurve(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n return v3Normalize(dxVector, decimalPlaces);\n};\n\n// -------------------- NORMAL --------------------------\n\n/**\n * Normal is a vector that runs at a right angle to the direction of the curve, and is typically of length 1.\n * To find it, we take the normalised tangent vector, and then rotate it by a 90 degrees.\n */\nexport const v2QuadraticBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2QuadraticBezierCurveTangent(t, startControlPoint, centerControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\nexport const v2CubicBezierCurveNormal = (\n t: number,\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2 => {\n\n const tangent = v2CubicBezierCurveTangent(t, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint, decimalPlaces);\n return [-tangent[1], tangent[0]];\n};\n\n// -------------------- EXTREMA --------------------------\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2QuadraticBezierCurveExtrema = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector => {\n\n /*\n (-2 * (1 - t)) * startControlPoint[0] + (2 - 4 * t) * centerControlPoint[0] + (2 * t) * endControlPoint[0]\n 2 * t * startControlPoint[0] - 4 * t * centerControlPoint[0] + 2 * t * endControlPoint[0] - 2 * startControlPoint[0] + 2 * centerControlPoint[0]\n t * (2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0]) + (- 2 * startControlPoint[0] + 2 * centerControlPoint[0])\n */\n\n const a1 = 2 * startControlPoint[0] - 4 * centerControlPoint[0] + 2 * endControlPoint[0];\n const b1 = -2 * startControlPoint[0] + 2 * centerControlPoint[0];\n const equation1: Vector3 = [a1, b1, 0];\n const res1 = linearEquation(equation1, decimalPlaces);\n\n const a2 = 2 * startControlPoint[1] - 4 * centerControlPoint[1] + 2 * endControlPoint[1];\n const b2 = -2 * startControlPoint[1] + 2 * centerControlPoint[1];\n const equation2: Vector3 = [a2, b2, 0];\n const res2 = linearEquation(equation2, decimalPlaces);\n\n const res: Vector = [];\n\n if(isNumber(res1)){\n res.push(res1);\n }\n\n if(isNumber(res2)){\n res.push(res2);\n }\n\n return res;\n};\n\n/**\n * Find maxima and minima by solving the equation B'(t) = 0\n * Returns result in [0, 1] range.\n */\nexport const v2CubicBezierCurveExtrema = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : Vector2|null => {\n\n const a1 = -3 * startControlPoint[0] + 9 * center1ControlPoint[0] - 9 * center2ControlPoint[0] + 3 * endControlPoint[0];\n const b1 = 6 * startControlPoint[0] - 12 * center1ControlPoint[0] + 6 * center2ControlPoint[0];\n const c1 = -3 * startControlPoint[0] + 3 * center1ControlPoint[0];\n const equation1: Vector = [a1, b1, c1, 0];\n\n const a2 = -3 * startControlPoint[1] + 9 * center1ControlPoint[1] - 9 * center2ControlPoint[1] + 3 * endControlPoint[1];\n const b2 = 6 * startControlPoint[1] - 12 * center1ControlPoint[1] + 6 * center2ControlPoint[1];\n const c2 = -3 * startControlPoint[1] + 3 * center1ControlPoint[1];\n const equation2: Vector = [a2, b2, c2, 0];\n\n // Any value between 0 and 1 is a root that matters for B\u00E9zier curves, anything below or above that is irrelevant (because B\u00E9zier curves are only defined over the interval [0,1]).\n const res1 = quadraticEquation(equation1, decimalPlaces).filter(num => num >= 0 && num <= 1);\n const res2 = quadraticEquation(equation2, decimalPlaces).filter(num => num >= 0 && num <= 1);\n\n const res = [...res1, ...res2];\n if(res.length === 2){\n return [...res1, ...res2] as Vector2;\n }\n\n return null;\n};\n\n// -------------------- BOUNDING BOX --------------------------\n\nexport const v2QuadraticBezierBBox = (\n startControlPoint: Vector2,\n centerControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2QuadraticBezierCurveExtrema(startControlPoint, centerControlPoint, endControlPoint);\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2QuadraticBezierCurve(percent, startControlPoint, centerControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\nexport const v2CubicBezierBBox = (\n startControlPoint: Vector2,\n center1ControlPoint: Vector2,\n center2ControlPoint: Vector2,\n endControlPoint: Vector2,\n decimalPlaces = Infinity\n) : IBBox => {\n\n const extrema = v2CubicBezierCurveExtrema(startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint) || [];\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for(const percent of extrema){\n const point = v2CubicBezierCurve(percent, startControlPoint, center1ControlPoint, center2ControlPoint, endControlPoint);\n\n const x = point[0];\n const y = point[1];\n\n minX = Math.min(minX, x ?? Infinity);\n maxX = Math.max(maxX, x ?? -Infinity);\n\n minY = Math.min(minY, y ?? Infinity);\n maxY = Math.max(maxY, y ?? -Infinity);\n }\n\n minX = setDecimalPlaces(Math.min(minX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n maxX = setDecimalPlaces(Math.max(maxX, startControlPoint[0], endControlPoint[0]), decimalPlaces);\n minY = setDecimalPlaces(Math.min(minY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n maxY = setDecimalPlaces(Math.max(maxY, startControlPoint[1], endControlPoint[1]), decimalPlaces);\n\n return {\n x: minX,\n y: minY,\n w: Math.abs(maxX - minX),\n h: Math.abs(maxY - minY),\n x2: maxX,\n y2: maxY,\n }\n};\n\n\n", "import { Vector2 } from '../types';\nimport { v2Sub } from './linear-algebra/vector';\nimport { getV2Angle } from './angle';\nimport { convertRange } from './other';\n\n/**\n * Circle Equation\n * x^2 + y^2 = radius^2\n * ----------------------\n * Circle Parametric Equation\n * x(t) = radius * cos(t)\n * y(t) = radius * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const circleMovement = (center: Vector2, angle: number, radius: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius,\n center[1] + Math.sin(angle) * radius\n ];\n};\n\n/**\n * Circle Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const circleMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radius: number\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return circleMovement(center, angle, radius);\n};\n\n/**\n * Ellipse Equation\n * (x - centerX)^2 / (radius1^2) + (y - centerY)^2 / (radius2^2) = 1\n * -----------------------------------------------------------------\n * Ellipse Parametric Equation\n * x(t) = radius1 * cos(t)\n * y(t) = radius2 * sin(t)\n * t is the parameter = angle\n *\n * Angle should be in the range [0, Math.PI]\n */\nexport const ellipseMovement = (center: Vector2, angle: number, radius1: number, radius2: number): Vector2 => {\n angle = angle % Math.PI * 2;\n\n return [\n center[0] + Math.cos(angle) * radius1,\n center[1] + Math.sin(angle) * radius2\n ];\n};\n\n/**\n * Ellipse Movement After Mouse.\n * Mouse Positions:\n * - pageX/Y coordinates are relative to the top left corner of the whole rendered page (including parts hidden by scrolling),\n * - screenX and screenY: Relative to the top left of the physical screen/monitor, this reference point only moves if you increase or decrease the number of monitors or the monitor resolution.\n * - clientX/Y coordinates are relative to the top left corner of the visible part of the page, \"seen\" through browser window.\n * - offsetX and offsetY are relative to the parent container,\n */\nexport const ellipseMovementAfterMouse = (\n mouse: Vector2,\n center: Vector2,\n radii: Vector2\n): Vector2 => {\n\n const vector = v2Sub(mouse, center);\n\n let angle = getV2Angle(vector);\n\n // convert the angle from the range [0, Math.PI*2] to the range [0, Math.PI]\n angle = convertRange(angle, 0, Math.PI*2, 0, Math.PI);\n\n return ellipseMovement(center, angle, radii[0], radii[1]);\n};\n\n/**\n * Sine Wave Equation (Sinusoid)\n * -----------------------------\n * const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n * amplitude = the peak deviation of the function from zero\n * frequency = number of cycles\n * phase = specifies (in radians) where in its cycle the oscillation is at t = 0.\n * think of it as \"shifting\" the starting point of the function to the right (positive p) or left (negative)\n */\nexport const sineWaveMovement = (x: number, amplitude: number, frequency: number, phase: number) : Vector2 => {\n /*\n example values:\n const amplitude = 50;\n const frequency = 0.005;\n const phase = 0;\n x: [0, 1000]\n */\n const y = amplitude * Math.sin(2 * Math.PI * frequency * x + phase);\n\n return [x, y];\n};\n\n/**\n * Lissajous curve (Lissajous figure or Bowditch curve)\n * Parametric equation #1\n * f(t) = A * sin(k * t + m)\n * f(t) = B * sin(n * t)\n * 0 <= m <= PI/2\n * k, n >= 1\n * -----------------------\n * Parametric equation #2\n * f(t) = A * cos(k * t - m)\n * f(t) = B * cos(n * t - p)\n * -----------------------------\n * Shapes:\n * k = 1, n = 1, m = 0, p = 0 ---> line\n * A = B, k = 1, n = 1, m = PI/2, p = PI/2 ----> circle\n * A != B, k = 1, n = 1, m = PI/2, p = PI/2 ----> ellipse\n * k = 2, n = 2, m = PI/2, p = PI/2 ----> section of a parabola\n */\nexport const lissajousCurve = (\n width: number,\n height: number,\n t: number,\n k: number,\n n: number,\n m: number,\n p: number\n) :Vector2 => {\n return [\n width * Math.cos(k * t - m),\n height * Math.cos(n * t - p),\n ];\n};\n", "import { getRandom } from './random';\nimport { HSLColor, RGBColor } from '../types';\nimport { mod } from './other';\nimport { setDecimalPlaces } from './format';\n\n// ------------------------ RANDOM COLOR -------------------------------------\n\nexport const getRandomRGBColor = () : RGBColor => {\n const hslColor = getRandomHSLColor();\n return hslToRgb(hslColor);\n};\n\nexport const getRandomHexColor = () : string => {\n const hslColor = getRandomHSLColor();\n return hslToHex(hslColor);\n};\n\nexport const getRandomHSLColor = () : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given hue\n */\nexport const getRandomHSLColorWithHue = (h: number) : HSLColor => {\n const s = getRandom(0, 100);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given saturation\n */\nexport const getRandomHSLColorWithSaturation = (s: number) : HSLColor => {\n const h = getRandom(1, 360);\n const l = getRandom(0, 100);\n return [h, s, l];\n};\n\n/**\n * generate random color with the given lightness\n */\nexport const getRandomHSLColorWithLightness = (l: number) : HSLColor => {\n const h = getRandom(1, 360);\n const s = getRandom(0, 100);\n return [h, s, l];\n};\n\nexport const getRandomGrayscaleHSLColor = () : HSLColor => {\n const l = getRandom(0, 100);\n return [0, 0, l];\n};\n\nexport const getRandomHSLColorWithinRanges = (\n hueStart = 1, hueEnd = 360,\n saturationStart = 0, saturationEnd = 100,\n lightStart = 0, lightEnd = 100\n) : HSLColor => {\n const h = getRandom(hueStart, hueEnd);\n const s = getRandom(saturationStart, saturationEnd);\n const l = getRandom(lightStart, lightEnd);\n return [h, s, l];\n};\n\n// ----------------------- CONVERT COLORS --------------------------------------\n\n/**\n * helper: convert hue value to %\n * @param {number} h\n * @return {number} [0, 100] %\n */\nconst convertHueToPercent = (h : number) : number => {\n\n // the hue value needs to be multiplied by 60 to convert it to degrees\n h *= 60;\n\n // if hue becomes negative, you need to add 360 to, because a circle has 360 degrees\n if(h < 0){\n h += 360;\n }\n\n // convert huw to %\n return h * 100 / 360;\n};\n\n/**\n * get hue from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] % - we use here % instead of [0, 359] degrees\n */\nconst getHue = (r : number, g : number, b : number, min : number | undefined = undefined, max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no hue, as it's gray\n if(min === max) return 0;\n\n // if red is max\n if(max === r){\n return convertHueToPercent((g - b) / (max - min));\n }\n\n // if green is max\n if(max === g){\n return convertHueToPercent(2.0 + (b - r) / (max - min));\n }\n\n // if blue is max\n if(max === b){\n return convertHueToPercent(4.0 + (r - g) / (max - min));\n }\n\n return 0;\n};\n\n/**\n * get luminance from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @return {number} [0, 100] %\n */\nconst getLuminance = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // calculate the luminance value\n // @ts-ignore\n const l = (min + max) / 2; // [0, 1]\n\n // return l value in %\n return l * 100;\n};\n\n/**\n * get saturation from RGB\n * @param {number} r [0, 255]\n * @param {number} g [0, 255]\n * @param {number} b [0, 255]\n * @param {number|undefined=} min - min number of [r, g, b]\n * @param {number|undefined=} max - max number of [r, g, b]\n * @param {number|undefined=} l - luminance in [0, 100] %\n * @return {number} [0, 100] %\n */\nconst getSaturation = (\n r : number,\n g : number,\n b : number,\n min : number | undefined = undefined,\n max : number | undefined = undefined,\n l : number | undefined = undefined) : number => {\n\n // find the minimum and maximum values of r, g, and b if they are not provided\n min = (min === undefined) ? Math.min(r, g, b) : min;\n max = (min === undefined) ? Math.max(r, g, b) : max;\n\n // if the min and max value are the same -> no saturation, as it's gray\n if(min === max) return 0;\n\n // calculate luminance if it's not provided\n l = (l === undefined) ? getLuminance(r, g, b) : l;\n\n // check the level of luminance\n const s = (l <= 50) ?\n // @ts-ignore\n ((max - min) / (max + min)) : // this formula is used when luminance <= 50%\n // @ts-ignore\n (max - min) / (2.0 - max - min); // this formula is used when luminance > 50%\n\n // return saturation in %\n return s * 100;\n};\n\nexport const rgbToHsl = (rgb: RGBColor, decimalPlaces = Infinity): HSLColor => {\n\n // convert rgb values to the range [0, 1]\n const r = rgb[0] / 255;\n const g = rgb[1] / 255;\n const b = rgb[2] / 255;\n\n // find the minimum and maximum values of r, g, and b\n const min = Math.min(r, g, b);\n const max = Math.max(r, g, b);\n\n // calculate the luminance value in %\n const l = getLuminance(r, g, b, min, max);\n\n // calculate the saturation in %\n const s = getSaturation(r, g, b, min, max, l);\n\n // calculate the hue in % (not in degrees!)\n const h = getHue(r, g, b, min, max);\n\n if(h > 360 || s > 100 || l > 100){\n return [0, 0, 100];\n }\n\n if(h < 0 || s < 0 || l < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(h, decimalPlaces),\n setDecimalPlaces(s, decimalPlaces),\n setDecimalPlaces(l, decimalPlaces),\n ];\n};\n\n/**\n * helper: HSL to RGB\n */\nconst hslToRgbHelper = (helper1 : number, helper2 : number, colorHelper : number) : number => {\n\n // all values need to be between 0 and 1\n // if you get a negative value you need to add 1 to it\n if(colorHelper < 0) colorHelper += 1;\n\n // if you get a value above 1 you need to subtract 1 from it.\n if(colorHelper > 1) colorHelper -= 1;\n\n if(colorHelper * 6 < 1) return helper2 + (helper1 - helper2) * 6 * colorHelper;\n\n if(colorHelper * 2 < 1) return helper1;\n\n if(colorHelper * 3 < 2){\n return helper2 + (helper1 - helper2) * (0.666 - colorHelper) * 6;\n }\n else{\n return helper2;\n }\n};\n\nexport const hslToRgb = (hsl: HSLColor, decimalPlaces = Infinity): RGBColor => {\n\n // convert all values to [0, 1] from %\n const h = hsl[0] / 100;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n // if there is no saturation -> it\u2019s grey\n if(s === 0){\n // convert the luminance from [0, 1] to [0, 255]\n const gray = l * 255;\n return [gray, gray, gray];\n }\n\n // check the level of luminance\n const helper1 = (l < 0.5) ?\n (l * (1.0 + s)) :\n (l + s - l * s);\n\n const helper2 = 2 * l - helper1;\n\n const rHelper = h + 0.333;\n const gHelper = h;\n const bHelper = h - 0.333;\n\n let r = hslToRgbHelper(helper1, helper2, rHelper);\n let g = hslToRgbHelper(helper1, helper2, gHelper);\n let b = hslToRgbHelper(helper1, helper2, bHelper);\n\n // convert rgb to [0, 255]\n r *= 255;\n g *= 255;\n b *= 255;\n\n if(r > 255 || g > 255 || b > 255){\n return [255, 255, 255];\n }\n\n if(r < 0 || g < 0 || b < 0){\n return [0, 0, 0];\n }\n\n return [\n setDecimalPlaces(r, decimalPlaces),\n setDecimalPlaces(g, decimalPlaces),\n setDecimalPlaces(b, decimalPlaces),\n ];\n};\n\n/**\n * HSL to hex\n * hslToHex(360, 100, 50) // [360, 100, 5] ==> \"#ff0000\" (red)\n */\nexport const hslToHex = (hsl: HSLColor) => {\n\n if(hsl[0] > 360 || hsl[1] > 100 || hsl[2] > 100){\n return '#ffffff';\n }\n\n if(hsl[0] < 0 || hsl[1] < 0 || hsl[2] < 0){\n return '#000000';\n }\n\n const h = hsl[0] / 360;\n const s = hsl[1] / 100;\n const l = hsl[2] / 100;\n\n let r, g, b;\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n};\n\n// ----------------------- GET SHIFTED COLORS --------------------------------------\n\nexport const getShiftedHue = (color: HSLColor, shift = 180) : HSLColor => {\n let hue = color[0];\n hue += shift;\n\n if (hue > 360 || hue < 0) {\n hue = mod(hue, 360);\n }\n\n return [hue, color[1], color[2]];\n};\n\nexport const getShiftedLightness = (color: HSLColor, shift = 10) : HSLColor => {\n let lightness = color[2];\n lightness += shift;\n\n if (lightness > 100 || lightness < 0) {\n lightness = mod(lightness, 100);\n }\n\n return [color[0], color[1], lightness];\n};\n\nexport const getShiftedSaturation = (color: HSLColor, shift = 10) : HSLColor => {\n let saturation = color[1];\n saturation += shift;\n\n if (saturation > 100) {\n saturation -= 100;\n }\n\n if(saturation < 0){\n saturation += 100;\n }\n\n return [color[0], saturation, color[2]];\n};\n", "/**\n * guid like '932ade5e-c515-4807-ac01-73b20ab3fb66'\n */\nexport const guid = () => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);\n });\n};\n\n/**\n * id like 'df4unio1opulby2uqh4'\n */\nexport const newId = () => {\n return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);\n};\n", "import { ICircle, IPolygon, IRect, Matrix2, Vector2 } from '../types';\nimport { mod } from './other';\nimport { v2GetNormal, v2DotProduct } from './linear-algebra/vector';\n\n/**\n * Rectangles collision detection.\n * Rectangles should not be rotated.\n * The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles.\n * Any gap means a collision does not exist.\n * Returns true if collision is detected.\n */\nexport const rectCollide = (rect1: IRect, rect2: IRect) : boolean => {\n return rect1.x <= rect2.x + rect2.w &&\n rect1.x + rect1.w >= rect2.x &&\n rect1.y <= rect2.y + rect2.h &&\n rect1.h + rect1.y >= rect2.y;\n};\n\n/**\n * Circles collision detection.\n * This algorithm works by taking the center points of the two circles\n * and ensuring the distance between the center points\n * are less than the two radii added together.\n * Returns true if collision is detected.\n */\nexport const circleCollide = (circle1: ICircle, circle2: ICircle) => {\n const dx = Math.abs(circle1.cx - circle2.cx);\n const dy = Math.abs(circle1.cy - circle2.cy);\n const distance = Math.sqrt(dx * dx + dy * dy);\n return distance <= circle1.r + circle2.r;\n};\n\n//-------------------- Separating Axis Theorem (SAT) Collision detection -------------------------\n\nconst getEdges = (poly: IPolygon) : Matrix2[] => {\n const edges: Matrix2[] = [];\n\n for(let i= 0; i {\n const edges: Matrix2[] = [];\n\n // collect polygon edges, and combine then into a single array\n edges.push(...getEdges(poly1));\n edges.push(...getEdges(poly2));\n\n // for each edge, find the normal vector and project both polygons onto it\n for (const edge of edges) {\n const normal = v2GetNormal(edge[0], edge[1]);\n const p1Proj = projectPolygon(poly1, normal);\n const p2Proj = projectPolygon(poly2, normal);\n\n // Check if the projections overlap\n const isOverlap = p1Proj.max >= p2Proj.min && p2Proj.max >= p1Proj.min;\n\n // Check if the projections overlap; if not, the polygons do not collide\n if (!isOverlap) return false;\n }\n\n // If all tests pass, the polygons overlap and collide\n return true;\n};\n\n/**\n * Project every polygon point onto the normal.\n * Then find min and max.\n */\nconst projectPolygon = (polygon: IPolygon, normal: Vector2): { min: number, max: number } => {\n let min = Infinity;\n let max = -Infinity;\n\n // Project each vertex of the polygon onto the axis\n for (const vertex of polygon) {\n const projection = v2DotProduct(vertex, normal);\n min = Math.min(min, projection);\n max = Math.max(max, projection);\n }\n\n return { min, max };\n};", "export interface IAnimationProps {\n duration?: number;\n callback: (result: IAnimationResult) => void;\n restartOnResize?: boolean;\n resizeCallback?: (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => void;\n}\n\nexport interface IAnimationResult {\n start: () => void;\n stop: () => void;\n pause: () => void;\n resume: () => void;\n restart: () => void;\n isAnimating: () => boolean;\n getStartTime: () => number|undefined;\n getElapsedTime: () => number|undefined;\n getPercent: () => number|undefined;\n getResizeObserver: () => ResizeObserver|undefined;\n}\n\nexport const animate = (props: IAnimationProps) : IAnimationResult => {\n\n const _duration = props.duration !== undefined ? props.duration : Infinity;\n\n let startTime: number|undefined = undefined; // in milliseconds\n let animationId: number|undefined = undefined;\n\n // the time elapsed since the start of the animation (in milliseconds)\n let elapsed: number|undefined = undefined;\n let previousTimeStamp: number|undefined = undefined;\n\n let animating = false;\n let observer: ResizeObserver|undefined = undefined;\n\n // -------------------- COMMANDS ---------------------\n\n const stop = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = false;\n\n /*if(observer !== undefined){\n observer.disconnect();\n observer = undefined;\n }*/\n\n if(animationId === undefined) return;\n window.cancelAnimationFrame(animationId);\n };\n\n const restart = () => {\n stop();\n start();\n };\n\n const pause = () => {\n animating = false;\n };\n\n const resume = () => {\n animating = true;\n };\n\n /**\n * Animation Step.\n * @param {number} timeStamp in milliseconds\n */\n const step = (timeStamp: DOMHighResTimeStamp) => {\n\n if (startTime === undefined) {\n startTime = timeStamp;\n }\n\n // the time elapsed since the start of the animation (in milliseconds)\n elapsed = timeStamp - startTime;\n\n if (animating && previousTimeStamp !== timeStamp && typeof props.callback === 'function') {\n\n // do the rendering .............\n props.callback(getResult());\n }\n\n if(elapsed <= _duration){\n previousTimeStamp = timeStamp;\n animationId = window.requestAnimationFrame(step);\n }\n else{\n stop();\n }\n };\n\n const observerHandler = (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => {\n restart();\n\n if(typeof props.resizeCallback === 'function'){\n props.resizeCallback(_entries, _observer);\n }\n };\n\n const start = () => {\n startTime = undefined;\n elapsed = undefined;\n previousTimeStamp = undefined;\n animating = true;\n\n if(props.restartOnResize && window.ResizeObserver && observer === undefined){\n observer = new ResizeObserver(observerHandler);\n observer.observe(document.body, { box: 'border-box' });\n }\n else{\n animationId = window.requestAnimationFrame(step);\n }\n };\n\n // --------------- GET INFO ----------------------\n\n /**\n * the time elapsed since the start of the animation (in milliseconds)\n */\n const getElapsedTime = () : number|undefined => {\n return elapsed;\n };\n\n const isAnimating = () => {\n return animating;\n };\n\n const getStartTime = () => {\n return startTime;\n };\n\n const getPercent = () => {\n if(_duration === Infinity || elapsed === undefined) return undefined;\n return elapsed * 100 / _duration;\n };\n\n const getResizeObserver = () => {\n return observer;\n };\n\n const getResult = () : IAnimationResult => {\n return {\n\n // commands --------------\n start,\n stop,\n pause,\n resume,\n restart,\n\n // information -------\n isAnimating,\n getElapsedTime,\n getStartTime,\n getPercent,\n getResizeObserver,\n };\n };\n\n return getResult();\n};\n", "import { setDecimalPlaces } from './format';\n\nexport const getCircleCircumference = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * radius, decimalPlaces);\n};\n\nexport const getEllipseCircumference = (radius1: number, radius2: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(2 * Math.PI * Math.sqrt((radius1 ** 2 + radius2 ** 2) / 2), decimalPlaces);\n};\n\nexport const isAngleInCircleArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg ||\n (currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg;\n};\n\n/**\n * get the side of a square inscribed in a circle\n */\nexport const getSquareInCircleSide = (radius: number, decimalPlaces = Infinity) => {\n return setDecimalPlaces(radius * 2 / Math.sqrt(2), decimalPlaces);\n};\n", "import { setDecimalPlaces, Vector2 } from 'mz-math';\n\nexport interface ISvg {\n cx: number;\n cy: number;\n radius: number;\n size: number;\n thickness: number;\n border: number;\n startAngleDeg: number;\n endAngleDeg: number;\n}\n\nexport const getSvg = (\n circleRadius: number,\n circleThickness: number,\n circleBorder: number,\n maxPointerRadius: number,\n startAngleDeg: number,\n endAngleDeg: number\n) : ISvg => {\n\n const thickness = circleThickness + circleBorder * 2;\n\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n const size = circleRadius * 2 + thickness + diff;\n\n const [ cx, cy ] = getSVGCenter(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n return {\n cx,\n cy,\n radius: circleRadius,\n size,\n thickness: circleThickness,\n border: circleBorder,\n startAngleDeg,\n endAngleDeg\n } as ISvg;\n};\n\nexport const getSVGCenter = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : Vector2 => {\n\n const size = getSVGSize(\n circleRadius,\n maxPointerRadius,\n circleThickness,\n circleBorder\n );\n\n const val = setDecimalPlaces(size/2, 2);\n\n return [\n val,\n val,\n ];\n};\n\nexport const getSVGSize = (\n circleRadius: number,\n maxPointerRadius: number,\n circleThickness: number,\n circleBorder: number\n) : number => {\n const thickness = circleThickness + circleBorder * 2;\n const diff = Math.max(0, maxPointerRadius * 2 - thickness);\n return circleRadius * 2 + thickness + diff;\n};", "// Data Defaults --------------------\nexport const DEFAULT_MIN = 0;\nexport const DEFAULT_MAX = 100;\nexport const DEFAULT_STEP = 1;\nexport const DEFAULT_ARROW_STEP = 1;\nexport const DEFAULT_ROUND = 0;\n\n// Path Defaults ---------------------\nexport const DEFAULT_PATH_START_ANGLE = 0;\nexport const DEFAULT_PATH_END_ANGLE = 360;\nexport const DEFAULT_PATH_RADIUS = 150;\nexport const DEFAULT_PATH_THICKNESS = 5;\nexport const DEFAULT_PATH_BG_COLOR = '#efefef';\nexport const DEFAULT_PATH_BORDER = 0;\nexport const DEFAULT_PATH_BORDER_COLOR = '#444444';\n\n// Pointer Defaults ------------------\nexport const DEFAULT_POINTER_RADIUS = 10;\nexport const DEFAULT_POINTER_BG_COLOR = '#163a86';\nexport const DEFAULT_POINTER_BG_COLOR_SELECTED = '#000';\nexport const DEFAULT_POINTER_BG_COLOR_DISABLED = '#a8a8a8';\nexport const DEFAULT_POINTER_BORDER = 0;\nexport const DEFAULT_POINTER_BORDER_COLOR = '#000';\n\n// Connection Defaults ------------------\nexport const DEFAULT_CONNECTION_BG_COLOR = '#5daed2';\nexport const DEFAULT_CONNECTION_BG_COLOR_DISABLED = '#97b0bb';\n\n// Text Defaults ------------------------\nexport const DEFAULT_TEXT_COLOR = '#000';\nexport const DEFAULT_TEXT_FONT_SIZE = 16;\n\n// Ticks Defaults -----------------------\nexport const DEFAULT_TICKS_ENABLED = false;\nexport const DEFAULT_TICKS_WIDTH = 3;\nexport const DEFAULT_TICKS_HEIGHT = 10;\nexport const DEFAULT_TICKS_COLOR = '#efefef';\nexport const DEFAULT_TICKS_VALUES_COLOR = '#000';\nexport const DEFAULT_TICKS_VALUES_FONT_SIZE = 12;\nexport const DEFAULT_TICKS_GROUP_SIZE = 10;\nexport const DEFAULT_TICKS_VALUES_DISTANCE = 15;\n\n// Animation Defaults -----------------------\nexport const DEFAULT_ANIMATION_DURATION = 200;\n\n\n", "import { isNumber } from 'mz-math';\n\nexport const getNumber = (value: number|string|undefined|null, defaultValue: number) : number => {\n return isNumber(value) ? Number(value) : defaultValue;\n};\n\nexport const getString = (value: string|undefined|null, defaultValue: string) : string => {\n return value === undefined || value === null ? defaultValue : value;\n};\n\nexport const getBoolean = (value: boolean|undefined|null, defaultValue: boolean) : boolean => {\n return value === undefined || value === null ? defaultValue : value;\n};", "import { mod } from 'mz-math';\n\nexport interface ICircle {\n strokeDasharray: string;\n strokeOffset: number;\n}\n\nexport const isAngleInArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n return (currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg) ||\n ((currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg);\n};\n\nexport const getAnglesDistance = (startAngle: number, endAngle: number) => {\n if(endAngle < startAngle) {\n endAngle += 360;\n }\n\n const diff = endAngle - startAngle;\n const diffMod = mod(diff, 360);\n\n return diffMod === 0 && diff > 0 ? 360 : diffMod;\n};\n\nexport const getCircle = (\n startAngleDeg: number,\n endAngleDeg: number,\n radius: number,\n) : ICircle => {\n\n if(startAngleDeg > endAngleDeg) {\n endAngleDeg += 360;\n }\n\n const circumference = 2 * Math.PI * radius;\n const angleDiff = endAngleDeg - startAngleDeg;\n const strokeOffset = -(startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDiff / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n return {\n strokeDasharray: [ strokeDasharray, complement ].join(' '),\n strokeOffset,\n } as ICircle;\n};", "import {\n Vector2,\n convertRange,\n mod,\n setDecimalPlaces,\n v2Sub,\n radiansToDegrees,\n degreesToRadians, circleMovement, v2Distance\n} from 'mz-math';\nimport { ISettings } from './settings-provider';\nimport {\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_POINTER_BG_COLOR,\n DEFAULT_POINTER_BG_COLOR_DISABLED,\n DEFAULT_POINTER_BG_COLOR_SELECTED,\n DEFAULT_POINTER_BORDER,\n DEFAULT_POINTER_BORDER_COLOR,\n DEFAULT_POINTER_RADIUS,\n} from './defaults-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport { IData } from './data-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IPointer {\n id: string;\n index: number;\n radius: number;\n angleDeg: number;\n prevAngleDeg: number;\n\n bgColor: string;\n bgColorSelected: string;\n bgColorDisabled: string;\n bgColorHover: string;\n\n border: number;\n borderColor: string;\n\n disabled: boolean;\n ariaLabel?: string;\n}\n\nexport interface IPointers {\n pointers: IPointer[];\n maxRadius: number;\n}\n\nexport const getAngleByMouse = (\n $svg: SVGSVGElement,\n clientX: number,\n clientY: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number\n) => {\n const { left, top } = $svg.getBoundingClientRect();\n\n const relativeMouse: Vector2 = [\n clientX - left,\n clientY - top,\n ];\n\n const vector = v2Sub(relativeMouse, [ cx, cy ]);\n\n let angleRad = Math.atan2(vector[1] / ry, vector[0] / rx);\n if(angleRad < 0){\n angleRad += 2 * Math.PI;\n }\n\n return radiansToDegrees(angleRad);\n};\n\nexport const angle2value = (data: IData, angle: number, pathStartAngle: number, pathEndAngle: number) : string | number => {\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(angle < pathStartAngle){\n angle += 360;\n }\n\n let value: string|number = convertRange(angle, pathStartAngle, pathEndAngle, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n return value;\n};\n\nconst value2angle = (data: IData, value: string | number, pathStartAngle: number, pathEndAngle: number) => {\n let _value: number;\n\n if(pathEndAngle < pathStartAngle) {\n pathEndAngle += 360;\n }\n\n if(data.data.length > 0) {\n const valueIndex = data.data.findIndex(item => item === value);\n _value = valueIndex === -1 ? 0 : valueIndex;\n }\n else{\n _value = typeof value !== 'number' ? data.min : value;\n }\n\n return mod(convertRange(_value, data.min, data.max, pathStartAngle, pathEndAngle), 360);\n};\n\nexport const initPointers = (\n settings: ISettings,\n data: IData\n) : IPointer[] => {\n\n if(!settings || !settings.pointers || settings.pointers.length < 0 || !data) {\n const angleDeg = mod(getNumber(settings.pathStartAngle, DEFAULT_PATH_START_ANGLE), 360);\n\n const bgColor = getString(settings.pointerBgColor, DEFAULT_POINTER_BG_COLOR);\n const bgColorSelected = getString(settings.pointerBgColorSelected, DEFAULT_POINTER_BG_COLOR_SELECTED);\n const bgColorDisabled = getString(settings.pointerBgColorDisabled, DEFAULT_POINTER_BG_COLOR_DISABLED);\n const bgColorHover = getString(settings.pointerBgColorHover, bgColorSelected);\n\n return [{\n id: '0',\n index: 0,\n radius: getNumber(settings.pointerRadius, DEFAULT_POINTER_RADIUS),\n angleDeg,\n prevAngleDeg: angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border: getNumber(settings.pointerBorder, DEFAULT_POINTER_BORDER),\n borderColor: getString(settings.pointerBorderColor, DEFAULT_POINTER_BORDER_COLOR),\n disabled: !!settings.disabled,\n }]\n }\n\n const pointers: IPointer[] = [];\n\n for(let i=0; i {\n\n const pointers = initPointers(settings, data);\n\n return {\n pointers,\n maxRadius: getMaxRadius(pointers),\n }\n};\n\nconst getMaxRadius = (pointers: IPointer[]) : number => {\n if(pointers.length <= 0) return 0;\n\n let max = -Infinity;\n\n for(const pointer of pointers){\n max = Math.max(max, Math.max(0, pointer.radius + pointer.border/2));\n }\n\n return max;\n};\n\nexport const getClosestPointer = (\n pointers: IPointer[],\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n if(!pointers || pointers.length <= 0) return null;\n\n if(pointers.length === 1) return pointers[0];\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n let min: number|undefined = undefined;\n let closestPointer: IPointer = null;\n\n const enabledPointers = pointers.filter(p => !p.disabled);\n\n for(const pointer of enabledPointers) {\n const pointerAngleRad = convertRange(degreesToRadians(pointer.angleDeg), 0, Math.PI * 2, 0, Math.PI);\n const pointOnArc = circleMovement([ cx, cy ], pointerAngleRad, pathRadius);\n const distance = v2Distance(currentPointOnArc, pointOnArc);\n\n if(min === undefined || distance < min) {\n min = distance;\n closestPointer = pointer;\n }\n }\n\n return { ...closestPointer };\n};\n\nexport const getClosestEdge = (\n startAngleDegrees: number,\n endAngleDegrees: number,\n currentPlaceDegrees: number,\n cx: number,\n cy: number,\n pathRadius: number\n) => {\n\n const angleRad = convertRange(degreesToRadians(currentPlaceDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const currentPointOnArc = circleMovement([ cx, cy ], angleRad, pathRadius);\n\n const startAngleRad = convertRange(degreesToRadians(startAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const startPointOnArc = circleMovement([ cx, cy ], startAngleRad, pathRadius);\n\n const endAngleRad = convertRange(degreesToRadians(endAngleDegrees), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const endPointOnArc = circleMovement([ cx, cy ], endAngleRad, pathRadius);\n\n const distance1 = v2Distance(currentPointOnArc, startPointOnArc);\n const distance2 = v2Distance(currentPointOnArc, endPointOnArc);\n\n return distance1 <= distance2 ? startAngleDegrees : endAngleDegrees;\n};\n\nexport const getMinMaxDistancePointers = (pointers: IPointer[], pathStartAngle: number) : [IPointer, IPointer] | null => {\n if(!pointers || pointers.length <= 0) return null;\n\n let minDistance = undefined;\n let maxDistance = undefined;\n let minPointer = null;\n let maxPointer = null;\n\n for(const pointer of pointers) {\n\n const distance = getAnglesDistance(pathStartAngle, pointer.angleDeg);\n\n if(minDistance === undefined || distance < minDistance) {\n minPointer = pointer;\n minDistance = distance;\n }\n\n if(maxDistance === undefined || distance > maxDistance) {\n maxPointer = pointer;\n maxDistance = distance;\n }\n }\n\n if(minPointer === null || maxPointer === null) return null;\n\n return [\n minPointer,\n maxPointer\n ];\n};\n\nexport const roundToStep = (angleDeg: number, step: number, pathStartAngle: number, pathEndAngle: number) : number => {\n if((mod(angleDeg, 360) === mod(pathStartAngle, 360)) ||\n (mod(angleDeg, 360) === mod(pathEndAngle, 360))) return angleDeg;\n return step === 0 ? 0 : Math.round(angleDeg / step) * step;\n};\n", "import { angle2value, getAngleByMouse, getClosestEdge, IPointer } from '../domain/pointers-provider';\nimport {\n useEffect,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n KeyboardEvent,\n useRef, useCallback,\n} from 'react';\nimport { circleMovement, convertRange, degreesToRadians, Vector2 } from 'mz-math';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { isAngleInArc } from '../domain/circle-provider';\nimport { IData } from '../domain/data-provider';\nimport { outlineNoneStyle } from '../domain/style-provider';\nimport { DEFAULT_POINTER_BG_COLOR } from '../domain/defaults-provider';\n\nexport interface IPointerProps {\n settings: ISettings;\n pointer: IPointer;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst getPointerFill = (\n pointer: IPointer,\n selectedPointerId: string,\n bgColor: string,\n bgColorSelected: string,\n bgColorDisabled: string,\n bgColorHover: string,\n isMouseOver: boolean\n) => {\n if(pointer.disabled) return bgColorDisabled;\n\n if(isMouseOver) return bgColorHover;\n\n if(pointer.id === selectedPointerId) {\n return bgColorSelected;\n }\n\n return bgColor;\n};\n\nconst Pointer = (props: IPointerProps) => {\n\n const pointerRef = useRef(null);\n\n const {\n pointer, svg, $svg, data, settings,\n setPointer, selectedPointerId,\n } = props;\n\n const {\n radius,\n angleDeg,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n border,\n borderColor,\n } = props.pointer;\n\n const { cx, cy } = svg;\n\n const [ center, setCenter ] = useState(null);\n const [ value, setValue ] = useState('');\n const [ fill, setFill ] = useState(DEFAULT_POINTER_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n useEffect(() => {\n setFill(getPointerFill(\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ));\n }, [\n pointer,\n selectedPointerId,\n bgColor,\n bgColorSelected,\n bgColorDisabled,\n bgColorHover,\n isMouseOver\n ]);\n\n useEffect(() => {\n const value = angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n );\n setValue(value === undefined ? '' : value.toString())\n }, [\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const angleRad = convertRange(degreesToRadians(angleDeg), 0, Math.PI * 2, 0, Math.PI); // [0, Math.PI*2] ---> [0, Math.PI]\n const pointerCenter = circleMovement([cx, cy], angleRad, svg.radius);\n setCenter(pointerCenter);\n }, [\n angleDeg,\n cx,\n cy,\n svg.radius,\n ]);\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent | TouchEvent | ReactTouchEvent) => {\n if(!$svg || settings.disabled || pointer.disabled) return;\n\n const mouseX = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientX : (evt as TouchEvent).touches[0].clientX;\n const mouseY = evt.type.indexOf('mouse') !== -1 ? (evt as MouseEvent).clientY : (evt as TouchEvent).touches[0].clientY;\n\n const degrees = getAngleByMouse(\n $svg,\n mouseX,\n mouseY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n let newAngleDeg;\n\n if(!isAngleInArc(\n svg.startAngleDeg,\n svg.endAngleDeg,\n degrees\n )){\n newAngleDeg = getClosestEdge(\n svg.startAngleDeg,\n svg.endAngleDeg,\n pointer.angleDeg,\n svg.cx,\n svg.cy,\n svg.radius\n );\n }\n else{\n newAngleDeg = degrees;\n }\n\n setPointer(pointer, newAngleDeg);\n }, [\n $svg,\n pointer,\n setPointer,\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n settings.disabled,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n const onKeyDown = (evt: KeyboardEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.keyboardDisabled) return;\n\n switch (evt.key) {\n case 'ArrowLeft': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowRight': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowUp': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg - data.arrowStepAngleDeg);\n break;\n }\n\n case 'ArrowDown': {\n evt.preventDefault();\n setPointer(pointer, pointer.angleDeg + data.arrowStepAngleDeg);\n break;\n }\n }\n };\n\n useEffect(() => {\n const $current = pointerRef.current;\n\n const onTouch = (evt: TouchEvent | ReactTouchEvent) => {\n if(settings.disabled || pointer.disabled) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n onValueChange(evt);\n };\n\n const onWheel = (evt: WheelEvent) => {\n\n if(settings.disabled || pointer.disabled || settings.mousewheelDisabled || document.activeElement !== $current) return;\n\n evt.stopPropagation();\n evt.preventDefault();\n\n const scrollTop = evt.deltaY < 0;\n\n let newAngleDeg;\n if(scrollTop) {\n newAngleDeg = pointer.angleDeg + data.arrowStepAngleDeg;\n }\n else{\n newAngleDeg = pointer.angleDeg - data.arrowStepAngleDeg;\n }\n\n setPointer(pointer, newAngleDeg);\n };\n\n $current?.addEventListener('touchmove', onTouch, {\n passive: false,\n });\n\n document.addEventListener('wheel', onWheel, {\n passive: false,\n });\n\n return () => {\n $current?.removeEventListener('touchmove', onTouch);\n document.removeEventListener('wheel', onWheel);\n };\n }, [\n center,\n onValueChange,\n data.arrowStepAngleDeg,\n pointer,\n setPointer,\n settings.disabled,\n settings.mousewheelDisabled,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n center &&\n \n\n {\n !settings.pointerSVG &&\n \n }\n\n {\n settings.pointerSVG &&\n \n { settings.pointerSVG }\n \n }\n \n }\n \n )\n};\n\nexport default Pointer;", "export const outlineNoneStyle = {\n outline: 'none',\n};", "import { IPointer, IPointers } from '../domain/pointers-provider';\nimport Pointer from './Pointer';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\nexport interface IPointersProps {\n pointers: IPointers;\n settings: ISettings;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n selectedPointerId: string;\n}\n\nconst Pointers = (props: IPointersProps) => {\n\n const {\n pointers, settings, svg, $svg, data,\n setPointer, selectedPointerId,\n } = props;\n\n return (\n <>\n {\n pointers.pointers.map(pointer => {\n\n return (\n \n )\n })\n }\n \n )\n};\n\nexport default Pointers;", "import { ISettings } from './settings-provider';\nimport { getNumber } from './common-provider';\nimport {\n DEFAULT_ARROW_STEP,\n DEFAULT_MAX,\n DEFAULT_MIN,\n DEFAULT_PATH_END_ANGLE,\n DEFAULT_PATH_START_ANGLE,\n DEFAULT_ROUND,\n DEFAULT_STEP\n} from './defaults-provider';\nimport { mod } from 'mz-math';\n\nexport interface IData {\n min: number;\n max: number;\n stepAngleDeg: number;\n arrowStepAngleDeg: number;\n round: number;\n data: (string | number)[];\n isClosedShape: boolean;\n}\n\nexport const getData = (setting: ISettings) : IData => {\n\n let min = getNumber(setting.min, DEFAULT_MIN);\n let max = getNumber(setting.max, DEFAULT_MAX);\n const step = getNumber(setting.step, DEFAULT_STEP);\n const arrowStep = getNumber(setting.arrowStep, DEFAULT_ARROW_STEP);\n const round = getNumber(setting.round, DEFAULT_ROUND);\n const data = setting.data || [];\n\n if(data.length > 0) {\n const minIndex = data.findIndex(item => item === min);\n const maxIndex = data.findIndex(item => item === max);\n\n min = minIndex === -1 ? 0 : minIndex;\n max = maxIndex === -1 ? data.length : maxIndex;\n }\n else{\n if(min > max) {\n min = max + DEFAULT_MAX;\n }\n }\n\n const pathStartAngle = getNumber(setting.pathStartAngle, DEFAULT_PATH_START_ANGLE);\n const pathEndAngle = getNumber(setting.pathEndAngle, DEFAULT_PATH_END_ANGLE);\n const isClosedShape = mod(pathStartAngle, 360) === mod(pathEndAngle, 360);\n\n const stepAngleDeg = step * 360 / (max - min);\n const arrowStepAngleDeg = arrowStep * 360 / (max - min);\n\n return {\n min,\n max,\n round,\n data,\n stepAngleDeg,\n arrowStepAngleDeg,\n isClosedShape,\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_CONNECTION_BG_COLOR,\n DEFAULT_CONNECTION_BG_COLOR_DISABLED\n} from '../domain/defaults-provider';\nimport {\n getAngleByMouse,\n getClosestPointer,\n getMinMaxDistancePointers,\n IPointer,\n IPointers\n} from '../domain/pointers-provider';\nimport {\n MouseEvent as ReactMouseEvent,\n useCallback,\n useEffect, useRef,\n useState\n} from 'react';\nimport { getConnection, IConnection } from '../domain/connection-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\nimport { animate, IAnimationResult, mod } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\n\ninterface IConnectionProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n data: IData;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst getStroke = (\n disabled: boolean,\n connectionBgColorDisabled: string,\n connectionBgColor: string,\n isMouseOver: boolean,\n connectionBgColorHover: string\n) => {\n if(disabled) return getString(connectionBgColorDisabled, DEFAULT_CONNECTION_BG_COLOR_DISABLED);\n\n const bgColor = getString(connectionBgColor, DEFAULT_CONNECTION_BG_COLOR);\n\n if(isMouseOver) {\n return getString(connectionBgColorHover, bgColor);\n }\n\n return bgColor;\n};\n\nconst Connection = (props: IConnectionProps) => {\n\n const { settings, pointers, $svg, svg, data, setPointer } = props;\n\n const [ connection, setConnection ] = useState(null);\n const [ animation, setAnimation ] = useState(null);\n const [ stroke, setStroke ] = useState(DEFAULT_CONNECTION_BG_COLOR);\n const [ isMouseOver, setIsMouseOver ] = useState(false);\n\n const rangeDraggingLastAngle = useRef();\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setStroke(getStroke(\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n isMouseOver,\n settings.connectionBgColorHover\n ));\n }, [\n settings.disabled,\n settings.connectionBgColorDisabled,\n settings.connectionBgColor,\n settings.connectionBgColorHover,\n isMouseOver,\n ]);\n\n useEffect(() => {\n setConnection(getConnection(\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n }, [\n pointers,\n svg.radius,\n svg.cx,\n svg.cy,\n svg.startAngleDeg,\n svg.endAngleDeg\n ]);\n\n const onClick = (evt: ReactMouseEvent) => {\n\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // RANGE DRAGGING -------------------------------------------\n\n const onValueChange = useCallback((evt: MouseEvent | ReactMouseEvent) => {\n if(!$svg || settings.disabled || !settings.rangeDragging) return;\n\n const minMaxResult = getMinMaxDistancePointers(pointers.pointers, svg.startAngleDeg);\n if(!minMaxResult) return;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n const mouseDegrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n if(rangeDraggingLastAngle.current === undefined) {\n rangeDraggingLastAngle.current = mouseDegrees;\n return;\n }\n\n const diff = (mouseDegrees - rangeDraggingLastAngle.current);\n if(diff === 0 || Math.abs(diff) < data.stepAngleDeg) return;\n\n setPointer(minPointer, mod(minPointer.angleDeg + diff, 360));\n setPointer(maxPointer, mod(maxPointer.angleDeg + diff, 360));\n\n rangeDraggingLastAngle.current = mouseDegrees;\n }, [\n $svg,\n svg.cx,\n svg.cy,\n svg.radius,\n data.stepAngleDeg,\n pointers.pointers,\n setPointer,\n settings.disabled,\n settings.rangeDragging,\n svg.startAngleDeg,\n ]);\n\n const onMouseUp = () => {\n window.removeEventListener('mousemove', onValueChange);\n window.removeEventListener('mouseup', onValueChange);\n\n rangeDraggingLastAngle.current = undefined;\n };\n\n const onMouseDown = (evt: ReactMouseEvent) => {\n if(!settings.rangeDragging || settings.disabled || pointers.pointers.length <= 1) return;\n\n onValueChange(evt);\n\n window.addEventListener('mousemove', onValueChange);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n const onMouseOver = () => {\n setIsMouseOver(true);\n };\n\n const onMouseOut = () => {\n setIsMouseOver(false);\n };\n\n return (\n <>\n {\n !getBoolean(settings.hideConnection, false) && connection &&\n \n }\n \n )\n};\n\nexport default Connection;", "import { IPointers } from './pointers-provider';\nimport { getAnglesDistance } from './circle-provider';\n\nexport interface IConnection {\n radius: number;\n cx: number;\n cy: number;\n\n // calculated properties ---------\n startAngleDeg: number;\n endAngleDeg: number;\n strokeDasharray: number[];\n strokeOffset: number;\n}\n\nexport const getConnection = (\n pointers: IPointers,\n radius: number,\n cx: number,\n cy: number,\n pathStartAngle: number,\n pathEndAngle: number,\n) : IConnection => {\n\n if(!pointers.pointers || pointers.pointers.length <= 0) return null;\n\n const result : IConnection = {\n radius,\n cx,\n cy,\n\n // calculated properties ---------\n startAngleDeg: pathStartAngle,\n endAngleDeg: pathStartAngle,\n strokeDasharray: [0, 0],\n strokeOffset: 0,\n };\n\n // Define start/end angles.\n if(pointers.pointers.length === 1) {\n result.startAngleDeg = pathStartAngle;\n result.endAngleDeg = pointers.pointers[0].angleDeg;\n }\n else{\n result.startAngleDeg = pointers.pointers[0].angleDeg;\n result.endAngleDeg = pointers.pointers[pointers.pointers.length - 1].angleDeg;\n\n /*const minMaxResult = getMinMaxDistancePointers(pointers.pointers, pathStartAngle);\n if(!minMaxResult) return null;\n\n const [ minPointer, maxPointer ] = minMaxResult;\n\n result.startAngleDeg = minPointer.angleDeg;\n result.endAngleDeg = maxPointer.angleDeg;*/\n }\n\n const pathAnglesDistance = getAnglesDistance(pathStartAngle, pathEndAngle);\n\n if(result.startAngleDeg > result.endAngleDeg) {\n result.endAngleDeg += 360;\n }\n\n let angleDistance = getAnglesDistance(result.startAngleDeg, result.endAngleDeg);\n\n const shouldSwitch = angleDistance > pathAnglesDistance;\n\n if(shouldSwitch) {\n angleDistance = 360 - angleDistance;\n [result.startAngleDeg, result.endAngleDeg] = [result.endAngleDeg, result.startAngleDeg];\n }\n\n const circumference = 2 * Math.PI * radius;\n const strokeOffset = -(result.startAngleDeg / 360) * circumference;\n const strokeDasharray = (angleDistance / 360) * circumference;\n const complement = circumference - strokeDasharray;\n\n result.strokeDasharray = [ strokeDasharray, complement ];\n result.strokeOffset = strokeOffset;\n\n return result;\n};", "import { IAnimationResult, mod } from 'mz-math';\n\nexport const getAnimationProgressAngle = (\n progress: IAnimationResult,\n animationSourceDegrees: number,\n animationTargetDegrees: number,\n startPathAngleDeg: number\n) => {\n let percent = progress.getPercent();\n\n if(percent < 0) {\n percent = 0;\n }\n\n if(percent > 100) {\n percent = 100;\n }\n\n let angle1 = animationSourceDegrees % 360;\n let angle2 = animationTargetDegrees % 360;\n\n if(angle1 < startPathAngleDeg) {\n angle1 += 360;\n }\n\n if(angle2 < startPathAngleDeg) {\n angle2 += 360;\n }\n\n const isClockwise = angle2 > angle1;\n\n if(isClockwise) {\n const clockwiseDistance = (angle2 - angle1 + 360) % 360;\n return mod(animationSourceDegrees + (percent * clockwiseDistance / 100), 360);\n }\n else {\n const counterclockwiseDistance = (angle1 - angle2 + 360) % 360;\n return mod(animationSourceDegrees - (percent * counterclockwiseDistance / 100), 360);\n }\n};", "import { ISettings } from '../domain/settings-provider';\nimport { angle2value, IPointers } from '../domain/pointers-provider';\nimport { getBoolean, getNumber, getString } from '../domain/common-provider';\nimport {\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE\n} from '../domain/defaults-provider';\nimport { useEffect, useState } from 'react';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITextProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n data: IData;\n}\n\nconst Text = (props: ITextProps) => {\n\n const { settings, pointers, svg, data } = props;\n\n const { cx, cy } = svg;\n const [ value, setValue ] = useState('');\n\n useEffect(() => {\n\n const values = pointers.pointers.map(pointer => angle2value(\n data,\n pointer.angleDeg,\n svg.startAngleDeg,\n svg.endAngleDeg\n ));\n\n values.sort((value1, value2) => {\n return value1.toString().localeCompare(\n value2.toString(),\n 'en',\n { numeric: true }\n );\n });\n\n const texts = values.map(value => `${ settings.textPrefix || '' }${ value }${ settings.textSuffix || '' }`);\n\n const textBetween = getString(settings.textBetween, ' ');\n setValue(texts.join(textBetween));\n\n }, [\n data,\n pointers.pointers,\n svg.startAngleDeg,\n svg.endAngleDeg,\n settings.textPrefix,\n settings.textSuffix,\n settings.textBetween,\n ]);\n\n const hideText = getBoolean(settings.hideText, false);\n\n return (\n <>\n {\n !hideText &&\n \n\n { value }\n\n \n }\n \n )\n};\n\nexport default Text;", "import { useEffect, useState, Fragment } from 'react';\nimport { getTicks, getTicksSettings, ITick, ITicks } from '../domain/ticks-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { IData } from '../domain/data-provider';\n\ninterface ITicksProps {\n settings: ISettings;\n svg: ISvg;\n data: IData;\n}\n\nconst Ticks = (props: ITicksProps) => {\n\n const { settings, svg, data } = props;\n\n const [ ticksSettings, setTicksSettings ] = useState(null);\n const [ ticks, setTicks ] = useState([]);\n\n useEffect(() => {\n setTicksSettings(getTicksSettings(settings, data));\n }, [\n settings,\n data,\n ]);\n\n useEffect(() => {\n if(!ticksSettings) return;\n\n let endAngleDeg = svg.endAngleDeg;\n if(endAngleDeg < svg.startAngleDeg) {\n endAngleDeg += 360;\n }\n\n setTicks(getTicks(\n ticksSettings,\n ticksSettings.ticksCount,\n svg.startAngleDeg,\n endAngleDeg,\n svg,\n data\n ));\n }, [\n data,\n svg,\n ticksSettings,\n ]);\n\n return (\n <>\n {\n ticksSettings && ticksSettings.enableTicks &&\n \n {\n ticks.map((tick, i) => {\n const { x, y, x1, y1, textX, textY, showText } = tick;\n\n return (\n \n \n\n {\n showText &&\n \n { settings.tickValuesPrefix }{ tick.tickValue }{ settings.tickValuesSuffix }\n \n }\n \n );\n })\n }\n \n }\n \n )\n};\n\nexport default Ticks;", "import {\n circleMovement,\n convertRange,\n degreesToRadians,\n setDecimalPlaces,\n v2MulScalar,\n v2Normalize\n} from 'mz-math';\nimport { ISvg } from './svg-provider';\nimport { IData } from './data-provider';\nimport { ISettings } from './settings-provider';\nimport { getBoolean, getNumber, getString } from './common-provider';\nimport {\n DEFAULT_TICKS_COLOR, DEFAULT_TICKS_ENABLED, DEFAULT_TICKS_GROUP_SIZE,\n DEFAULT_TICKS_HEIGHT, DEFAULT_TICKS_VALUES_COLOR,\n DEFAULT_TICKS_VALUES_DISTANCE, DEFAULT_TICKS_VALUES_FONT_SIZE,\n DEFAULT_TICKS_WIDTH\n} from './defaults-provider';\n\nexport interface ITicks {\n ticksCount: number;\n enableTicks: boolean;\n ticksWidth: number;\n ticksHeight: number;\n longerTicksHeight: number;\n ticksDistanceToPanel: number;\n tickValuesDistance: number;\n ticksColor: string;\n tickValuesColor: string;\n tickValuesFontSize: number;\n ticksGroupSize: number;\n longerTickValuesOnly: boolean;\n showTickValues: boolean;\n}\n\nexport interface ITick {\n x: number;\n y: number;\n x1: number;\n y1: number;\n textX: number;\n textY: number;\n isLonger: boolean;\n showText: boolean;\n tickValue?: string;\n}\n\nexport const getTicksSettings = (settings: ISettings, data: IData) : ITicks => {\n\n let ticksCount = getNumber(settings.ticksCount, 0);\n if(!ticksCount) {\n if(data.data && data.data.length > 0) {\n ticksCount = data.data.length;\n }\n else{\n ticksCount = data.max;\n }\n }\n\n const ticksHeight = getNumber(settings.ticksHeight, DEFAULT_TICKS_HEIGHT);\n\n return {\n ticksCount,\n enableTicks: getBoolean(settings.enableTicks, DEFAULT_TICKS_ENABLED),\n ticksWidth: getNumber(settings.ticksWidth, DEFAULT_TICKS_WIDTH),\n ticksHeight,\n longerTicksHeight: getNumber(settings.longerTicksHeight, ticksHeight * 2),\n ticksDistanceToPanel: getNumber(settings.ticksDistanceToPanel, 0),\n tickValuesDistance: getNumber(settings.tickValuesDistance, DEFAULT_TICKS_VALUES_DISTANCE),\n ticksColor: getString(settings.ticksColor, DEFAULT_TICKS_COLOR),\n tickValuesColor: getString(settings.tickValuesColor, DEFAULT_TICKS_VALUES_COLOR),\n tickValuesFontSize: getNumber(settings.tickValuesFontSize, DEFAULT_TICKS_VALUES_FONT_SIZE),\n ticksGroupSize: getNumber(settings.ticksGroupSize, DEFAULT_TICKS_GROUP_SIZE),\n longerTickValuesOnly: getBoolean(settings.longerTickValuesOnly, true),\n showTickValues: getBoolean(settings.showTickValues, true),\n };\n};\n\nexport const getTicks = (\n ticksSettings: ITicks,\n ticksCount: number,\n pathStartAngle: number,\n pathEndAngle: number,\n svg: ISvg,\n data: IData\n) : ITick[] => {\n\n const ticks: ITick[] = [];\n\n const deltaAngle = Math.abs(pathEndAngle - pathStartAngle);\n const oneTickAngleSize = ticksCount === 0 ? 0 : deltaAngle / ticksCount;\n\n let count = ticksCount;\n if(!data.isClosedShape) {\n count++;\n }\n\n for(let i=0; i [0, Math.PI]\n\n let [x, y] = circleMovement([svg.cx, svg.cy], angleRad, svg.radius);\n\n const isLonger = ticksSettings.ticksGroupSize !== undefined && (i % ticksSettings.ticksGroupSize === 0 );\n\n let desiredDistance = ticksSettings.ticksHeight;\n\n if(isLonger) {\n desiredDistance = ticksSettings.longerTicksHeight;\n }\n\n const normalizedDirectionVector = v2Normalize([svg.cx - x, svg.cy - y]);\n const tickEndVector = v2MulScalar(normalizedDirectionVector, desiredDistance);\n\n const tickStartVector = v2MulScalar(normalizedDirectionVector, ticksSettings.ticksDistanceToPanel + svg.thickness/2);\n x += tickStartVector[0];\n y += tickStartVector[1];\n\n const x1 = x + tickEndVector[0];\n const y1 = y + tickEndVector[1];\n\n // ------- Define tick value. ---------------------\n let tickValue: string|undefined = undefined;\n if(ticksSettings.showTickValues && (!ticksSettings.longerTickValuesOnly || ticksSettings.longerTickValuesOnly && (isLonger || ticksSettings.ticksGroupSize === undefined))) {\n\n let value: string|number = convertRange(i, 0, ticksCount, data.min, data.max);\n\n if(data.data.length > 0) {\n const index = Math.round(value);\n value = data.data[index];\n }\n else{\n value = setDecimalPlaces(value, data.round);\n }\n\n tickValue = (value ?? '').toString();\n }\n\n let textX = 0;\n let textY = 0;\n const showText = tickValue !== undefined;\n\n if(showText) {\n const _tickValuesDistance = getNumber(desiredDistance + ticksSettings.tickValuesDistance, desiredDistance * 1.5);\n const tickTextVector = v2MulScalar(normalizedDirectionVector, _tickValuesDistance);\n textX = x + tickTextVector[0];\n textY = y + tickTextVector[1];\n }\n\n ticks.push({\n x,\n y,\n x1,\n y1,\n textX,\n textY,\n isLonger,\n tickValue,\n showText,\n });\n }\n\n return ticks;\n};", "import { useEffect, useState, MouseEvent, useRef } from 'react';\nimport { getCircle, ICircle } from '../domain/circle-provider';\nimport { getNumber, getString } from '../domain/common-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport {\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_PATH_BG_COLOR,\n DEFAULT_PATH_BORDER_COLOR,\n} from '../domain/defaults-provider';\nimport { ISvg } from '../domain/svg-provider';\nimport { getAngleByMouse, getClosestPointer, IPointer, IPointers } from '../domain/pointers-provider';\nimport { animate, IAnimationResult, newId } from 'mz-math';\nimport { getAnimationProgressAngle } from '../domain/animation-provider';\nimport InnerCircle from './InnerCircle';\n\ninterface ICircleProps {\n settings: ISettings;\n pointers: IPointers;\n svg: ISvg;\n $svg: SVGSVGElement;\n setPointer: (pointer: IPointer, newAngleDeg: number) => void;\n}\n\nconst Circle = (props: ICircleProps) => {\n\n const { settings, pointers, $svg, svg, setPointer } = props;\n\n const [ animation, setAnimation ] = useState(null);\n const [ maskId ] = useState(newId());\n const [ circle, setCircle ] = useState({\n strokeDasharray: '0 1000000',\n strokeOffset: 0,\n });\n\n const animationClosestPointer = useRef(null);\n const animationSourceDegrees = useRef(0);\n const animationTargetDegrees = useRef(0);\n\n useEffect(() => {\n setCircle(getCircle(\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius\n ));\n }, [\n svg.startAngleDeg,\n svg.endAngleDeg,\n svg.radius,\n ]);\n\n const onClick = (evt: MouseEvent) => {\n if(!$svg || settings.disabled || (animation && animation.isAnimating())) return;\n\n const degrees = getAngleByMouse(\n $svg,\n evt.clientX,\n evt.clientY,\n svg.cx,\n svg.cy,\n svg.radius,\n svg.radius\n );\n\n const closestPointer = getClosestPointer(\n pointers.pointers,\n degrees,\n svg.cx,\n svg.cy,\n svg.radius\n );\n\n if(!closestPointer) return;\n\n if(settings.animateOnClick) {\n animationClosestPointer.current = closestPointer;\n animationSourceDegrees.current = closestPointer.angleDeg;\n animationTargetDegrees.current = degrees;\n animation?.start();\n }\n else{\n setPointer(closestPointer, degrees);\n }\n };\n\n // ANIMATE ON CLICK -------------------------------------------\n useEffect(() => {\n if(animation) {\n animation.stop();\n }\n\n if(!settings.animateOnClick) {\n setAnimation(null);\n return;\n }\n\n const _animation = animate({\n callback: (progress) => {\n if(!animationClosestPointer.current) return;\n const currentDegrees = getAnimationProgressAngle(\n progress,\n animationSourceDegrees.current,\n animationTargetDegrees.current,\n svg.startAngleDeg\n );\n setPointer(animationClosestPointer.current, currentDegrees);\n },\n duration: getNumber(settings.animationDuration, DEFAULT_ANIMATION_DURATION),\n });\n\n setAnimation(_animation);\n },\n // eslint-disable-next-line\n [\n settings.animateOnClick,\n settings.animationDuration,\n ]);\n\n return (\n \n\n {\n settings.pathInnerBgColor &&\n \n }\n\n {\n svg.border > 0 &&\n \n }\n\n \n \n )\n};\n\nexport default Circle;\n", "import { ISvg } from '../domain/svg-provider';\nimport { ISettings } from '../domain/settings-provider';\nimport { ICircle } from '../domain/circle-provider';\nimport { useEffect, useState } from 'react';\nimport { circleMovement, convertRange, degreesToRadians, mod, Vector2 } from 'mz-math';\nimport { getBoolean } from '../domain/common-provider';\n\ninterface IInnerCircleProps {\n maskId: string;\n settings: ISettings;\n svg: ISvg;\n circle: ICircle;\n}\n\nconst InnerCircle = (props: IInnerCircleProps) => {\n\n const { svg, maskId, settings, circle } = props;\n\n const [ startPoint, setStartPoint ] = useState([0, 0]);\n const [ endPoint, setEndPoint ] = useState([0, 0]);\n const [ largeArcFlag, setLargeArcFlag ] = useState(0);\n const [ pathInnerBgFull, setPathInnerBgFull] = useState(false);\n\n useEffect(() => {\n if(mod(svg.startAngleDeg, 360) === mod(svg.endAngleDeg, 360)) {\n setPathInnerBgFull(true);\n return;\n }\n\n setPathInnerBgFull(getBoolean(settings.pathInnerBgFull, false));\n }, [\n settings.pathInnerBgFull,\n svg.startAngleDeg,\n svg.endAngleDeg,\n ]);\n\n useEffect(() => {\n const startAngleDeg = convertRange(svg.startAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setStartPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(startAngleDeg), svg.radius));\n\n const endAngleDeg = convertRange(svg.endAngleDeg, 0, Math.PI*2, 0, Math.PI);\n setEndPoint(circleMovement([svg.cx, svg.cy], degreesToRadians(endAngleDeg), svg.radius));\n\n const largeArcFlag = svg.endAngleDeg - svg.startAngleDeg <= 180 ? 1 : 0;\n setLargeArcFlag(largeArcFlag);\n }, [\n svg.cx,\n svg.cy,\n svg.endAngleDeg,\n svg.radius,\n svg.startAngleDeg,\n ]);\n\n return (\n <>\n {\n !pathInnerBgFull &&\n \n \n \n \n }\n\n \n \n )\n};\n\nexport default InnerCircle;"], + "mappings": "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", "names": ["require_react_production_min", "__commonJSMin", "exports", "l", "n", "p", "q", "r", "t", "u", "v", "w", "x", "y", "z", "A", "a", "B", "C", "D", "E", "b", "e", "F", "G", "H", "I", "J", "K", "L", "M", "d", "c", "k", "h", "g", "f", "m", "N", "O", "escape", "P", "Q", "R", "S", "T", "U", "V", "W", "require_react", "__commonJSMin", "exports", "module", "require_react_jsx_runtime_production_min", "__commonJSMin", "exports", "f", "k", "l", "m", "n", "p", "q", "c", "a", "g", "b", "d", "e", "h", "require_jsx_runtime", "__commonJSMin", "exports", "module", "import_react", "setDecimalPlaces", "num", "decimalPlaces", "coefficient", "__pow", "mod", "n", "m", "convertRange", "x", "a", "b", "c", "d", "isNumber", "value", "radiansToDegrees", "radians", "decimalPlaces", "res", "setDecimalPlaces", "degreesToRadians", "degrees", "vSub", "vector1", "vector2", "decimalPlaces", "vector", "i", "setDecimalPlaces", "v2Sub", "vMulScalar", "v", "scalar", "decimalPlaces", "vector", "i", "setDecimalPlaces", "v2MulScalar", "v2", "vLength", "vector", "decimalPlaces", "sum", "i", "setDecimalPlaces", "v2Distance", "vector1", "vector2", "decimalPlaces", "diff", "vSub", "vLength", "vNormalize", "v", "decimalPlaces", "length", "vLength", "unitVector", "i", "setDecimalPlaces", "v2Normalize", "v2", "circleMovement", "center", "angle", "radius", "newId", "animate", "props", "_duration", "startTime", "animationId", "elapsed", "previousTimeStamp", "animating", "observer", "stop", "restart", "start", "pause", "resume", "step", "timeStamp", "getResult", "observerHandler", "_entries", "_observer", "getElapsedTime", "isAnimating", "getStartTime", "getPercent", "getResizeObserver", "getSvg", "circleRadius", "circleThickness", "circleBorder", "maxPointerRadius", "startAngleDeg", "endAngleDeg", "thickness", "diff", "size", "cx", "cy", "getSVGCenter", "getSVGSize", "val", "s", "DEFAULT_PATH_BG_COLOR", "DEFAULT_PATH_BORDER_COLOR", "DEFAULT_POINTER_BG_COLOR", "DEFAULT_POINTER_BG_COLOR_SELECTED", "DEFAULT_POINTER_BG_COLOR_DISABLED", "DEFAULT_POINTER_BORDER_COLOR", "DEFAULT_CONNECTION_BG_COLOR", "DEFAULT_CONNECTION_BG_COLOR_DISABLED", "DEFAULT_TEXT_COLOR", "DEFAULT_TICKS_COLOR", "DEFAULT_TICKS_VALUES_COLOR", "getNumber", "value", "defaultValue", "H", "getString", "getBoolean", "isAngleInArc", "startAngleDeg", "endAngleDeg", "currentDegrees", "getAnglesDistance", "startAngle", "endAngle", "diff", "diffMod", "y", "getCircle", "radius", "circumference", "angleDiff", "strokeOffset", "strokeDasharray", "complement", "getAngleByMouse", "$svg", "clientX", "clientY", "cx", "cy", "rx", "ry", "left", "top", "relativeMouse", "vector", "R", "angleRad", "Mr", "angle2value", "data", "angle", "pathStartAngle", "pathEndAngle", "value", "j", "index", "s", "value2angle", "_value", "valueIndex", "item", "y", "initPointers", "settings", "angleDeg", "getNumber", "bgColor", "getString", "DEFAULT_POINTER_BG_COLOR", "bgColorSelected", "DEFAULT_POINTER_BG_COLOR_SELECTED", "bgColorDisabled", "DEFAULT_POINTER_BG_COLOR_DISABLED", "bgColorHover", "DEFAULT_POINTER_BORDER_COLOR", "pointers", "i", "settingPointer", "radius", "border", "borderColor", "disabled", "getBoolean", "angleAfterStep", "roundToStep", "getPointers", "getMaxRadius", "max", "pointer", "getClosestPointer", "currentPlaceDegrees", "pathRadius", "hr", "currentPointOnArc", "Kt", "min", "closestPointer", "enabledPointers", "p", "pointerAngleRad", "pointOnArc", "distance", "Er", "__spreadValues", "getClosestEdge", "startAngleDegrees", "endAngleDegrees", "startAngleRad", "startPointOnArc", "endAngleRad", "endPointOnArc", "distance1", "distance2", "getMinMaxDistancePointers", "minDistance", "maxDistance", "minPointer", "maxPointer", "getAnglesDistance", "step", "import_react", "outlineNoneStyle", "import_jsx_runtime", "getPointerFill", "pointer", "selectedPointerId", "bgColor", "bgColorSelected", "bgColorDisabled", "bgColorHover", "isMouseOver", "Pointer", "props", "pointerRef", "svg", "$svg", "data", "settings", "setPointer", "radius", "angleDeg", "border", "borderColor", "cx", "cy", "center", "setCenter", "value", "setValue", "fill", "setFill", "DEFAULT_POINTER_BG_COLOR", "setIsMouseOver", "angle2value", "angleRad", "j", "hr", "pointerCenter", "Kt", "onValueChange", "evt", "mouseX", "mouseY", "degrees", "getAngleByMouse", "newAngleDeg", "isAngleInArc", "getClosestEdge", "onMouseUp", "onMouseDown", "onKeyDown", "$current", "onTouch", "onWheel", "scrollTop", "onMouseOver", "onMouseOut", "outlineNoneStyle", "Pointer_default", "import_jsx_runtime", "Pointers", "props", "pointers", "settings", "svg", "$svg", "data", "setPointer", "selectedPointerId", "pointer", "Pointer_default", "Pointers_default", "getData", "setting", "min", "getNumber", "max", "step", "arrowStep", "round", "data", "minIndex", "item", "maxIndex", "pathStartAngle", "pathEndAngle", "isClosedShape", "y", "stepAngleDeg", "arrowStepAngleDeg", "import_react", "getConnection", "pointers", "radius", "cx", "cy", "pathStartAngle", "pathEndAngle", "result", "pathAnglesDistance", "getAnglesDistance", "angleDistance", "circumference", "strokeOffset", "strokeDasharray", "complement", "getAnimationProgressAngle", "progress", "animationSourceDegrees", "animationTargetDegrees", "startPathAngleDeg", "percent", "angle1", "angle2", "clockwiseDistance", "y", "counterclockwiseDistance", "import_jsx_runtime", "getStroke", "disabled", "connectionBgColorDisabled", "connectionBgColor", "isMouseOver", "connectionBgColorHover", "getString", "DEFAULT_CONNECTION_BG_COLOR_DISABLED", "bgColor", "DEFAULT_CONNECTION_BG_COLOR", "Connection", "props", "settings", "pointers", "$svg", "svg", "data", "setPointer", "connection", "setConnection", "animation", "setAnimation", "stroke", "setStroke", "setIsMouseOver", "rangeDraggingLastAngle", "animationClosestPointer", "animationSourceDegrees", "animationTargetDegrees", "getConnection", "onClick", "evt", "degrees", "getAngleByMouse", "closestPointer", "getClosestPointer", "onValueChange", "minMaxResult", "getMinMaxDistancePointers", "minPointer", "maxPointer", "mouseDegrees", "diff", "y", "onMouseUp", "onMouseDown", "_animation", "Fo", "progress", "currentDegrees", "getAnimationProgressAngle", "getNumber", "onMouseOver", "onMouseOut", "getBoolean", "Connection_default", "import_react", "import_jsx_runtime", "Text", "props", "settings", "pointers", "svg", "data", "cx", "cy", "value", "setValue", "values", "pointer", "angle2value", "value1", "value2", "texts", "textBetween", "getString", "hideText", "getBoolean", "getNumber", "DEFAULT_TEXT_COLOR", "Text_default", "import_react", "getTicksSettings", "settings", "data", "ticksCount", "getNumber", "ticksHeight", "getBoolean", "getString", "DEFAULT_TICKS_COLOR", "DEFAULT_TICKS_VALUES_COLOR", "getTicks", "ticksSettings", "pathStartAngle", "pathEndAngle", "svg", "ticks", "deltaAngle", "oneTickAngleSize", "count", "i", "currentAngle", "angleRad", "j", "hr", "x", "y", "Kt", "isLonger", "desiredDistance", "normalizedDirectionVector", "E", "tickEndVector", "wr", "tickStartVector", "x1", "y1", "tickValue", "value", "index", "s", "textX", "textY", "showText", "_tickValuesDistance", "tickTextVector", "import_jsx_runtime", "Ticks", "props", "settings", "svg", "data", "ticksSettings", "setTicksSettings", "ticks", "setTicks", "getTicksSettings", "endAngleDeg", "getTicks", "tick", "i", "x", "y", "x1", "y1", "textX", "textY", "showText", "Ticks_default", "import_react", "import_react", "import_jsx_runtime", "InnerCircle", "props", "svg", "maskId", "settings", "circle", "startPoint", "setStartPoint", "endPoint", "setEndPoint", "largeArcFlag", "setLargeArcFlag", "pathInnerBgFull", "setPathInnerBgFull", "y", "getBoolean", "startAngleDeg", "j", "Kt", "hr", "endAngleDeg", "InnerCircle_default", "import_jsx_runtime", "Circle", "props", "settings", "pointers", "$svg", "svg", "setPointer", "animation", "setAnimation", "maskId", "Yo", "circle", "setCircle", "animationClosestPointer", "animationSourceDegrees", "animationTargetDegrees", "getCircle", "onClick", "evt", "degrees", "getAngleByMouse", "closestPointer", "getClosestPointer", "_animation", "Fo", "progress", "currentDegrees", "getAnimationProgressAngle", "getNumber", "InnerCircle_default", "getString", "DEFAULT_PATH_BORDER_COLOR", "DEFAULT_PATH_BG_COLOR", "Circle_default", "import_jsx_runtime", "RoundSlider", "props", "data", "setData", "svg", "setSvg", "pointers", "setPointers", "selectedPointerId", "setSelectedPointerId", "prevAngleDegRef", "svgRef", "_data", "getData", "getPointers", "pathStartAngle", "getNumber", "pathEndAngle", "getSvg", "clearSelectedPointer", "evt", "setPointersCallback", "pointer", "newAngleDeg", "roundToStep", "y", "updatePointer", "prevAngle", "nextAngle", "prevIndex", "nextIndex", "prevPointer", "nextPointer", "splitPointDeg", "t1", "t2", "clockwiseNew", "isAngleInArc", "clockwisePrev", "clockwise", "t3", "t4", "counterClockwiseNew", "counterClockwisePrev", "getClosestEdge", "angleChanged", "_a", "_pointers", "__spreadValues", "updatedPointers", "val", "angle2value", "$pointer", "__spreadProps", "outlineNoneStyle", "Circle_default", "Ticks_default", "Connection_default", "Pointers_default", "Text_default"] } diff --git a/src/core/index.tsx b/src/core/index.tsx index 657062f..b5c721d 100644 --- a/src/core/index.tsx +++ b/src/core/index.tsx @@ -189,6 +189,12 @@ export const RoundSlider = (props: ISettings) => { if(nextAngle <= prevAngle) { nextAngle += 360; } + else{ + if(mod(prevAngle, 360) <= mod(nextAngle, 360)) { + prevAngle = mod(prevAngle, 360); + nextAngle = mod(nextAngle, 360); + } + } if(!isAngleInArc(prevAngle, nextAngle, newAngleDeg)){ newAngleDeg = getClosestEdge( diff --git a/src/example/index.tsx b/src/example/index.tsx index d9f4eef..9155184 100644 --- a/src/example/index.tsx +++ b/src/example/index.tsx @@ -370,7 +370,7 @@ export const test2PointersOnCircle = () => { export const testMultiplePointers = () => { return ( <> - {/* { value: 90, } ]} - />*/} + /> { ]} /> - {/* { value: 90, } ]} - />*/} + /> ) }; @@ -1674,8 +1674,8 @@ const App = () => { <> {/*{ testInnerCircle() }*/} {/*{ TestSmallCircle() }*/} - { testMultiplePointers() } - {/*{ test2PointersOnCircle() }*/} + {/*{ testMultiplePointers() }*/} + { test2PointersOnCircle() } {/*{ testTicksProperties() }*/} {/*{ testCirclePathSegments() }*/} {/*{ testBorder() }*/} diff --git a/test/browser/example.min.js b/test/browser/example.min.js index d24b2d4..6f8aa96 100644 --- a/test/browser/example.min.js +++ b/test/browser/example.min.js @@ -4,163 +4,20 @@ https://github.com/mzusin/react-round-slider MIT License Copyright (c) 2023-present, Miriam Zusin */ -(()=>{var RO=Object.create;var Gh=Object.defineProperty,xO=Object.defineProperties,DO=Object.getOwnPropertyDescriptor,AO=Object.getOwnPropertyDescriptors,_O=Object.getOwnPropertyNames,sS=Object.getOwnPropertySymbols,OO=Object.getPrototypeOf,fS=Object.prototype.hasOwnProperty,MO=Object.prototype.propertyIsEnumerable;var cS=(d,v,g)=>v in d?Gh(d,v,{enumerable:!0,configurable:!0,writable:!0,value:g}):d[v]=g,us=(d,v)=>{for(var g in v||(v={}))fS.call(v,g)&&cS(d,g,v[g]);if(sS)for(var g of sS(v))MO.call(v,g)&&cS(d,g,v[g]);return d},dS=(d,v)=>xO(d,AO(v));var Va=(d,v)=>()=>(v||d((v={exports:{}}).exports,v),v.exports);var wO=(d,v,g,E)=>{if(v&&typeof v=="object"||typeof v=="function")for(let y of _O(v))!fS.call(d,y)&&y!==g&&Gh(d,y,{get:()=>v[y],enumerable:!(E=DO(v,y))||E.enumerable});return d};var rt=(d,v,g)=>(g=d!=null?RO(OO(d)):{},wO(v||!d||!d.__esModule?Gh(g,"default",{value:d,enumerable:!0}):g,d));var pS=Va(($e,Af)=>{"use strict";(function(){"use strict";typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var d="18.2.0",v=Symbol.for("react.element"),g=Symbol.for("react.portal"),E=Symbol.for("react.fragment"),y=Symbol.for("react.strict_mode"),L=Symbol.for("react.profiler"),c=Symbol.for("react.provider"),$=Symbol.for("react.context"),V=Symbol.for("react.forward_ref"),F=Symbol.for("react.suspense"),Z=Symbol.for("react.suspense_list"),B=Symbol.for("react.memo"),q=Symbol.for("react.lazy"),k=Symbol.for("react.offscreen"),I=Symbol.iterator,we="@@iterator";function me(s){if(s===null||typeof s!="object")return null;var h=I&&s[I]||s[we];return typeof h=="function"?h:null}var Se={current:null},ue={transition:null},ne={current:null,isBatchingLegacy:!1,didScheduleLegacyUpdate:!1},ge={current:null},fe={},ke=null;function Le(s){ke=s}fe.setExtraStackFrame=function(s){ke=s},fe.getCurrentStack=null,fe.getStackAddendum=function(){var s="";ke&&(s+=ke);var h=fe.getCurrentStack;return h&&(s+=h()||""),s};var Rt=!1,Ae=!1,_e=!1,xe=!1,Ye=!1,ae={ReactCurrentDispatcher:Se,ReactCurrentBatchConfig:ue,ReactCurrentOwner:ge};ae.ReactDebugCurrentFrame=fe,ae.ReactCurrentActQueue=ne;function Be(s){{for(var h=arguments.length,D=new Array(h>1?h-1:0),O=1;O1?h-1:0),O=1;O1){for(var st=Array(Ze),ct=0;ct1){for(var vt=Array(ct),Et=0;Et is not supported and will be removed in a future major release. Did you mean to render instead?")),h.Provider},set:function(te){h.Provider=te}},_currentValue:{get:function(){return h._currentValue},set:function(te){h._currentValue=te}},_currentValue2:{get:function(){return h._currentValue2},set:function(te){h._currentValue2=te}},_threadCount:{get:function(){return h._threadCount},set:function(te){h._threadCount=te}},Consumer:{get:function(){return D||(D=!0,se("Rendering is not supported and will be removed in a future major release. Did you mean to render instead?")),h.Consumer}},displayName:{get:function(){return h.displayName},set:function(te){P||(Be("Setting `displayName` on Context.Consumer has no effect. You should set it directly on the context with Context.displayName = '%s'.",te),P=!0)}}}),h.Consumer=de}return h._currentRenderer=null,h._currentRenderer2=null,h}var kr=-1,va=0,fo=1,po=2;function qa(s){if(s._status===kr){var h=s._result,D=h();if(D.then(function(de){if(s._status===va||s._status===kr){var te=s;te._status=fo,te._result=de}},function(de){if(s._status===va||s._status===kr){var te=s;te._status=po,te._result=de}}),s._status===kr){var O=s;O._status=va,O._result=D}}if(s._status===fo){var P=s._result;return P===void 0&&se(`lazy: Expected the result of a dynamic import() call. Instead received: %s - -Your code should look like: - const MyComponent = lazy(() => import('./MyComponent')) - -Did you accidentally put curly braces around the import?`,P),"default"in P||se(`lazy: Expected the result of a dynamic import() call. Instead received: %s - -Your code should look like: - const MyComponent = lazy(() => import('./MyComponent'))`,P),P.default}else throw s._result}function Zr(s){var h={_status:kr,_result:s},D={$$typeof:q,_payload:h,_init:qa};{var O,P;Object.defineProperties(D,{defaultProps:{configurable:!0,get:function(){return O},set:function(de){se("React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),O=de,Object.defineProperty(D,"defaultProps",{enumerable:!0})}},propTypes:{configurable:!0,get:function(){return P},set:function(de){se("React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),P=de,Object.defineProperty(D,"propTypes",{enumerable:!0})}}})}return D}function Lr(s){s!=null&&s.$$typeof===B?se("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):typeof s!="function"?se("forwardRef requires a render function but was given %s.",s===null?"null":typeof s):s.length!==0&&s.length!==2&&se("forwardRef render functions accept exactly two parameters: props and ref. %s",s.length===1?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined."),s!=null&&(s.defaultProps!=null||s.propTypes!=null)&&se("forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?");var h={$$typeof:V,render:s};{var D;Object.defineProperty(h,"displayName",{enumerable:!1,configurable:!0,get:function(){return D},set:function(O){D=O,!s.name&&!s.displayName&&(s.displayName=O)}})}return h}var Ur;Ur=Symbol.for("react.module.reference");function Wa(s){return!!(typeof s=="string"||typeof s=="function"||s===E||s===L||Ye||s===y||s===F||s===Z||xe||s===k||Rt||Ae||_e||typeof s=="object"&&s!==null&&(s.$$typeof===q||s.$$typeof===B||s.$$typeof===c||s.$$typeof===$||s.$$typeof===V||s.$$typeof===Ur||s.getModuleId!==void 0))}function m(s,h){Wa(s)||se("memo: The first argument must be a component. Instead received: %s",s===null?"null":typeof s);var D={$$typeof:B,type:s,compare:h===void 0?null:h};{var O;Object.defineProperty(D,"displayName",{enumerable:!1,configurable:!0,get:function(){return O},set:function(P){O=P,!s.name&&!s.displayName&&(s.displayName=P)}})}return D}function N(){var s=Se.current;return s===null&&se(`Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: -1. You might have mismatching versions of React and the renderer (such as React DOM) -2. You might be breaking the Rules of Hooks -3. You might have more than one copy of React in the same app -See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.`),s}function Y(s){var h=N();if(s._context!==void 0){var D=s._context;D.Consumer===s?se("Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?"):D.Provider===s&&se("Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?")}return h.useContext(s)}function le(s){var h=N();return h.useState(s)}function He(s,h,D){var O=N();return O.useReducer(s,h,D)}function Ge(s){var h=N();return h.useRef(s)}function Oe(s,h){var D=N();return D.useEffect(s,h)}function ce(s,h){var D=N();return D.useInsertionEffect(s,h)}function Ft(s,h){var D=N();return D.useLayoutEffect(s,h)}function mt(s,h){var D=N();return D.useCallback(s,h)}function gt(s,h){var D=N();return D.useMemo(s,h)}function Sn(s,h,D){var O=N();return O.useImperativeHandle(s,h,D)}function Jr(s,h){{var D=N();return D.useDebugValue(s,h)}}function vo(){var s=N();return s.useTransition()}function Pn(s){var h=N();return h.useDeferredValue(s)}function Ff(){var s=N();return s.useId()}function ha(s,h,D){var O=N();return O.useSyncExternalStore(s,h,D)}var Me=0,Xa,Cl,El,Tl,Rl,xl,Dl;function Al(){}Al.__reactDisabledLog=!0;function gs(){{if(Me===0){Xa=console.log,Cl=console.info,El=console.warn,Tl=console.error,Rl=console.group,xl=console.groupCollapsed,Dl=console.groupEnd;var s={configurable:!0,enumerable:!0,value:Al,writable:!0};Object.defineProperties(console,{info:s,log:s,warn:s,error:s,group:s,groupCollapsed:s,groupEnd:s})}Me++}}function Hf(){{if(Me--,Me===0){var s={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:it({},s,{value:Xa}),info:it({},s,{value:Cl}),warn:it({},s,{value:El}),error:it({},s,{value:Tl}),group:it({},s,{value:Rl}),groupCollapsed:it({},s,{value:xl}),groupEnd:it({},s,{value:Dl})})}Me<0&&se("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var _l=ae.ReactCurrentDispatcher,ki;function Qa(s,h,D){{if(ki===void 0)try{throw Error()}catch(P){var O=P.stack.trim().match(/\n( *(at )?)/);ki=O&&O[1]||""}return` -`+ki+s}}var gr=!1,Ka;{var ho=typeof WeakMap=="function"?WeakMap:Map;Ka=new ho}function ys(s,h){if(!s||gr)return"";{var D=Ka.get(s);if(D!==void 0)return D}var O;gr=!0;var P=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var de;de=_l.current,_l.current=null,gs();try{if(h){var te=function(){throw Error()};if(Object.defineProperty(te.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(te,[])}catch(Ht){O=Ht}Reflect.construct(s,[],te)}else{try{te.call()}catch(Ht){O=Ht}s.call(te.prototype)}}else{try{throw Error()}catch(Ht){O=Ht}s()}}catch(Ht){if(Ht&&O&&typeof Ht.stack=="string"){for(var Ee=Ht.stack.split(` -`),Pe=O.stack.split(` -`),Ze=Ee.length-1,st=Pe.length-1;Ze>=1&&st>=0&&Ee[Ze]!==Pe[st];)st--;for(;Ze>=1&&st>=0;Ze--,st--)if(Ee[Ze]!==Pe[st]){if(Ze!==1||st!==1)do if(Ze--,st--,st<0||Ee[Ze]!==Pe[st]){var ct=` -`+Ee[Ze].replace(" at new "," at ");return s.displayName&&ct.includes("")&&(ct=ct.replace("",s.displayName)),typeof s=="function"&&Ka.set(s,ct),ct}while(Ze>=1&&st>=0);break}}}finally{gr=!1,_l.current=de,Hf(),Error.prepareStackTrace=P}var vt=s?s.displayName||s.name:"",Et=vt?Qa(vt):"";return typeof s=="function"&&Ka.set(s,Et),Et}function Ol(s,h,D){return ys(s,!1)}function Bf(s){var h=s.prototype;return!!(h&&h.isReactComponent)}function Za(s,h,D){if(s==null)return"";if(typeof s=="function")return ys(s,Bf(s));if(typeof s=="string")return Qa(s);switch(s){case F:return Qa("Suspense");case Z:return Qa("SuspenseList")}if(typeof s=="object")switch(s.$$typeof){case V:return Ol(s.render);case B:return Za(s.type,h,D);case q:{var O=s,P=O._payload,de=O._init;try{return Za(de(P),h,D)}catch(te){}}}return""}var bs={},mo=ae.ReactDebugCurrentFrame;function go(s){if(s){var h=s._owner,D=Za(s.type,s._source,h?h.type:null);mo.setExtraStackFrame(D)}else mo.setExtraStackFrame(null)}function Ss(s,h,D,O,P){{var de=Function.call.bind(Mn);for(var te in s)if(de(s,te)){var Ee=void 0;try{if(typeof s[te]!="function"){var Pe=Error((O||"React class")+": "+D+" type `"+te+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof s[te]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw Pe.name="Invariant Violation",Pe}Ee=s[te](h,te,O,D,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(Ze){Ee=Ze}Ee&&!(Ee instanceof Error)&&(go(P),se("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",O||"React class",D,te,typeof Ee),go(null)),Ee instanceof Error&&!(Ee.message in bs)&&(bs[Ee.message]=!0,go(P),se("Failed %s type: %s",D,Ee.message),go(null))}}}function Ja(s){if(s){var h=s._owner,D=Za(s.type,s._source,h?h.type:null);Le(D)}else Le(null)}var yo;yo=!1;function nt(){if(ge.current){var s=Mt(ge.current.type);if(s)return` - -Check the render method of \``+s+"`."}return""}function Vf(s){if(s!==void 0){var h=s.fileName.replace(/^.*[\\\/]/,""),D=s.lineNumber;return` - -Check your code at `+h+":"+D+"."}return""}function Cs(s){return s!=null?Vf(s.__source):""}var Re={};function Es(s){var h=nt();if(!h){var D=typeof s=="string"?s:s.displayName||s.name;D&&(h=` - -Check the top-level render call using <`+D+">.")}return h}function Cn(s,h){if(!(!s._store||s._store.validated||s.key!=null)){s._store.validated=!0;var D=Es(h);if(!Re[D]){Re[D]=!0;var O="";s&&s._owner&&s._owner!==ge.current&&(O=" It was passed a child from "+Mt(s._owner.type)+"."),Ja(s),se('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',D,O),Ja(null)}}}function ei(s,h){if(typeof s=="object"){if(yn(s))for(var D=0;D",P=" Did you accidentally export a JSX literal instead of a component?"):te=typeof s,se("React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",te,P)}var Ee=pa.apply(this,arguments);if(Ee==null)return Ee;if(O)for(var Pe=2;Pe10&&Be("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table."),O._updatedFibers.clear()}}}var Nr=!1,bo=null;function Ml(s){if(bo===null)try{var h=("require"+Math.random()).slice(0,7),D=Af&&Af[h];bo=D.call(Af,"timers").setImmediate}catch(O){bo=function(P){Nr===!1&&(Nr=!0,typeof MessageChannel=="undefined"&&se("This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning."));var de=new MessageChannel;de.port1.onmessage=P,de.port2.postMessage(void 0)}}return bo(s)}var ma=0,wl=!1;function jf(s){{var h=ma;ma++,ne.current===null&&(ne.current=[]);var D=ne.isBatchingLegacy,O;try{if(ne.isBatchingLegacy=!0,O=s(),!D&&ne.didScheduleLegacyUpdate){var P=ne.current;P!==null&&(ne.didScheduleLegacyUpdate=!1,Co(P))}}catch(vt){throw So(h),vt}finally{ne.isBatchingLegacy=D}if(O!==null&&typeof O=="object"&&typeof O.then=="function"){var de=O,te=!1,Ee={then:function(vt,Et){te=!0,de.then(function(Ht){So(h),ma===0?kl(Ht,vt,Et):vt(Ht)},function(Ht){So(h),Et(Ht)})}};return!wl&&typeof Promise!="undefined"&&Promise.resolve().then(function(){}).then(function(){te||(wl=!0,se("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"))}),Ee}else{var Pe=O;if(So(h),ma===0){var Ze=ne.current;Ze!==null&&(Co(Ze),ne.current=null);var st={then:function(vt,Et){ne.current===null?(ne.current=[],kl(Pe,vt,Et)):vt(Pe)}};return st}else{var ct={then:function(vt,Et){vt(Pe)}};return ct}}}}function So(s){s!==ma-1&&se("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. "),ma=s}function kl(s,h,D){{var O=ne.current;if(O!==null)try{Co(O),Ml(function(){O.length===0?(ne.current=null,h(s)):kl(s,h,D)})}catch(P){D(P)}else h(s)}}var ni=!1;function Co(s){if(!ni){ni=!0;var h=0;try{for(;h{"use strict";vS.exports=pS()});var hS=Va(dt=>{"use strict";(function(){"use strict";typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var d=!1,v=!1,g=5;function E(G,ie){var Te=G.length;G.push(ie),c(G,ie,Te)}function y(G){return G.length===0?null:G[0]}function L(G){if(G.length===0)return null;var ie=G[0],Te=G.pop();return Te!==ie&&(G[0]=Te,$(G,Te,0)),ie}function c(G,ie,Te){for(var Qe=Te;Qe>0;){var ot=Qe-1>>>1,Qt=G[ot];if(V(Qt,ie)>0)G[ot]=ie,G[Qe]=Qt,Qe=ot;else return}}function $(G,ie,Te){for(var Qe=Te,ot=G.length,Qt=ot>>>1;QeTe&&(!G||Mn()));){var Qe=Ye.callback;if(typeof Qe=="function"){Ye.callback=null,ae=Ye.priorityLevel;var ot=Ye.expirationTime<=Te,Qt=Qe(ot);Te=dt.unstable_now(),typeof Qt=="function"?Ye.callback=Qt:Ye===y(Ae)&&L(Ae),Xt(Te)}else L(Ae);Ye=y(Ae)}if(Ye!==null)return!0;var xt=y(_e);return xt!==null&&wt(Ot,xt.startTime-Te),!1}function Kr(G,ie){switch(G){case F:case Z:case B:case q:case k:break;default:G=B}var Te=ae;ae=G;try{return ie()}finally{ae=Te}}function fr(G){var ie;switch(ae){case F:case Z:case B:ie=B;break;default:ie=ae;break}var Te=ae;ae=ie;try{return G()}finally{ae=Te}}function Mr(G){var ie=ae;return function(){var Te=ae;ae=ie;try{return G.apply(this,arguments)}finally{ae=Te}}}function Kn(G,ie,Te){var Qe=dt.unstable_now(),ot;if(typeof Te=="object"&&Te!==null){var Qt=Te.delay;typeof Qt=="number"&&Qt>0?ot=Qe+Qt:ot=Qe}else ot=Qe;var xt;switch(G){case F:xt=ge;break;case Z:xt=fe;break;case k:xt=Rt;break;case q:xt=Le;break;case B:default:xt=ke;break}var In=ot+xt,lt={id:xe++,callback:ie,priorityLevel:G,startTime:ot,expirationTime:In,sortIndex:-1};return ot>Qe?(lt.sortIndex=ot,E(_e,lt),y(Ae)===null&<===y(_e)&&(zt?mr():zt=!0,wt(Ot,ot-Qe))):(lt.sortIndex=In,E(Ae,lt),!se&&!Be&&(se=!0,hr(Vn))),lt}function On(){}function dr(){!se&&!Be&&(se=!0,hr(Vn))}function yn(){return y(Ae)}function Zn(G){G.callback=null}function nn(){return ae}var rn=!1,At=null,an=-1,on=g,Mt=-1;function Mn(){var G=dt.unstable_now()-Mt;return!(G125){console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported");return}G>0?on=Math.floor(1e3/G):on=g}var pr=function(){if(At!==null){var G=dt.unstable_now();Mt=G;var ie=!0,Te=!0;try{Te=At(ie,G)}finally{Te?bn():(rn=!1,At=null)}}else rn=!1},bn;if(typeof gn=="function")bn=function(){gn(pr)};else if(typeof MessageChannel!="undefined"){var vr=new MessageChannel,wn=vr.port2;vr.port1.onmessage=pr,bn=function(){wn.postMessage(null)}}else bn=function(){Ne(pr,0)};function hr(G){At=G,rn||(rn=!0,bn())}function wt(G,ie){an=Ne(function(){G(dt.unstable_now())},ie)}function mr(){bt(an),an=-1}var wr=$a,pa=null;dt.unstable_IdlePriority=k,dt.unstable_ImmediatePriority=F,dt.unstable_LowPriority=q,dt.unstable_NormalPriority=B,dt.unstable_Profiling=pa,dt.unstable_UserBlockingPriority=Z,dt.unstable_cancelCallback=Zn,dt.unstable_continueExecution=dr,dt.unstable_forceFrameRate=Ya,dt.unstable_getCurrentPriorityLevel=nn,dt.unstable_getFirstCallbackNode=yn,dt.unstable_next=fr,dt.unstable_pauseExecution=On,dt.unstable_requestPaint=wr,dt.unstable_runWithPriority=Kr,dt.unstable_scheduleCallback=Kn,dt.unstable_shouldYield=Mn,dt.unstable_wrapCallback=Mr,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error)})()});var gS=Va((bM,mS)=>{"use strict";mS.exports=hS()});var yS=Va(lr=>{"use strict";(function(){"use strict";typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var d=Dr(),v=gS(),g=d.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,E=!1;function y(e){E=e}function L(e){if(!E){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r1?t-1:0),r=1;r2&&(e[0]==="o"||e[0]==="O")&&(e[1]==="n"||e[1]==="N")}function In(e,t,n,r){if(n!==null&&n.type===vr)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":{if(r)return!1;if(n!==null)return!n.acceptsBooleans;var a=e.toLowerCase().slice(0,5);return a!=="data-"&&a!=="aria-"}default:return!1}}function lt(e,t,n,r){if(t===null||typeof t=="undefined"||In(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case wt:return!t;case mr:return t===!1;case wr:return isNaN(t);case pa:return isNaN(t)||t<1}return!1}function kn(e){return pt.hasOwnProperty(e)?pt[e]:null}function ut(e,t,n,r,a,i,o){this.acceptsBooleans=t===hr||t===wt||t===mr,this.attributeName=r,this.attributeNamespace=a,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=o}var pt={},Mi=["children","dangerouslySetInnerHTML","defaultValue","defaultChecked","innerHTML","suppressContentEditableWarning","suppressHydrationWarning","style"];Mi.forEach(function(e){pt[e]=new ut(e,vr,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0],n=e[1];pt[t]=new ut(t,wn,!1,n,null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){pt[e]=new ut(e,hr,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){pt[e]=new ut(e,hr,!1,e,null,!1,!1)}),["allowFullScreen","async","autoFocus","autoPlay","controls","default","defer","disabled","disablePictureInPicture","disableRemotePlayback","formNoValidate","hidden","loop","noModule","noValidate","open","playsInline","readOnly","required","reversed","scoped","seamless","itemScope"].forEach(function(e){pt[e]=new ut(e,wt,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){pt[e]=new ut(e,wt,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){pt[e]=new ut(e,mr,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){pt[e]=new ut(e,pa,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){pt[e]=new ut(e,wr,!1,e.toLowerCase(),null,!1,!1)});var Ga=/[\-\:]([a-z])/g,wi=function(e){return e[1].toUpperCase()};["accent-height","alignment-baseline","arabic-form","baseline-shift","cap-height","clip-path","clip-rule","color-interpolation","color-interpolation-filters","color-profile","color-rendering","dominant-baseline","enable-background","fill-opacity","fill-rule","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","glyph-name","glyph-orientation-horizontal","glyph-orientation-vertical","horiz-adv-x","horiz-origin-x","image-rendering","letter-spacing","lighting-color","marker-end","marker-mid","marker-start","overline-position","overline-thickness","paint-order","panose-1","pointer-events","rendering-intent","shape-rendering","stop-color","stop-opacity","strikethrough-position","strikethrough-thickness","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-anchor","text-decoration","text-rendering","underline-position","underline-thickness","unicode-bidi","unicode-range","units-per-em","v-alphabetic","v-hanging","v-ideographic","v-mathematical","vector-effect","vert-adv-y","vert-origin-x","vert-origin-y","word-spacing","writing-mode","xmlns:xlink","x-height"].forEach(function(e){var t=e.replace(Ga,wi);pt[t]=new ut(t,wn,!1,e,null,!1,!1)}),["xlink:actuate","xlink:arcrole","xlink:role","xlink:show","xlink:title","xlink:type"].forEach(function(e){var t=e.replace(Ga,wi);pt[t]=new ut(t,wn,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Ga,wi);pt[t]=new ut(t,wn,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){pt[e]=new ut(e,wn,!1,e.toLowerCase(),null,!1,!1)});var co="xlinkHref";pt[co]=new ut("xlinkHref",wn,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){pt[e]=new ut(e,wn,!1,e.toLowerCase(),null,!0,!0)});var Sl=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i,kr=!1;function va(e){!kr&&Sl.test(e)&&(kr=!0,c("A future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead. React was passed %s.",JSON.stringify(e)))}function fo(e,t,n,r){if(r.mustUseProperty){var a=r.propertyName;return e[a]}else{Mt(n,t),r.sanitizeURL&&va(""+n);var i=r.attributeName,o=null;if(r.type===mr){if(e.hasAttribute(i)){var l=e.getAttribute(i);return l===""?!0:lt(t,n,r,!1)?l:l===""+n?n:l}}else if(e.hasAttribute(i)){if(lt(t,n,r,!1))return e.getAttribute(i);if(r.type===wt)return n;o=e.getAttribute(i)}return lt(t,n,r,!1)?o===null?n:o:o===""+n?n:o}}function po(e,t,n,r){{if(!Qt(t))return;if(!e.hasAttribute(t))return n===void 0?void 0:null;var a=e.getAttribute(t);return Mt(n,t),a===""+n?n:a}}function qa(e,t,n,r){var a=kn(t);if(!xt(t,a,r)){if(lt(t,n,a,r)&&(n=null),r||a===null){if(Qt(t)){var i=t;n===null?e.removeAttribute(i):(Mt(n,t),e.setAttribute(i,""+n))}return}var o=a.mustUseProperty;if(o){var l=a.propertyName;if(n===null){var u=a.type;e[l]=u===wt?!1:""}else e[l]=n;return}var f=a.attributeName,p=a.attributeNamespace;if(n===null)e.removeAttribute(f);else{var S=a.type,b;S===wt||S===mr&&n===!0?b="":(Mt(n,f),b=""+n,a.sanitizeURL&&va(b.toString())),p?e.setAttributeNS(p,f,b):e.setAttribute(f,b)}}}var Zr=Symbol.for("react.element"),Lr=Symbol.for("react.portal"),Ur=Symbol.for("react.fragment"),Wa=Symbol.for("react.strict_mode"),m=Symbol.for("react.profiler"),N=Symbol.for("react.provider"),Y=Symbol.for("react.context"),le=Symbol.for("react.forward_ref"),He=Symbol.for("react.suspense"),Ge=Symbol.for("react.suspense_list"),Oe=Symbol.for("react.memo"),ce=Symbol.for("react.lazy"),Ft=Symbol.for("react.scope"),mt=Symbol.for("react.debug_trace_mode"),gt=Symbol.for("react.offscreen"),Sn=Symbol.for("react.legacy_hidden"),Jr=Symbol.for("react.cache"),vo=Symbol.for("react.tracing_marker"),Pn=Symbol.iterator,Ff="@@iterator";function ha(e){if(e===null||typeof e!="object")return null;var t=Pn&&e[Pn]||e[Ff];return typeof t=="function"?t:null}var Me=Object.assign,Xa=0,Cl,El,Tl,Rl,xl,Dl,Al;function gs(){}gs.__reactDisabledLog=!0;function Hf(){{if(Xa===0){Cl=console.log,El=console.info,Tl=console.warn,Rl=console.error,xl=console.group,Dl=console.groupCollapsed,Al=console.groupEnd;var e={configurable:!0,enumerable:!0,value:gs,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}Xa++}}function _l(){{if(Xa--,Xa===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:Me({},e,{value:Cl}),info:Me({},e,{value:El}),warn:Me({},e,{value:Tl}),error:Me({},e,{value:Rl}),group:Me({},e,{value:xl}),groupCollapsed:Me({},e,{value:Dl}),groupEnd:Me({},e,{value:Al})})}Xa<0&&c("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var ki=g.ReactCurrentDispatcher,Qa;function gr(e,t,n){{if(Qa===void 0)try{throw Error()}catch(a){var r=a.stack.trim().match(/\n( *(at )?)/);Qa=r&&r[1]||""}return` -`+Qa+e}}var Ka=!1,ho;{var ys=typeof WeakMap=="function"?WeakMap:Map;ho=new ys}function Ol(e,t){if(!e||Ka)return"";{var n=ho.get(e);if(n!==void 0)return n}var r;Ka=!0;var a=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var i;i=ki.current,ki.current=null,Hf();try{if(t){var o=function(){throw Error()};if(Object.defineProperty(o.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(o,[])}catch(x){r=x}Reflect.construct(e,[],o)}else{try{o.call()}catch(x){r=x}e.call(o.prototype)}}else{try{throw Error()}catch(x){r=x}e()}}catch(x){if(x&&r&&typeof x.stack=="string"){for(var l=x.stack.split(` -`),u=r.stack.split(` -`),f=l.length-1,p=u.length-1;f>=1&&p>=0&&l[f]!==u[p];)p--;for(;f>=1&&p>=0;f--,p--)if(l[f]!==u[p]){if(f!==1||p!==1)do if(f--,p--,p<0||l[f]!==u[p]){var S=` -`+l[f].replace(" at new "," at ");return e.displayName&&S.includes("")&&(S=S.replace("",e.displayName)),typeof e=="function"&&ho.set(e,S),S}while(f>=1&&p>=0);break}}}finally{Ka=!1,ki.current=i,_l(),Error.prepareStackTrace=a}var b=e?e.displayName||e.name:"",A=b?gr(b):"";return typeof e=="function"&&ho.set(e,A),A}function Bf(e,t,n){return Ol(e,!0)}function Za(e,t,n){return Ol(e,!1)}function bs(e){var t=e.prototype;return!!(t&&t.isReactComponent)}function mo(e,t,n){if(e==null)return"";if(typeof e=="function")return Ol(e,bs(e));if(typeof e=="string")return gr(e);switch(e){case He:return gr("Suspense");case Ge:return gr("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case le:return Za(e.render);case Oe:return mo(e.type,t,n);case ce:{var r=e,a=r._payload,i=r._init;try{return mo(i(a),t,n)}catch(o){}}}return""}function go(e){var t=e._debugOwner?e._debugOwner.type:null,n=e._debugSource;switch(e.tag){case k:return gr(e.type);case Rt:return gr("Lazy");case fe:return gr("Suspense");case xe:return gr("SuspenseList");case V:case Z:case Le:return Za(e.type);case ne:return Za(e.type.render);case F:return Bf(e.type);default:return""}}function Ss(e){try{var t="",n=e;do t+=go(n),n=n.return;while(n);return t}catch(r){return` -Error generating stack: `+r.message+` -`+r.stack}}function Ja(e,t,n){var r=e.displayName;if(r)return r;var a=t.displayName||t.name||"";return a!==""?n+"("+a+")":n}function yo(e){return e.displayName||"Context"}function nt(e){if(e==null)return null;if(typeof e.tag=="number"&&c("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Ur:return"Fragment";case Lr:return"Portal";case m:return"Profiler";case Wa:return"StrictMode";case He:return"Suspense";case Ge:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Y:var t=e;return yo(t)+".Consumer";case N:var n=e;return yo(n._context)+".Provider";case le:return Ja(e,e.render,"ForwardRef");case Oe:var r=e.displayName||null;return r!==null?r:nt(e.type)||"Memo";case ce:{var a=e,i=a._payload,o=a._init;try{return nt(o(i))}catch(l){return null}}}return null}function Vf(e,t,n){var r=t.displayName||t.name||"";return e.displayName||(r!==""?n+"("+r+")":n)}function Cs(e){return e.displayName||"Context"}function Re(e){var t=e.tag,n=e.type;switch(t){case se:return"Cache";case Se:var r=n;return Cs(r)+".Consumer";case ue:var a=n;return Cs(a._context)+".Provider";case _e:return"DehydratedFragment";case ne:return Vf(n,n.render,"ForwardRef");case we:return"Fragment";case k:return n;case q:return"Portal";case B:return"Root";case I:return"Text";case Rt:return nt(n);case me:return n===Wa?"StrictMode":"Mode";case ae:return"Offscreen";case ge:return"Profiler";case Ye:return"Scope";case fe:return"Suspense";case xe:return"SuspenseList";case zt:return"TracingMarker";case F:case V:case Ae:case Z:case ke:case Le:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n;break}return null}var Es=g.ReactDebugCurrentFrame,Cn=null,ei=!1;function ti(){{if(Cn===null)return null;var e=Cn._debugOwner;if(e!==null&&typeof e!="undefined")return Re(e)}return null}function If(){return Cn===null?"":Ss(Cn)}function Kt(){Es.getCurrentStack=null,Cn=null,ei=!1}function St(e){Es.getCurrentStack=e===null?null:If,Cn=e,ei=!1}function Pf(){return Cn}function yr(e){ei=e}function jn(e){return""+e}function Nr(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return bn(e),e;default:return""}}var bo={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0};function Ml(e,t){bo[t.type]||t.onChange||t.onInput||t.readOnly||t.disabled||t.value==null||c("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`."),t.onChange||t.readOnly||t.disabled||t.checked==null||c("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")}function ma(e){var t=e.type,n=e.nodeName;return n&&n.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function wl(e){return e._valueTracker}function jf(e){e._valueTracker=null}function So(e){var t="";return e&&(ma(e)?t=e.checked?"true":"false":t=e.value),t}function kl(e){var t=ma(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t);bn(e[t]);var r=""+e[t];if(!(e.hasOwnProperty(t)||typeof n=="undefined"||typeof n.get!="function"||typeof n.set!="function")){var a=n.get,i=n.set;Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(l){bn(l),r=""+l,i.call(this,l)}}),Object.defineProperty(e,t,{enumerable:n.enumerable});var o={getValue:function(){return r},setValue:function(l){bn(l),r=""+l},stopTracking:function(){jf(e),delete e[t]}};return o}}function ni(e){wl(e)||(e._valueTracker=kl(e))}function Co(e){if(!e)return!1;var t=wl(e);if(!t)return!0;var n=t.getValue(),r=So(e);return r!==n?(t.setValue(r),!0):!1}function Eo(e){if(e=e||(typeof document!="undefined"?document:void 0),typeof e=="undefined")return null;try{return e.activeElement||e.body}catch(t){return e.body}}var Ts=!1,Rs=!1,xs=!1,s=!1;function h(e){var t=e.type==="checkbox"||e.type==="radio";return t?e.checked!=null:e.value!=null}function D(e,t){var n=e,r=t.checked,a=Me({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:r!=null?r:n._wrapperState.initialChecked});return a}function O(e,t){Ml("input",t),t.checked!==void 0&&t.defaultChecked!==void 0&&!Rs&&(c("%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components",ti()||"A component",t.type),Rs=!0),t.value!==void 0&&t.defaultValue!==void 0&&!Ts&&(c("%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components",ti()||"A component",t.type),Ts=!0);var n=e,r=t.defaultValue==null?"":t.defaultValue;n._wrapperState={initialChecked:t.checked!=null?t.checked:t.defaultChecked,initialValue:Nr(t.value!=null?t.value:r),controlled:h(t)}}function P(e,t){var n=e,r=t.checked;r!=null&&qa(n,"checked",r,!1)}function de(e,t){var n=e;{var r=h(t);!n._wrapperState.controlled&&r&&!s&&(c("A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components"),s=!0),n._wrapperState.controlled&&!r&&!xs&&(c("A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components"),xs=!0)}P(e,t);var a=Nr(t.value),i=t.type;if(a!=null)i==="number"?(a===0&&n.value===""||n.value!=a)&&(n.value=jn(a)):n.value!==jn(a)&&(n.value=jn(a));else if(i==="submit"||i==="reset"){n.removeAttribute("value");return}t.hasOwnProperty("value")?Ze(n,t.type,a):t.hasOwnProperty("defaultValue")&&Ze(n,t.type,Nr(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(n.defaultChecked=!!t.defaultChecked)}function te(e,t,n){var r=e;if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var a=t.type,i=a==="submit"||a==="reset";if(i&&(t.value===void 0||t.value===null))return;var o=jn(r._wrapperState.initialValue);n||o!==r.value&&(r.value=o),r.defaultValue=o}var l=r.name;l!==""&&(r.name=""),r.defaultChecked=!r.defaultChecked,r.defaultChecked=!!r._wrapperState.initialChecked,l!==""&&(r.name=l)}function Ee(e,t){var n=e;de(n,t),Pe(n,t)}function Pe(e,t){var n=t.name;if(t.type==="radio"&&n!=null){for(var r=e;r.parentNode;)r=r.parentNode;Mt(n,"name");for(var a=r.querySelectorAll("input[name="+JSON.stringify(""+n)+'][type="radio"]'),i=0;i.")))}):t.dangerouslySetInnerHTML!=null&&(vt||(vt=!0,c("Pass a `value` prop if you set dangerouslyInnerHTML so React knows which value should be selected.")))),t.selected!=null&&!st&&(c("Use the `defaultValue` or `value` props on must be a scalar value if `multiple` is false.%s",n,Ds())}}}}function ga(e,t,n,r){var a=e.options;if(t){for(var i=n,o={},l=0;l.");var r=Me({},t,{value:void 0,defaultValue:void 0,children:jn(n._wrapperState.initialValue)});return r}function rm(e,t){var n=e;Ml("textarea",t),t.value!==void 0&&t.defaultValue!==void 0&&!nm&&(c("%s contains a textarea with both value and defaultValue props. Textarea elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled textarea and remove one of these props. More info: https://reactjs.org/link/controlled-components",ti()||"A component"),nm=!0);var r=t.value;if(r==null){var a=t.children,i=t.defaultValue;if(a!=null){c("Use the `defaultValue` or `value` props instead of setting children on