UNPKG

cdejs

Version:

CanvasDotEffect is a lightweight JS library that helps create customizable and interactive dot-based effects using the Canvas API

2 lines 214 kB
// CanvasDotEffect UMD - v1.3.0 (function(factory){if(typeof define==="function"&&define.amd)define([],factory);else if(typeof module==="object"&&module.exports)module.exports=factory();else if(typeof window!=="undefined")window.CDE=factory();else this.CDE=factory()})(function(){"use strict";class CDEUtils{static DEFAULT_ACCEPTABLE_DIFFERENCE=1e-7;static CIRC=2*Math.PI;static TO_DEGREES=Math.PI/180;static getLast(arr,index=0){return arr[arr.length-1-index]}static addAt(arr,el,index=0){return arr.slice(0,index).concat(el,arr.slice(index))}static random(min,max,decimals=0){if(max+=decimals?0:1,decimals){const precision=10**decimals;return Math.round((Math.random()*(max-min)+min)*precision)/precision}return Math.random()*(max-min)+min|0}static clamp(num,min=1/0,max=1/0){return num<min?min:num>max?max:num}static avg(arr){let a_ll=arr.length,total=0;for(let i=0;i<a_ll;i++)total+=arr[i];return total/a_ll}static isDefined(value){return null!=value}static isFunction(value){return"function"==typeof value}static round(num,decimals=0){const precision=10**decimals;return Math.round(num*precision)/precision}static fade(prog,i=0,minValue=0,maxValue=5){return maxValue-=minValue,i%2?minValue+maxValue*(1-prog):minValue+maxValue*prog}static getRatio(pos1,pos2,limit=100){let p1=pos1.pos||pos1,p2=pos2.pos||pos2;return Math.min(1,CDEUtils.getDist(p1[0],p1[1],p2[0],p2[1])/limit)}static getNearestDots(dot,shape=dot.parent){let dots=shape.dots,d_ll=dots.length,dotX=dot.x,dotY=dot.y,res=[];for(let i=0;i<d_ll;i++){const atDot=dots[i];atDot.id!=dot.id&&res.push([atDot,CDEUtils.getDist(dotX,dotY,atDot.pos[0],atDot.pos[1])])}return res.toSorted(((d1,d2)=>d1[1]-d2[1]))}static getRegulationCB(callback,timeout=1e3){let timeoutId;return(...params)=>{clearTimeout(timeoutId),timeoutId=setTimeout((()=>callback(...params)),timeout)}}static noTimeoutInterval(callback,timeout=1e3){return callback(),setInterval(callback,timeout)}static unlinkArr2(arr){return[arr[0],arr[1]]}static unlinkArr3(arr){return[arr[0],arr[1],arr[2]]}static unlinkPositions(arr){const isArray=Array.isArray,unlinkArr2=CDEUtils.unlinkArr2,o1=arr?.[0],o2=arr?.[1];return isArray(arr)?[isArray(o1)?unlinkArr2(o1):o1,isArray(o2)?unlinkArr2(o2):o2]:arr}static rotatePos(pos=[0,0],deg=0,centerPos=[0,0]){const rad=CDEUtils.toRad(deg),cos=Math.cos(rad),sin=Math.sin(rad),sx=pos[0]-centerPos[0],sy=pos[1]-centerPos[1];return[sx*cos-sy*sin+centerPos[0],sx*sin+sy*cos+centerPos[1]]}static scalePos(pos=[0,0],scale=[1,1],centerPos=[0,0]){const sx=pos[0]-centerPos[0],sy=pos[1]-centerPos[1];return[sx*scale[0]+centerPos[0],sy*scale[1]+centerPos[1]]}static getPositionsCenter(positions){return[(positions[0][0]+positions[1][0])/2,(positions[0][1]+positions[1][1])/2]}static getDist(x1,y1,x2,y2){const dx=x1-x2,dy=y1-y2;return Math.sqrt(dx*dx+dy*dy)}static getDist_pos(pos1,pos2){const dx=pos1[0]-pos2[0],dy=pos1[1]-pos2[1];return Math.sqrt(dx*dx+dy*dy)}static getLinearFn(pos1,pos2){const a=(pos2[1]-pos1[1])/(pos2[0]-pos1[0]),b=-a*pos1[0]+pos1[1];return[a,b,x=>a*x+b,pos1]}static getLinearFn_coords(x1,y1,x2,y2){const a=(y2-y1)/(x2-x1),b=-a*x1+y1;return[a,b,x=>a*x+b,[x1,y1]]}static getPerpendicularLinearFn(linearFnResult){const a=-1/linearFnResult[0],pos=linearFnResult[3],b=-a*pos[0]+pos[1];return[a,b,x=>a*x+b,pos]}static getValueFromRange(minMax){return Array.isArray(minMax)?CDEUtils.random(minMax[0],minMax[1]):minMax}static arrayEquals(arr1,arr2){return arr1.length===arr2.length&&arr1.every(((v,i)=>v==arr2[i]))}static addPos(pos1,pos2){return[(pos1[0]||0)+(pos2[0]||0),(pos1[1]||0)+(pos2[1]||0)]}static subPos(pos1,pos2){return[(pos1[0]||0)-(pos2[0]||0),(pos1[1]||0)-(pos2[1]||0)]}static mulPos(pos1,pos2){return[(pos1[0]||0)*(pos2[0]||0),(pos1[1]||0)*(pos2[1]||0)]}static divPos(pos1,pos2){return[(pos1[0]||0)/(pos2[0]||0),(pos1[1]||0)/(pos2[1]||0)]}static posEquals(arr1,arr2){return arr2&&arr1&&arr1[0]==arr2[0]&&arr1[1]==arr2[1]}static positionsEquals(positions1,positions2){return positions1&&positions2&&positions1[0][0]==positions2[0][0]&&positions1[0][1]==positions2[0][1]&&positions1[1][0]==positions2[1][0]&&positions1[1][1]==positions2[1][1]}static mod(max,ratio,range=max){return max-ratio*range-(range<0)*max}static toRad(deg){return deg*CDEUtils.TO_DEGREES}static toDeg(rad){return rad/CDEUtils.TO_DEGREES}static getAcceptableDiff(num,acceptableDiff=CDEUtils.DEFAULT_ACCEPTABLE_DIFFERENCE){const rounded=Math.round(num);return rounded-num<=acceptableDiff?rounded:num}static getMinMax(arr,propPath=null){let min=1/0,max=-1/0,ll=arr.length;for(let i=0;i<ll;i++){const v=propPath?+arr[i][propPath]:arr[i];v<min&&(min=v),v>max&&(max=v)}return[min,max]}static repeatedTimeout(iterationCount,callback,delay=5){let at=0;for(let i=0;i<iterationCount;i++)setTimeout((()=>callback(i)),at+=delay)}static stackTraceLog(...logs){try{throw new Error("stackTraceLog")}catch(e){console.log(e,...logs)}}}class FPSCounter{static COMMON_REFRESH_RATES=[30,60,75,90,120,144,165,240,360,480,500];static ABNORMAL_FLUCTUATION_THRESHOLD=20;constructor(averageSampleSize){this._averageSampleSize=averageSampleSize||10,this._times=[],this._averageSample=[],this._maxFps=0}getFpsRaw(){let fps,now=performance.now();for(;this._times.length&&this._times[0]<=now-1e3;)this._times.shift();return fps=this._times.push(now),this._maxFps<fps&&(this._maxFps=fps),fps}getFps(){const avgSample=this._averageSample;return avgSample.push(this.getFpsRaw()),avgSample.length>this._averageSampleSize&&avgSample.shift(),0|Math.min(CDEUtils.avg(avgSample),this._maxFps)}getApproximatedUserRefreshRate(forceFPS=this.maxFps){return performance.now()>1e3?FPSCounter.COMMON_REFRESH_RATES.reduce(((a,b)=>a<forceFPS-1?b:a),null):null}getRecommendedFPS(prioritizeStability=!0,stabilityThreshold=8){if(performance.now()>1e3){const refreshRates=FPSCounter.COMMON_REFRESH_RATES,avgFps=this._averageSample.reduce(((a,b)=>a+b),0)/this._averageSampleSize;return avgFps&&prioritizeStability?refreshRates[refreshRates.indexOf(refreshRates.reduce(((a,b)=>a<avgFps+stabilityThreshold?b:a),null))-1]||refreshRates[0]:this.getApproximatedUserRefreshRate(avgFps)}return null}runRecommendedFPSEvaluation(resultCB,duration=1e4,sampleCount=10,prioritizeStability=!0,stabilityThreshold=8){sampleCount=sampleCount?sampleCount|=0:10,duration<sampleCount&&(duration=sampleCount);const delay=duration/sampleCount,rawResults=[];for(let i=delay;i<=duration;i+=delay){setTimeout((()=>{if(rawResults.push(this.getRecommendedFPS(prioritizeStability,stabilityThreshold)),i>=duration&&CDEUtils.isFunction(resultCB)){const[min,max]=CDEUtils.getMinMax(rawResults),avg=CDEUtils.avg(rawResults),recommendedValue=this.getApproximatedUserRefreshRate(avg-stabilityThreshold);resultCB({recommendedValue:recommendedValue,stats:{rawResults:rawResults,min:min,max:max,avg:avg}})}}),1e3+i)}}[Symbol.toPrimitive](){return this.getFps()}*[Symbol.iterator](){const times=this._times,t_ll=times.length;for(let i=0;i<t_ll;i++)yield times[i]}get[Symbol.toStringTag](){return this.instanceOf}get instanceOf(){return"FPSCounter"}get maxFps(){return this._maxFps-1}get averageSampleSize(){return this._averageSampleSize}get fpsRaw(){return this._times.length}set averageSampleSize(averageSampleSize){this._averageSampleSize=averageSampleSize}}class CanvasUtils{static SHOW_CENTERS_DOT_ID={};static toggleCenter(canvas,shape,radius=5,color=[255,0,0,1]){if(CanvasUtils.SHOW_CENTERS_DOT_ID[shape.id])canvas.remove(CanvasUtils.SHOW_CENTERS_DOT_ID[shape.id]),delete CanvasUtils.SHOW_CENTERS_DOT_ID[shape.id];else{const dot=new Dot([0,0],radius,color,null,shape);CanvasUtils.SHOW_CENTERS_DOT_ID[shape.id]=dot.id,canvas.add(dot)}}static showIntersectionPoints(canvas,res){const s_d1=new Dot(res[0][0],3,[255,0,0,1]),s_d2=new Dot(res[0][1],3,[255,0,0,.45]),t_d1=new Dot(res[1][1],3,[255,0,0,.45]),t_d2=new Dot(res[1][0],3,[255,0,0,1]);canvas.add(s_d1),canvas.add(s_d2),canvas.add(t_d1),canvas.add(t_d2)}static firstDotOnly(dot){return dot.id==dot.parent.firstDot.id}static drawOuterRing(dot,renderStyles,radiusMultiplier=1,forceBatching=!1){const color=renderStyles.colorObject??renderStyles,opacityThreshold=Color.OPACITY_VISIBILITY_THRESHOLD,filter=renderStyles._filter;color[3]<opacityThreshold||color.a<opacityThreshold||(filter&&-1!==filter.indexOf("#")&&!forceBatching?dot.render.stroke(Render.getArc(dot.pos,(dot.radius||1)*radiusMultiplier),renderStyles):dot.render.batchStroke(Render.getArc(dot.pos,(dot.radius||1)*radiusMultiplier),renderStyles))}static drawLine(dot,target,renderStyles,radiusPaddingMultiplier=0,lineType=Render.getLine,spread,forceBatching){const color=renderStyles.colorObject??renderStyles,opacityThreshold=Color.OPACITY_VISIBILITY_THRESHOLD,filter=renderStyles._filter;if(!(color[3]<opacityThreshold||color.a<opacityThreshold))if(radiusPaddingMultiplier){const res=dot.getLinearIntersectPoints(target,Math.max(target.radius??_Obj.DEFAULT_RADIUS,.1)*radiusPaddingMultiplier,dot,Math.max(dot.radius*radiusPaddingMultiplier,.1));filter&&-1!==filter.indexOf("#")&&!forceBatching?dot.render.stroke(lineType(res[0][0],res[1][0],spread),renderStyles):dot.render.batchStroke(lineType(res[0][0],res[1][0],spread),renderStyles)}else filter&&-1!==filter.indexOf("#")&&!forceBatching?dot.render.stroke(lineType(dot.pos,target.pos??target,spread),renderStyles):dot.render.batchStroke(lineType(dot.pos,target.pos??target,spread),renderStyles)}static drawDotConnections(dot,renderStyles,radiusPaddingMultiplier=0,lineType=Render.getLine,spread,forceBatching){const render=dot.render,dotPos=dot.pos,dotConnections=dot.connections,dc_ll=dot.connections.length,color=renderStyles.colorObject??renderStyles,opacityThreshold=Color.OPACITY_VISIBILITY_THRESHOLD,filter=renderStyles._filter,hasURLFilter=filter&&-1!==filter.indexOf("#");if(lineType||(lineType=Render.getLine),dc_ll){if(color[3]<opacityThreshold||color.a<opacityThreshold)return;if(radiusPaddingMultiplier){const dotRadiusPadding=dot.radius*radiusPaddingMultiplier;for(let i=0;i<dc_ll;i++){const c=dotConnections[i],res=dot.getLinearIntersectPoints(c,c.radius*radiusPaddingMultiplier,dot,dotRadiusPadding);hasURLFilter&&!forceBatching?render.stroke(lineType(res[0][0],res[1][0],spread),renderStyles):render.batchStroke(lineType(res[0][0],res[1][0],spread),renderStyles)}}else for(let i=0;i<dc_ll;i++)hasURLFilter&&!forceBatching?render.stroke(lineType(dotPos,dotConnections[i].pos,spread),renderStyles):render.batchStroke(lineType(dotPos,dotConnections[i].pos,spread),renderStyles)}}static getDraggableDotCB(disableMultipleDrag=!0){let mouseup=!1,dragAnim=null;return disableMultipleDrag?(dot,mouse,dist,ratio,pickableRadius=20)=>{const draggedObjId=mouse.holdValue.draggedObjId;mouse.clicked&&(!draggedObjId&&dist<pickableRadius||draggedObjId==dot.id)?(mouse.holdValue.draggedObjId=dot.id,mouseup=!0,dot?.currentBacklogAnim?.id==dragAnim?.id&&dragAnim&&dragAnim.end(),dot.x=mouse.x,dot.y=mouse.y):mouseup?(mouse.holdValue.draggedObjId=null,mouseup=!1,dragAnim=dot.addForce(Math.min(CDEUtils.mod(Math.min(mouse.speed,3e3),ratio)/4,300),mouse.dir,750+1200*ratio,Anim.easeOutQuad)):!mouse.clicked&&draggedObjId&&(mouse.holdValue.draggedObjId=null)}:(dot,mouse,dist,ratio,pickableRadius=50)=>{mouse.clicked&&dist<pickableRadius?(mouseup=!0,dot?.currentBacklogAnim?.id==dragAnim?.id&&dragAnim&&dragAnim.end(),dot.x=mouse.x,dot.y=mouse.y):mouseup&&(mouseup=!1,dragAnim=dot.addForce(Math.min(CDEUtils.mod(Math.min(mouse.speed,3e3),ratio)/4,300),mouse.dir,750+1200*ratio,Anim.easeOutQuad))}}static getTrailEffectCB(canvas,dot,length=8,moveEffectCB=null,disableDefaultMovements=!1){let trail=[],trailPos=new Array(length).fill(dot.pos),lastPos=null,equals=CDEUtils.posEquals,isDefaultMovements=!disableDefaultMovements;for(let i=0;i<length;i++){const trailObj=dot.duplicate();trail.push(trailObj),canvas.add(trailObj)}return mouse=>{let pos=CDEUtils.unlinkArr2(dot.pos),isMoving=!1;if(!equals(lastPos,pos)){if(trailPos.shift(),trailPos.push(pos),isDefaultMovements)for(let i=0;i<length;i++)trail[i].moveAt(trailPos[i]);lastPos=pos,isMoving=!0}if(moveEffectCB)for(let i=0;i<length;i++)moveEffectCB(trail[i],(i+1)/length,isMoving,mouse,trailPos[i],i)}}static getMovementOscillatorCB(obj,distances=[100,100],isAdditive=!0){const distanceX=distances[0],distanceY=distances[1];if(isAdditive){let lastProg;return(prog,i)=>{const dirProg=i%2?1-prog:prog;null==lastProg&&(lastProg=dirProg);const newProg=dirProg-lastProg;distanceX&&(obj.x+=distanceX*newProg),distanceY&&(obj.y+=distanceY*newProg),lastProg=dirProg}}{const ix=obj.x,iy=obj.y;return(prog,i)=>{const dirProg=i%2?1-prog:prog;distanceX&&(obj.x=ix+distanceX*dirProg),distanceY&&(obj.y=iy+distanceY*dirProg)}}}static rotateGradient(obj,duration=1e3,speed=1,isFillColor=!1){return obj.playAnim(new Anim((prog=>obj[isFillColor?"fillColorRaw":"colorRaw"].rotation=360*-speed*prog),duration))}static lookAt(obj,target,offset=0){const t=target?.pos??target;obj.rotation=offset-CDEUtils.toDeg(Math.atan2(obj.pos[1]-t[1],-(obj.pos[0]-t[0])))}static drawOutline(render,obj,color=[255,0,0,1]){const bounds=obj.getBounds();render.batchStroke(Render.getPositionsRect(bounds[0],bounds[1]),color?.color||color)}static drawOutlineAccurate(render,obj,color=[0,50,255,1]){render.batchStroke(obj.getBoundsAccurate(),color?.color||color)}static drawPos(render,pos,color=[255,0,0,1],radius){render.batchStroke(Render.getArc(pos,radius),color?.color||color)}static SHAPES={DEBUG_SHAPE:(pos,dots)=>new Shape(pos||[100,100],dots||[new Dot,new Dot([100]),new Dot([,100]),new Dot([100,100])]),THROWABLE_DOT:(pos,radius,color)=>{const dragAnim=CanvasUtils.getDraggableDotCB();return new Shape(pos||[10,10],new Dot,radius,color,null,((render,dot,ratio,res,m,dist,shape)=>dragAnim(shape.firstDot,m,dist,ratio)))}};static createDrawingBoard(CVS,borderPositions=[[0,0],CVS.size],renderStyles=[255,0,0,1],newLineMoveThreshold=Math.min(1,(CVS.fpsLimit||60)/15),borderColor=Color.DEFAULT_RGBA){let d_ll=0,render=CVS.render,cvsStatic=Canvas.STATIC,thresholdAt=0,obj=new Shape(null,[new Dot(borderPositions[0]),new Dot(borderPositions[1])],0,null,0,null,null,(()=>[]),(()=>{for(let i=0;i<d_ll;i++)render.batchStroke(obj.setupResults[i],renderStyles);borderColor&&(borderColor.a||borderColor[3])&&CanvasUtils.drawOutline(render,obj,borderColor)}),null,!0);CVS.add(obj);const clickListenerId=CVS.mouse.addListener(obj,Mouse.LISTENER_TYPES.DOWN,(pos=>{const path=new Path2D,x=pos[0],y=pos[1];path.moveTo(x,y),path.arc(x,y,(renderStyles.lineWidth||render.defaultProfile.lineWidth)/4,0,CDEUtils.CIRC),d_ll=obj.setupResults.push(path)})),enterListenerId=CVS.mouse.addListener(obj,Mouse.LISTENER_TYPES.ENTER,((pos,_,mouse)=>{if(mouse.clicked){const path=new Path2D,x=pos[0],y=pos[1];path.moveTo(x,y),d_ll=obj.setupResults.push(path)}})),moveListenerId=CVS.mouse.addListener(obj,Mouse.LISTENER_TYPES.MOVE,((pos,_,mouse)=>{if(++thresholdAt==newLineMoveThreshold){const lastPos=mouse.lastPos,path=obj.setupResults[d_ll-1];if(path&&mouse.clicked&&obj.isWithin(lastPos)&&(path.lineTo(pos[0],pos[1],lastPos[0],lastPos[1]),CVS.fpsLimit==cvsStatic))for(let i=0;i<d_ll;i++)render.stroke(obj.setupResults[i],renderStyles);thresholdAt=0}}));return{obj:obj,mouseListeners:{click:clickListenerId,enter:enterListenerId,move:moveListenerId}}}static createEmptyObj(CVS,setupCB,loopCB){const obj=new Shape(null,null,0,null,0,null,void 0,setupCB,loopCB,null,!0);return CVS.add(obj),obj}static createButton(CVS,text="Button",pos=CVS.getCenter(),onClickCB=null,fillColor="aliceblue",textColor="black",padding=[20,30],onHoverCB=null,disableDefaultEffects=!1){const textDisplay=new TextDisplay(text,[0,0],textColor,null,null,null,(self=>{const[width,height]=self.trueSize,w=width/2+padding[1]/2,h=height/2+padding[0]/2,button=CVS.add(new FilledShape(fillColor,!0,pos,[new Dot([-w,-h]),new Dot([w,-h]),new Dot([w,h]),new Dot([-w,h])],0,fillColor,null,null,null,null,null,null,!0)),brightnesses_default=100,brightnesses_hover=85,brightnesses_click=70,hoverHandler=isHover=>{disableDefaultEffects||(button.fillColorObject.brightness=isHover?brightnesses_hover:brightnesses_default,CVS.setCursorStyle(isHover?Canvas.CURSOR_STYLES.POINTER:Canvas.CURSOR_STYLES.DEFAULT)),CDEUtils.isFunction(onHoverCB)&&onHoverCB(isHover,button,self)},clickHandler=isDown=>{disableDefaultEffects||(button.fillColorObject.brightness=isDown?brightnesses_click:brightnesses_hover),isDown&&CDEUtils.isFunction(onClickCB)&&onClickCB(button,self)};return CVS.mouse.addListener(button,Mouse.LISTENER_TYPES.DOWN,(()=>clickHandler(!0))),CVS.mouse.addListener(button,Mouse.LISTENER_TYPES.UP,(()=>clickHandler(!1))),CVS.mouse.addListener(button,Mouse.LISTENER_TYPES.ENTER,(()=>hoverHandler(!0))),CVS.mouse.addListener(button,Mouse.LISTENER_TYPES.LEAVE,(()=>hoverHandler(!1))),button}),null,(self=>self.setupResults));return CVS.add(textDisplay),[textDisplay.setupResults,textDisplay]}static FOLLOW_PATHS={INFINITY_SIGN:(width,height,progressOffset)=>(width??=100,height??=50,progressOffset??=0,[[0,prog=>{const progress=CDEUtils.CIRC*((prog+progressOffset)%1);return[width*Math.sin(progress),height*Math.sin(2*progress)]}]]),CIRCLE:(width,height,progressOffset)=>(width??=100,height??=100,progressOffset??=0,[[0,prog=>{const progress=CDEUtils.CIRC*((prog+progressOffset)%1);return[width*Math.cos(progress),height*Math.sin(progress)]}]]),RECTANGLE:(width,height,progressOffset)=>(width??=100,height??=100,progressOffset??=0,[[0,prog=>{const pos=(prog+progressOffset)%1*2*(width+height);return pos<width?[pos,0]:pos<width+height?[width,pos-width]:pos<2*width+height?[width-(pos-(width+height)),height]:[0,height-(pos-(2*width+height))]}]]),QUADRATIC:(width,height,isFliped)=>{width??=100,height??=200;const maxNaturalHeight=Math.pow(width/2,2);return[[0,prog=>{let x=(prog-.5)*width,y=height*(Math.pow(x,2)/maxNaturalHeight);return isFliped&&(y=height-y),[x,y]}]]},LINEAR:(width,a)=>(width??=100,a??=1,[[0,prog=>{const x=prog*width;return[x,a*x]}]]),SINE_WAVE:(width,height)=>(width??=100,height??=100,[[0,prog=>{const x=prog*width;return[x,height*Math.sin(CDEUtils.CIRC*x/width)]}]]),COSINE_WAVE:(width,height)=>(width??=100,height??=100,[[0,prog=>{const x=prog*width;return[x,height*Math.cos(CDEUtils.CIRC*x/width)]}]]),RELATIVE:(forceX,forceY)=>{forceX??=void 0,forceY??=void 0;let isForceXFn=!1,isForceYFn=!1;return Array.isArray(forceX)&&(forceX=forceX.flat()[1],isForceXFn=!0),Array.isArray(forceY)&&(forceY=forceY.flat()[1],isForceYFn=!0),[[0,prog=>[isForceXFn?forceX(prog)[0]:forceX,isForceYFn?forceY(prog)[1]:forceX]]]}}}class Color{static DEFAULT_COLOR="aliceblue";static DEFAULT_RGBA=[240,248,255,1];static DEFAULT_COLOR_VALUE="rgba(240, 248, 255, 1)";static CSS_COLOR_TO_RGBA_CONVERTIONS={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],grey:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightsteelblue:[176,224,230,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],rebeccapurple:[102,51,153,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};static RGBA_TO_CSS_COLOR_CONVERTIONS={"0,0,0,0":"transparent","240,248,255,1":"aliceblue","250,235,215,1":"antiquewhite","0,255,255,1":"aqua","127,255,212,1":"aquamarine","240,255,255,1":"azure","245,245,220,1":"beige","255,228,196,1":"bisque","0,0,0,1":"black","255,235,205,1":"blanchedalmond","0,0,255,1":"blue","138,43,226,1":"blueviolet","165,42,42,1":"brown","222,184,135,1":"burlywood","95,158,160,1":"cadetblue","127,255,0,1":"chartreuse","210,105,30,1":"chocolate","255,127,80,1":"coral","100,149,237,1":"cornflowerblue","255,248,220,1":"cornsilk","220,20,60,1":"crimson","0,0,139,1":"darkblue","0,139,139,1":"darkcyan","184,134,11,1":"darkgoldenrod","169,169,169,1":"darkgray","0,100,0,1":"darkgreen","189,183,107,1":"darkkhaki","139,0,139,1":"darkmagenta","85,107,47,1":"darkolivegreen","255,140,0,1":"darkorange","153,50,204,1":"darkorchid","139,0,0,1":"darkred","233,150,122,1":"darksalmon","143,188,143,1":"darkseagreen","72,61,139,1":"darkslateblue","47,79,79,1":"darkslategray","0,206,209,1":"darkturquoise","148,0,211,1":"darkviolet","255,20,147,1":"deeppink","0,191,255,1":"deepskyblue","105,105,105,1":"dimgray","30,144,255,1":"dodgerblue","178,34,34,1":"firebrick","255,250,240,1":"floralwhite","34,139,34,1":"forestgreen","220,220,220,1":"gainsboro","248,248,255,1":"ghostwhite","255,215,0,1":"gold","218,165,32,1":"goldenrod","128,128,128,1":"gray","0,128,0,1":"green","173,255,47,1":"greenyellow","240,255,240,1":"honeydew","255,105,180,1":"hotpink","205,92,92,1":"indianred","75,0,130,1":"indigo","255,255,240,1":"ivory","240,230,140,1":"khaki","230,230,250,1":"lavender","255,240,245,1":"lavenderblush","124,252,0,1":"lawngreen","255,250,205,1":"lemonchiffon","173,216,230,1":"lightblue","240,128,128,1":"lightcoral","224,255,255,1":"lightcyan","250,250,210,1":"lightgoldenrodyellow","211,211,211,1":"lightgray","144,238,144,1":"lightgreen","255,182,193,1":"lightpink","255,160,122,1":"lightsalmon","32,178,170,1":"lightseagreen","135,206,250,1":"lightskyblue","119,136,153,1":"lightslategray","176,224,230,1":"lightsteelblue","255,255,224,1":"lightyellow","0,255,0,1":"lime","50,205,50,1":"limegreen","250,240,230,1":"linen","255,0,255,1":"magenta","128,0,0,1":"maroon","102,205,170,1":"mediumaquamarine","0,0,205,1":"mediumblue","186,85,211,1":"mediumorchid","147,112,219,1":"mediumpurple","60,179,113,1":"mediumseagreen","123,104,238,1":"mediumslateblue","0,250,154,1":"mediumspringgreen","72,209,204,1":"mediumturquoise","199,21,133,1":"mediumvioletred","25,25,112,1":"midnightblue","245,255,250,1":"mintcream","255,228,225,1":"mistyrose","255,228,181,1":"moccasin","255,222,173,1":"navajowhite","0,0,128,1":"navy","253,245,230,1":"oldlace","128,128,0,1":"olive","107,142,35,1":"olivedrab","255,165,0,1":"orange","255,69,0,1":"orangered","218,112,214,1":"orchid","238,232,170,1":"palegoldenrod","152,251,152,1":"palegreen","175,238,238,1":"paleturquoise","219,112,147,1":"palevioletred","255,239,213,1":"papayawhip","255,218,185,1":"peachpuff","205,133,63,1":"peru","255,192,203,1":"pink","221,160,221,1":"plum","128,0,128,1":"purple","102,51,153,1":"rebeccapurple","255,0,0,1":"red","188,143,143,1":"rosybrown","65,105,225,1":"royalblue","139,69,19,1":"saddlebrown","250,128,114,1":"salmon","244,164,96,1":"sandybrown","46,139,87,1":"seagreen","255,245,238,1":"seashell","160,82,45,1":"sienna","192,192,192,1":"silver","135,206,235,1":"skyblue","106,90,205,1":"slateblue","112,128,144,1":"slategray","255,250,250,1":"snow","0,255,127,1":"springgreen","70,130,180,1":"steelblue","210,180,140,1":"tan","0,128,128,1":"teal","216,191,216,1":"thistle","255,99,71,1":"tomato","64,224,208,1":"turquoise","238,130,238,1":"violet","245,222,179,1":"wheat","255,255,255,1":"white","245,245,245,1":"whitesmoke","255,255,0,1":"yellow","154,205,50,1":"yellowgreen"};static FORMATS={RGBA:"RGBA",TEXT:"TEXT",HEX:"HEX",GRADIENT:"GRADIENT",PATTERN:"PATTERN",COLOR:"COLOR",HSV:"HSVA"};static CONVERTABLE_FORMATS={RGBA:"RGBA",TEXT:"TEXT",HEX:"HEX",HSV:"HSVA"};static STRICT_FORMATS={RGBA:"RGBA",COLOR:"COLOR"};static DEFAULT_TEMPERANCE=0;static SEARCH_STARTS={TOP_LEFT:"TOP_LEFT",BOTTOM_RIGHT:"BOTTOM_RIGHT"};static DEFAULT_SEARCH_START=Color.SEARCH_STARTS.TOP_LEFT;static DEFAULT_DECIMAL_ROUNDING_POINT=3;static OPACITY_VISIBILITY_THRESHOLD=.029;#rgba=null;#hsv=null;constructor(color,isChannel=!1){const format=Color.getFormat(color);this._color=color instanceof Color?color._color:format&&color||Color.DEFAULT_COLOR,this._format=format||Color.getFormat(this._color),this.#updateCache(),this._isChannel=isChannel||!1}#updateCache(){const formats=Color.FORMATS,format=this._format;if(format==formats.GRADIENT||format==formats.PATTERN)this.#rgba=this.#hsv=[];else{this.#rgba=format!=formats.RGBA?this.convertTo():Color.#unlinkRGBA(this._color);const rgba=this.#rgba,DDRP=Color.DEFAULT_DECIMAL_ROUNDING_POINT,round=CDEUtils.round,a=rgba[3];rgba[0]=round(rgba[0],DDRP),rgba[1]=round(rgba[1],DDRP),rgba[2]=round(rgba[2],DDRP),rgba[3]=null!=a?round(a,DDRP):1,this.#hsv=Color.convertTo(rgba,formats.HSV)}}static convertTo(color,format=Color.CONVERTABLE_FORMATS.RGBA){let inputFormat=Color.getFormat(color),convertedColor=color,formats=Color.CONVERTABLE_FORMATS,RGBA=formats.RGBA,HEX=formats.HEX,TEXT=formats.TEXT,HSV=formats.HSV;return inputFormat&&(format==RGBA?inputFormat==HEX?convertedColor=Color.#hexToRgba(color):inputFormat==TEXT?convertedColor=Color.#unlinkRGBA(Color.CSS_COLOR_TO_RGBA_CONVERTIONS[color]):inputFormat==HSV&&(convertedColor=Color.#hsvToRgba(color)):format==HEX?convertedColor=inputFormat==RGBA?Color.#rgbaToHex(color):Color.#rgbaToHex(Color.convertTo(color,RGBA)):format==TEXT?convertedColor=inputFormat==RGBA?Color.RGBA_TO_CSS_COLOR_CONVERTIONS[color.toString()]??color:Color.RGBA_TO_CSS_COLOR_CONVERTIONS[Color.convertTo(color,RGBA).toString()]??color:format==HSV&&(convertedColor=inputFormat==RGBA?Color.#rgbaToHsv(color):Color.#rgbaToHsv(Color.convertTo(color,RGBA)))),convertedColor}convertTo(color=this._color,format=Color.CONVERTABLE_FORMATS.RGBA){return Color.convertTo(color,format)}static random(outputFormat=Color.CONVERTABLE_FORMATS.RGBA,randomizeAlpha=!1,rRange=[0,255],gRange=[0,255],bRange=[0,255],aRange=[0,1]){const formats=Color.CONVERTABLE_FORMATS,random=CDEUtils.random,randomRGBA=[random(...rRange),random(...gRange),random(...bRange),randomizeAlpha?random(...aRange,2):1];return outputFormat==formats.HEX?Color.convertTo(randomRGBA,formats.HEX):outputFormat==formats.TEXT?Color.convertTo(randomRGBA,formats.TEXT):outputFormat==formats.HSV?Color.convertTo(randomRGBA,formats.HSV):randomRGBA}static#unlinkRGBA(rgba){return rgba?[rgba[0],rgba[1],rgba[2],rgba[3]]:null}static#rgbaToHsv(rgba){let hue,r=rgba[0]/255,g=rgba[1]/255,b=rgba[2]/255,min=Math.min(r,g,b),max=Math.max(r,g,b),diff=max-min;return max==min?hue=0:(hue=max==r?(g-b)/diff:max==g?(b-r)/diff+2:(r-g)/diff+4,hue=(360+60*hue)%360),[hue,max&&diff/max*100,100*max]}static#hsvToRgba(hsv){let r,g,b,hue=hsv[0],sat=hsv[1]/100,bright=hsv[2]/100,chro=bright*sat,x=chro*(1-Math.abs(hue/60%2-1)),dc=bright-chro;return 0<=hue&&hue<60?(r=chro,g=x,b=0):60<=hue&&hue<120?(r=x,g=chro,b=0):120<=hue&&hue<180?(r=0,g=chro,b=x):180<=hue&&hue<240?(r=0,g=x,b=chro):240<=hue&&hue<300?(r=x,g=0,b=chro):(r=chro,g=0,b=x),[Math.round(255*(r+dc)),Math.round(255*(g+dc)),Math.round(255*(b+dc)),1]}static#rgbaToHex(rgba){let r=(0|rgba[0]).toString(16),g=(0|rgba[1]).toString(16),b=(0|rgba[2]).toString(16),a=rgba[3],hex="#"+(r.length<2?"0"+r:r)+(g.length<2?"0"+g:g)+(b.length<2?"0"+b:b);if(1!=a){const alpha=Math.round(255*a).toString(16);hex+=alpha.length<2?"0"+alpha:alpha}return hex}static#hexToRgba(hex){"#"!=hex[0]&&(hex="#"+hex);const res=[],h_ll=hex.length-1,hasAlpha=4==h_ll||8==h_ll;if(h_ll<6)for(let i=1;i<=h_ll;i++){let char1=hex[i],v=parseInt(char1+char1,16);hasAlpha&&i==h_ll&&(v=Math.round(v/255*100)/100),res.push(v)}else for(let i=1;i<h_ll;i+=2){let v=parseInt(hex[i]+hex[i+1],16);hasAlpha&&i+1==h_ll&&(v=Math.round(v/255*100)/100),res.push(v)}return res}static getFormat(color){const formats=Color.FORMATS;return color?Array.isArray(color)?4==color.length?formats.RGBA:formats.HSV:color instanceof Color?formats.COLOR:color instanceof Gradient?formats.GRADIENT:color instanceof Pattern?formats.PATTERN:"#"==color[0]?formats.HEX:Color.CSS_COLOR_TO_RGBA_CONVERTIONS[color]?formats.TEXT:null:null}static uniquify(color){return color instanceof Color?color.isChannel?color:color.duplicate():new Color(color)}static rgbaAdd(rgba,rValue=0,gValue=0,bValue=0,aValue=0){const c=(v,isAlpha)=>CDEUtils.clamp(v,0,isAlpha?1:255);return[c(rgba[0]+(rValue||0)),c(rgba[1]+(gValue||0)),c(rgba[2]+(bValue||0)),c(rgba[3]+(aValue||0),!0)]}static rgbaAddAll(rgba,value=0){const c=(v,isAlpha)=>CDEUtils.clamp(v,0,isAlpha?1:255);return[c(rgba[0]+(value||0)),c(rgba[1]+(value||0)),c(rgba[2]+(value||0)),rgba[3]]}static rgbaSet(rgba,rValue,gValue,bValue,aValue){const c=(v,isAlpha)=>CDEUtils.clamp(v,0,isAlpha?1:255);return[c(rValue??rgba[0]??0),c(gValue??rgba[1]??0),c(bValue??rgba[2]??0),c(aValue??rgba[3]??1,!0)]}static rgbaHsvAdd(rgba,hueValue,saturationValue,brightnessValue){const hsv=Color.#rgbaToHsv(rgba);return hsv[0]=(hsv[0]+(hueValue??0))%360||0,hsv[1]=CDEUtils.clamp(hsv[1]+(saturationValue??0),0,100)||0,hsv[2]=CDEUtils.clamp(hsv[2]+(brightnessValue??0),0,100)||0,Color.rgbaSet(Color.#hsvToRgba(hsv),null,null,null,rgba[3])}static formatRgba(rgba){return Array.isArray(rgba)?`rgba(${rgba[0]??255}, ${rgba[1]??255}, ${rgba[2]??255}, ${rgba[3]??1})`:null}static rgba(r=255,g=255,b=255,a=1){const round=CDEUtils.round,roundingPoint=Color.DEFAULT_DECIMAL_ROUNDING_POINT;return[round(r,roundingPoint),round(g,roundingPoint),round(b,roundingPoint),round(a,roundingPoint)]}static getColorValue(color){return"string"==typeof color||color instanceof CanvasGradient||color instanceof CanvasPattern?color:color instanceof _DynamicColor?color.value:Color.formatRgba(color)??color.color}static findFirstPos(canvas,color,useAlpha=!1,temperance=Color.DEFAULT_TEMPERANCE,searchStart=Color.DEFAULT_SEARCH_START,areaSize=[]){let x,y,yi,xi,currentR,currentG,currentB,width=areaSize[0]??canvas.width,height=areaSize[1]??canvas.height,data=canvas.ctx.getImageData(0,0,width,height).data,ow=4*width,r=color.r??color[0],g=color.g??color[1],b=color.b??color[2],a=255*(color.a??color[3]),br=r-temperance,bg=g-temperance,bb=b-temperance,ba=a-temperance,tr=r+temperance,tg=g+temperance,tb=b+temperance,ta=a+temperance,isSearchTL=searchStart==Color.SEARCH_STARTS.TOP_LEFT,startX=isSearchTL?0:width-1,endX=isSearchTL?width:-1,stepX=isSearchTL?1:-1,endY=isSearchTL?height:-1,stepY=isSearchTL?1:-1;for(y=isSearchTL?0:height-1;y!=endY;y+=stepY)for(yi=y*ow,x=startX;x!=endX;x+=stepX)if(xi=yi+4*x,currentR=data[xi],temperance){if(currentR>=br&&currentR<=tr&&(currentG=data[xi+1],currentB=data[xi+2],currentG>=bg&&currentG<=tg&&currentB>=bb&&currentB<=tb&&(!useAlpha||undefined>=ba&&undefined<=ta)))return[x,y]}else if(currentR==r&&data[xi+1]==g&&data[xi+2]==b&&(!useAlpha||data[xi+3]==a))return[x,y];return null}duplicate(dynamicColorPositions){const formats=Color.FORMATS,format=this._format;return format==formats.GRADIENT||format==formats.PATTERN?new Color(this._color.duplicate(dynamicColorPositions)):new Color(Color.#unlinkRGBA(this.#rgba))}toString(){let colorValue=Color.getColorValue(this._color);return(colorValue instanceof CanvasGradient||colorValue instanceof CanvasPattern)&&(colorValue=this._color.toString()),colorValue}[Symbol.toPrimitive](){return this.color}*[Symbol.iterator](){const rgba=this.#rgba;for(let i=0;i<4;i++)yield rgba[i]}get[Symbol.toStringTag](){return this.instanceOf}get instanceOf(){return"Color"}get color(){const formats=Color.FORMATS,format=this._format;return format==formats.GRADIENT||format==formats.PATTERN?this._color.value:Color.formatRgba(this.#rgba)}get colorRaw(){return this._color}get isChannel(){return this._isChannel}get rgba(){return this.#rgba}get hsv(){return this.#hsv}get r(){return this.#rgba[0]}get g(){return this.#rgba[1]}get b(){return this.#rgba[2]}get a(){return this.#rgba[3]}get hue(){return this.#hsv[0]}get saturation(){return this.#hsv[1]}get brightness(){return this.#hsv[2]}set color(color){const colorValue=color?._color||color,format=Color.getFormat(colorValue);format&&(this._color=colorValue,this._format=format,this.#updateCache())}set r(r){this.#rgba[0]=CDEUtils.round(r,Color.DEFAULT_DECIMAL_ROUNDING_POINT)}set g(g){this.#rgba[1]=CDEUtils.round(g,Color.DEFAULT_DECIMAL_ROUNDING_POINT)}set b(b){this.#rgba[2]=CDEUtils.round(b,Color.DEFAULT_DECIMAL_ROUNDING_POINT)}set a(a){this.#rgba[3]=CDEUtils.round(a,Color.DEFAULT_DECIMAL_ROUNDING_POINT)}set rgba(rgba){this.#rgba[0]=CDEUtils.round(rgba[0],Color.DEFAULT_DECIMAL_ROUNDING_POINT),this.#rgba[1]=CDEUtils.round(rgba[1],Color.DEFAULT_DECIMAL_ROUNDING_POINT),this.#rgba[2]=CDEUtils.round(rgba[2],Color.DEFAULT_DECIMAL_ROUNDING_POINT),this.#rgba[3]=CDEUtils.round(rgba[3],Color.DEFAULT_DECIMAL_ROUNDING_POINT)}set hue(hue){hue%=360,this.#hsv[0]!=hue&&(this.#hsv[0]=hue,this.#rgba=Color.#hsvToRgba(this.#hsv))}set saturation(saturation){saturation=saturation>100?100:saturation,this.#hsv[1]!=saturation&&(this.#hsv[1]=saturation,this.#rgba=Color.#hsvToRgba(this.#hsv))}set brightness(brightness){brightness=brightness>100?100:brightness,this.#hsv[2]!=brightness&&(this.#hsv[2]=brightness,this.#rgba=Color.#hsvToRgba(this.#hsv))}}const colors=Object.entries(Color.CSS_COLOR_TO_RGBA_CONVERTIONS),c_ll=colors.length;for(let i=0;i<c_ll;i++){const color=colors[i];Object.defineProperty(Color,color[0],{get:()=>color[1]})}class _HasColor{constructor(color){this._initColor=color,this._color=this._initColor}getInitColor(){return CDEUtils.isFunction(this._initColor)?this._initColor(this):this._initColor||null}get[Symbol.toStringTag](){return this.instanceOf}get instanceOf(){return"_HasColor"}get colorObject(){return this._color}get colorRaw(){return this._color.colorRaw}get color(){return this._color?.color}get initColor(){return this._initColor}get rgba(){return this._color.rgba}get r(){return this._color.r}get g(){return this._color.g}get b(){return this._color.b}get a(){return this._color.a}get hsv(){return this._color.hsv}get hue(){return this._color.hue}get saturation(){return this._color.saturation}get brightness(){return this._color.brightness}set color(color){const c=this._color;if(!c||c?.colorRaw?.toString()!==color?.toString()){const specialColor=color?.colorRaw||color;specialColor?.positions==_DynamicColor.PLACEHOLDER&&((color=color.isChannel?specialColor:specialColor.duplicate()).initPositions=this),c instanceof Color?c.color=color:this._color=Color.uniquify(color)}}set r(r){this._color.r=r}set g(g){this._color.g=g}set b(b){this._color.b=b}set a(a){this._color.a=a}set hue(hue){this._color.hue=hue}set saturation(saturation){this._color.saturation=saturation}set brightness(brightness){this._color.brightness=brightness}set initColor(initColor){this._initColor=initColor}}class GridAssets{static D=["t","r","b","l","tr","br","bl","tl","i"].reduce(((a,b,i)=>(a.places.push([a[b]=1<<i,ar=>0==i?-ar:1==i?1:2==i?ar:3==i?-1:4==i?1-ar:5==i?ar+1:6==i?ar-1:7==i?-ar-1:8==i?0:void 0]),a)),{places:[]});static DEFAULT_SOURCE=GridAssets.fontSource5x5;static get fontSource5x5(){const D=GridAssets.D;return{width:5,height:5,A:[[2,D.bl+D.br],[1,D.bl],[3,D.br],[0,D.r+D.b],[1,D.r],[2,D.r],[3,D.r],[4,D.b],[0,D.b],[4,D.b],[0],[4]],B:[[0,D.r+D.b],[,D.r],[,D.r],[,D.br],[0,D.b],[4,D.bl],[0,D.r+D.b],[,D.r],[,D.r],[,D.br],[0,D.b],[4,D.bl],[0,D.r],[,D.r],[,D.r],[]],C:[[1,D.r+D.bl],[,D.r],[,D.r],[],[0,D.b],[0,D.b],[0,D.br],[-1,D.r],[2,D.r],[,D.r],[]],D:[[0,D.r+D.b],[,D.r],[,D.r],[,D.br],[0,D.b],[4,D.b],[0,D.b],[4,D.b],[0,D.b],[4,D.bl],[0,D.r],[,D.r],[,D.r],[]],E:[[0,D.r+D.b],[,D.r],[,D.r],[,D.r],[],[0,D.b],[0,D.b+D.r],[,D.r],[,D.r],[,D.r],[0,D.b],[0,D.r],[,D.r],[,D.r],[,D.r],[]],F:[[0,D.r+D.b],[,D.r],[,D.r],[,D.r],[],[0,D.b],[0,D.b+D.r],[,D.r],[,D.r],[],[0,D.b],[0]],G:[[1,D.r+D.bl],[,D.r],[,D.r],[],[0,D.b],[0,D.b],[3,D.r],[4,D.b],[0,D.br],[4,D.b],[1,D.r],[,D.r],[,D.r],[]],H:[[0,D.r+D.b],[4,D.b],[0,D.b],[4,D.b],[0,D.b+D.r],[,D.r],[,D.r],[,D.r],[,D.b],[0,D.b],[4,D.b],[0],[4]],I:[[1,D.r],[,D.b+D.r],[],[2,D.b],[2,D.b],[2,D.b],[1,D.r],[,D.r],[]],J:[[1,D.r],[,D.r],[,D.b+D.r],[],[3,D.b],[3,D.b],[0,D.br],[3,D.bl],[1,D.r],[,D.r]],K:[[0,D.b],[3,D.bl],[0,D.b],[2,D.bl],[0,D.b+D.r],[,D.r+D.br],[0,D.b],[2,D.br],[0],[3,D.r]],L:[[0,D.b],[0,D.b],[0,D.b],[0,D.b],[0,D.r],[,D.r],[,D.r],[,D.r]],M:[[0,D.b+D.br],[4,D.b+D.bl],[0,D.b],[,D.br],[3,D.bl],[4,D.b],[0,D.b],[2],[4,D.b],[0,D.b],[4,D.b],[0],[4]],N:[[0,D.b+D.br],[4,D.b],[0,D.b],[,D.br],[4,D.b],[0,D.b],[2,D.br],[4,D.b],[0,D.b],[3,D.br],[4,D.b],[0],[4]],O:[[1,D.bl+D.r],[,D.r],[,D.br],[0,D.b],[4,D.b],[0,D.b],[4,D.b],[0,D.b+D.br],[4,D.b+D.bl],[1,D.r],[,D.r],[,D.r]],P:[[0,D.r+D.b],[,D.r],[,D.br],[0,D.b],[3,D.bl],[0,D.b+D.r],[,D.r],[],[0,D.b],[0]],Q:[[1,D.bl+D.r],[,D.r],[,D.br],[0,D.b],[4,D.b],[0,D.b],[4,D.b],[0,D.b+D.br],[3,D.br],[,D.bl],[1,D.r],[,D.r],[],[]],R:[[0,D.r+D.b],[,D.r],[,D.br],[0,D.b],[3,D.bl],[0,D.b+D.r],[,D.r+D.br],[],[0,D.b],[2,D.br],[0],[3]],S:[[1,D.r+D.bl],[,D.r],[,D.r],[],[0,D.br],[-1,D.r],[2,D.r],[,D.br],[-4,D.bl],[0,D.r+D.bl],[,D.r],[,D.r],[]],T:[[0,D.r],[,D.r],[,D.b+D.r],[,D.r],[],[2,D.b],[2,D.b],[2,D.b],[2]],U:[[0,D.r+D.b],[4,D.b],[0,D.b],[4,D.b],[0,D.b+D.r],[4,D.b],[0,D.br],[4,D.bl],[1,D.r],[,D.r],[,D.r]],V:[[0,D.r+D.b],[4,D.b],[0,D.b],[4,D.b],[0,D.br],[4,D.bl],[1,D.br],[3,D.bl],[2,D.r]],W:[[0,D.b+D.br],[4,D.b+D.bl],[0,D.b],[4,D.b],[0,D.b],[2,D.bl+D.br],[4,D.b],[0,D.b],[,D.bl],[3,D.br],[4,D.b],[0],[4]],X:[[0,D.br],[4,D.bl],[1,D.br],[3,D.bl],[2,D.br+D.bl],[1,D.bl],[3,D.br],[0],[4]],Y:[[0,D.br],[4,D.bl],[1,D.br],[3,D.bl],[2,D.b],[2,D.b],[2]],Z:[[0,D.r],[,D.r],[,D.r],[,D.r],[,D.bl],[3,D.bl],[2,D.bl],[1,D.bl],[0,D.r],[,D.r],[,D.r],[,D.r],[]],a:[[1/0],[1,D.bl+D.r],[,D.br],[0,D.b],[3,D.b],[0,D.br],[3,D.bl+D.br],[1,D.r],[],[4]],b:[[0,D.b],[0,D.b],[0,D.b+D.r],[,D.r],[,D.br],[0,D.b],[3,D.bl],[0,D.r],[,D.r],[,D.r]],c:[[1/0],[1,D.r+D.bl],[,D.r],[],[0,D.b],[0,D.br],[-1,D.r],[2,D.r],[]],d:[[3,D.b],[3,D.b],[1,D.bl+D.r],[,D.r],[,D.b],[0,D.br],[3,D.b],[1,D.r],[,D.r],[]],e:[[1,D.r+D.bl],[,D.br],[0,D.b],[3,D.bl],[0,D.b+D.r],[,D.r],[],[0,D.br],[3,D.bl],[1,D.r],[]],f:[[1,D.b+D.r],[],[1,D.b],[0,D.r],[,D.r+D.b],[],[1,D.b],[1]],g:[[1,D.bl+D.r],[,D.br],[0,D.br],[3,D.bl],[1,D.r],[,D.br],[0,D.br],[3,D.bl],[1,D.r],[]],h:[[0,D.b],[0,D.b],[0,D.b+D.r],[,D.r],[,D.br],[0,D.b],[3,D.b],[0],[3]],i:[[1/0],[1,D.i],[1,D.b],[1,D.b],[1]],j:[[2,D.i],[2,D.b],[2,D.b],[0,D.br],[2,D.bl],[1]],k:[[0,D.b],[0,D.b],[2,D.bl],[0,D.b],[2,D.bl],[0,D.b+D.r],[,D.br],[0],[2]],l:[[0,D.b],[0,D.b],[0,D.b],[0,D.b],[0]],m:[[1/0],[1,D.bl+D.br],[3,D.bl+D.br],[0,D.b],[2,D.b],[4,D.b],[0,D.b],[2,D.b],[4,D.b],[0],[2],[4]],n:[[1/0],[0,D.b],[,D.bl+D.r],[,D.bl+D.br],[0,D.b],[3,D.b],[0,D.b],[3,D.b],[0],[3]],o:[[1/0],[1,D.bl+D.r],[,D.br],[0,D.b],[3,D.b],[0,D.br],[3,D.bl],[1,D.r],[]],p:[[1,D.r+D.bl],[,D.br],[0,D.b],[3,D.bl],[0,D.b+D.r],[,D.r],[],[0,D.b],[0]],q:[[1,D.r+D.bl],[,D.br],[0,D.br],[3,D.b],[1,D.r],[,D.r],[,D.b],[3,D.b],[3]],r:[[1/0],[0,D.b],[,D.bl+D.r],[],[0,D.b],[0,D.b],[0]],s:[[1/0],[2,D.bl+D.br],[1,D.br],[3],[1,D.br],[2,D.r],[,D.b],[2,D.r],[]],t:[[2,D.b],[1,D.r],[,D.b+D.r],[],[2,D.b],[2,D.b],[2]],u:[[1/0],[0,D.b],[2,D.b],[0,D.b],[2,D.b],[0,D.br],[2,D.bl+D.br],[1,D.r],[3]],v:[[1/0],[1,D.b],[3,D.b],[1,D.b],[3,D.b],[1,D.br],[3,D.bl],[2,D.r]],w:[[1/0],[0,D.b],[2,D.b],[4,D.b],[0,D.b],[2,D.b],[4,D.b],[0,D.br],[2,D.bl+D.br],[4,D.bl],[1],[3]],x:[[1,D.b],[3,D.b],[1,D.br],[3,D.bl],[2,D.br+D.bl],[1,D.b],[3,D.b],[1],[3]],y:[[1/0],[1,D.b],[3,D.b],[1,D.br],[3,D.bl],[2,D.b],[2]],z:[[1/0],[0,D.r],[,D.r],[,D.r],[,D.bl],[2,D.bl],[1,D.bl],[0,D.r],[,D.r],[,D.r],[]],"!":[[3,D.b],[3,D.b],[3,D.b],[3],[3,D.i]],"?":[[1,D.r+D.bl],[,D.r],[,D.br],[0],[4,D.bl],[3,D.bl],[2],[2,D.i]],"@":[[1,D.bl+D.r],[,D.r],[,D.br],[0,D.b],[2,D.bl+D.br],[4,D.b],[0,D.b],[1,D.br],[3,D.b],[4,D.b],[0,D.b+D.br],[2,D.r],[3,D.r],[4],[1,D.r],[,D.r],[,D.r]],"#":[[1,D.b],[3,D.b],[0,D.r],[1,D.b+D.r],[2,D.r],[3,D.b+D.r],[],[1,D.b],[3,D.b],[0,D.r],[1,D.b+D.r],[2,D.r],[3,D.b+D.r],[],[1],[3]],$:[[1,D.r+D.bl],[,D.r+D.b],[,D.r],[],[0,D.br],[2,D.b],[1,D.r],[2,D.r+D.b],[,D.br],[2,D.b],[4,D.bl],[0,D.r+D.bl],[,D.r],[,D.r],[]],"%":[[0,D.r+D.b],[1,D.b],[4,D.bl],[0,D.r],[],[3,D.bl],[2,D.bl],[1,D.bl],[3,D.r+D.b],[4,D.b],[0],[3,D.r],[]],"^":[[2,D.br+D.bl],[1],[3]],"&":[[0,D.r+D.br],[,D.r],[,D.r],[,D.bl],[1,D.br],[2,D.bl],[1,D.bl],[2,D.br],[0,D.br],[3,D.br],[,D.bl],[1,D.r],[2,D.r],[3],[]],"*":[[1,D.br],[,D.b],[,D.bl],[1,D.r],[,D.r],[],[1,D.tr],[,D.t],[,D.tl]],"(":[[3,D.bl],[2,D.b],[2,D.b],[2,D.br],[-3]],")":[[1,D.br],[-2,D.b],[2,D.b],[2,D.bl],[1]],"{":[[3,D.bl],[2,D.b],[1,D.r],[2,D.b],[2,D.br],[-3]],"}":[[1,D.br],[-2,D.b],[2,D.b+D.r],[],[2,D.bl],[1]],",":[[1/0],[1/0],[1/0],[1,D.bl],[0]],".":[[1/0],[1/0],[1/0],[1/0],[0,D.i]],"+":[[1/0],[2,D.b],[1,D.r],[2,D.b+D.r],[],[2]],_:[[1/0],[1/0],[1/0],[1/0],[0,D.r],[,D.r],[,D.r],[,D.r],[,D.r]],"-":[[1/0],[1/0],[1,D.r],[,D.r],[]],"=":[[1/0],[1,D.r],[,D.r],[,D.r],[1/0],[1,D.r],[,D.r],[,D.r]],";":[[2,D.r+D.b],[3,D.b],[2,D.r],[],[2,D.r+D.b],[3,D.b],[2,D.r],[,D.b],[3]],":":[[1/0],[2,D.r+D.b],[3,D.b],[2,D.r],[],[2,D.r+D.b],[3,D.b],[2,D.r],[]],"[":[[2,D.b+D.r],[3],[2,D.b],[2,D.b],[2,D.b],[2,D.r],[3]],"]":[[1,D.r],[2,D.b],[2,D.b],[2,D.b],[2,D.b],[1,D.r],[2]],"'":[[0,D.b],[0]],"|":[[2,D.b],[2,D.b],[2,D.b],[2,D.b],[2]],"/":[[4,D.bl],[3,D.bl],[2,D.bl],[1,D.bl],[0]],"\\":[[0,D.br],[-1,D.br],[-2,D.br],[-3,D.br],[-4]],0:[[1,D.bl+D.r],[,D.br],[0,D.b],[3,D.b],[0,D.b],[,D.r],[],[,D.b],[0,D.b+D.br],[3,D.b+D.bl],[1,D.r],[,D.r]],1:[[2,D.b+D.bl],[1],[,D.b],[2,D.b],[2,D.b],[1,D.r],[,D.r],[]],2:[[1,D.r+D.bl],[,D.br],[0],[3,D.bl],[2,D.bl],[1,D.bl],[0,D.r],[,D.r],[,D.r],[,D.r]],3:[[1,D.r+D.bl],[,D.br],[0],[3,D.bl],[2,D.br],[0,D.br],[3,D.bl],[1,D.r],[,D.r]],4:[[3,D.b+D.bl],[2,D.bl],[,D.b],[1,D.bl],[3,D.b],[0,D.r],[,D.r],[,D.r],[,D.r+D.b],[,D.r],[3]],5:[[1,D.r+D.b],[,D.r],[,D.r],[],[1,D.b],[-1,D.r],[2,D.r],[,D.br],[-4,D.bl],[1,D.r+D.bl],[,D.r],[]],6:[[0,D.r+D.b],[,D.r],[,D.r],[,D.r],[0,D.b],[0,D.r+D.b],[,D.r],[,D.r],[,D.r+D.b],[0,D.b],[3,D.b],[0,D.r],[,D.r],[,D.r],[,D.r]],7:[[0,D.r],[,D.r],[,D.r],[,D.b],[3,D.bl],[1,D.r],[,D.bl+D.r],[],[1,D.bl],[0]],8:[[1,D.bl+D.r],[,D.br],[0,D.br],[3,D.bl],[1,D.bl+D.r],[,D.br],[0,D.b+D.br],[3,D.b+D.bl],[1,D.r],[,D.r]],9:[[1,D.r+D.bl],[,D.br],[0,D.br],[3,D.bl+D.b],[1,D.r],[],[,D.b],[3,D.b],[3]]}}}class TypingDevice{static KEYS={A:"A",B:"B",C:"C",D:"D",E:"E",F:"F",G:"G",H:"H",I:"I",J:"J",K:"K",L:"L",M:"M",N:"N",O:"O",P:"P",Q:"Q",R:"R",S:"S",T:"T",U:"U",V:"V",W:"W",X:"X",Y:"Y",Z:"Z",DIGIT_0:"0",DIGIT_1:"1",DIGIT_2:"2",DIGIT_3:"3",DIGIT_4:"4",DIGIT_5:"5",DIGIT_6:"6",DIGIT_7:"7",DIGIT_8:"8",DIGIT_9:"9",SPACE:" ",ENTER:"ENTER",TAB:"TAB",BACKSPACE:"BACKSPACE",ESCAPE:"ESCAPE",SHIFT:"SHIFT",CONTROL:"CONTROL",ALT:"ALT",ALT_GRAPH:"ALTGRAPH",META:"META",CAPS_LOCK:"CAPSLOCK",CONTEXT_MENU:"CONTEXTMENU",ARROW_UP:"ARROWUP",ARROW_DOWN:"ARROWDOWN",ARROW_LEFT:"ARROWLEFT",ARROW_RIGHT:"ARROWRIGHT",HOME:"HOME",END:"END",PAGE_UP:"PAGEUP",PAGE_DOWN:"PAGEDOWN",INSERT:"INSERT",DELETE:"DELETE",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12",F13:"F13",F14:"F14",F15:"F15",F16:"F16",F17:"F17",F18:"F18",F19:"F19",F20:"F20",F21:"F21",F22:"F22",F23:"F23",F24:"F24",NUMPAD_0:"NUMPAD0",NUMPAD_1:"NUMPAD1",NUMPAD_2:"NUMPAD2",NUMPAD_3:"NUMPAD3",NUMPAD_4:"NUMPAD4",NUMPAD_5:"NUMPAD5",NUMPAD_6:"NUMPAD6",NUMPAD_7:"NUMPAD7",NUMPAD_8:"NUMPAD8",NUMPAD_9:"NUMPAD9",NUMPAD_ADD:"NUMPADADD",NUMPAD_SUBTRACT:"NUMPADSUBTRACT",NUMPAD_MULTIPLY:"NUMPADMULTIPLY",NUMPAD_DIVIDE:"NUMPADDIVIDE",NUMPAD_DECIMAL:"NUMPADDECIMAL",NUMPAD_ENTER:"NUMPADENTER",PAUSE:"PAUSE",PRINT_SCREEN:"PRINTSCREEN",SCROLL_LOCK:"SCROLLLOCK",NUM_LOCK:"NUMLOCK",LAUNCH_APPLICATION_1:"LAUNCHAPPLICATION1",LAUNCH_APPLICATION_2:"LAUNCHAPPLICATION2",BRACKET_LEFT:"BRACKETLEFT",BRACKET_RIGHT:"BRACKETRIGHT",SEMICOLON:"SEMICOLON",QUOTE:"QUOTE",COMMA:"COMMA",PERIOD:"PERIOD",SLASH:"SLASH",BACKSLASH:"BACKSLASH",EQUAL:"EQUAL",MINUS:"MINUS",BACKQUOTE:"BACKQUOTE",AUDIO_VOLUME_UP:"AUDIOVOLUMEUP",AUDIO_VOLUME_DOWN:"AUDIOVOLUMEDOWN",AUDIO_VOLUME_MUTE:"AUDIOVOLUMEMUTE",MEDIA_PLAY_PAUSE:"MEDIAPLAYPAUSE",MEDIA_NEXT_TRACK:"MEDIANEXTTRACK",MEDIA_PREVIOUS_TRACK:"MEDIAPREVIOUSTRACK",MEDIA_STOP:"MEDIASTOP",BROWSER_BACK:"BROWSERBACK",BROWSER_FORWARD:"BROWSERFORWARD",BROWSER_REFRESH:"BROWSERREFRESH",BROWSER_STOP:"BROWSERSTOP",BROWSER_SEARCH:"BROWSERSEARCH",BROWSER_FAVORITES:"BROWSERFAVORITES",BROWSER_HOME:"BROWSERHOME"};constructor(){this._keysPressed=[]}setDown(e){const key=e.key?.toUpperCase();key&&!this.isDown(key)&&this._keysPressed.push({key:key,keyCode:e.keyCode})}setUp(e){const key=e.key?.toUpperCase();key&&this.isDown(key)&&(this._keysPressed=this._keysPressed.filter((v=>v.key!==key)))}isDown(keys){const isMultipleKeys=Array.isArray(keys),keysPressed=this.keysPressed;if(!isMultipleKeys)return keysPressed.includes(keys?.toUpperCase());{const k_ll=keys.length;for(let i=0;i<k_ll;i++){const key=keys[i]?.toUpperCase();if(keysPressed.includes(key))return!0}}return!1}hasKeysDown(){return Boolean(this._keysPressed.length)}*[Symbol.iterator](){const keyPressed=this._keysPressed,k_ll=keyPressed.length;for(let i=0;i<k_ll;i++)yield keyPressed[i]}get[Symbol.toStringTag](){return this.instanceOf}get instanceOf(){return"TypingDevice"}get keysPressedRaw(){return this._keysPressed}get keysPressed(){return this._keysPressed.map((v=>v.key))}get keyCodesPressed(){return this._keysPressed.map((v=>v.keyCode))}set keysPressed(keysPressed){this._keysPressed=keysPressed}}class Mouse{static DEFAULT_MOUSE_DECELERATION=.8;static DEFAULT_MOUSE_MOVE_TRESHOLD=.1;static DEFAULT_MOUSE_ANGULAR_DECELERATION=.2;static#LISTENER_ID_GIVER=0;static LISTENER_TYPES={CLICK:0,DOWN:0,UP:1,MAIN_DOWN:0,MAIN_UP:1,MIDDLE_DOWN:2,MIDDLE_UP:3,RIGHT_DOWN:4,RIGHT_UP:5,EXTRA_FOWARD_DOWN:6,EXTRA_FOWARD_UP:7,EXTRA_BACK_DOWN:8,EXTRA_BACK_UP:9,MOVE:10,ENTER:11,LEAVE:12,EXIT:12};#lastX=null;#lastY=null;#wasWithin=[];constructor(ctx){this._ctx=ctx,this._valid=!1,this._x=null,this._y=null,this._lastPos=[0,0],this._rawX=null,this._rawY=null,this._dir=null,this._speed=null,this._clicked=!1,this._rightClicked=!1,this._scrollClicked=!1,this._extraForwardClicked=!1,this._extraBackClicked=!1,this._holdValue={},this._listeners=[],this._moveListenersOptimizationEnabled=!0}calcSpeed(deltaTime){const DECELERATION=Mouse.DEFAULT_MOUSE_DECELERATION;isFinite(this.#lastX)&&isFinite(this.#lastY)&&deltaTime?(this._speed=this._speed*DECELERATION+CDEUtils.getDist(this._x,this._y,this.#lastX,this.#lastY)/deltaTime*(1-DECELERATION),this._speed<Mouse.DEFAULT_MOUSE_MOVE_TRESHOLD&&(this._speed=0)):this._speed=0,this.#lastX=this._x,this.#lastY=this._y}calcAngle(){const dx=this._x-this.#lastX,dy=this._y-this.#lastY;if(isFinite(dx)&&isFinite(dy)&&(dx||dy)){let diff=(360-CDEUtils.toDeg(Math.atan2(dy,dx)))%360-this._dir;diff+=360*(diff<-180)-360*(diff>180),this._dir=(this._dir+diff*Mouse.DEFAULT_MOUSE_ANGULAR_DECELERATION+360)%360}else this._dir=0}updateMouseClicks(e){const isMouseDownEvent="mousedown"==e.type||"touchstart"==e.type,TYPES=Mouse.LISTENER_TYPES;0==e.button?(this._clicked=isMouseDownEvent,this.checkListeners(isMouseDownEvent?TYPES.MAIN_DOWN:TYPES.MAIN_UP)):1==e.button?(this._scrollClicked=isMouseDownEvent,this.checkListeners(isMouseDownEvent?TYPES.MIDDLE_DOWN:TYPES.MIDDLE_UP)):2==e.button?(this._rightClicked=isMouseDownEvent,this.checkListeners(isMouseDownEvent?TYPES.RIGHT_DOWN:TYPES.RIGHT_UP)):3==e.button?(this._extraBackClicked=isMouseDownEvent,this.checkListeners(isMouseDownEvent?TYPES.EXTRA_BACK_DOWN:TYPES.EXTRA_BACK_UP)):4==e.button&&(this._extraForwardClicked=isMouseDownEvent,this.checkListeners(isMouseDownEvent?TYPES.EXTRA_FOWARD_DOWN:TYPES.EXTRA_FOWARD_UP))}invalidate(){this._x=1/0,this._y=1/0,this._rawX=1/0,this._rawY=1/0}updatePos(x,y,offset){this._valid=!0,this._rawX=x,this._rawY=y,this._x=x-offset[0],this._y=y-offset[1],this._moveListenersOptimizationEnabled&&(this.checkListeners(Mo