-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathq5.min.js
8 lines (8 loc) · 107 KB
/
q5.min.js
1
2
3
4
5
6
7
8
/**
* q5.js
* @version 2.25
* @author quinton-ashley, Tezumie, and LingDong-
* @license LGPL-3.0
* @class Q5
*/
function Q5(e,t,r){let a=this;a._q5=!0,a._parent=t,"webgpu-fallback"==r?(a._renderer="c2d",a._webgpu=a._webgpuFallback=!0):(a._renderer=r||Q5.render,a["_"+a._renderer]=!0);let i,o="auto"==e;if(e??="global","auto"==e){if(!(window.setup||window.update||window.draw))return;e="global"}a._scope=e,"global"==e&&(Q5._hasGlobal=a._isGlobal=!0,i=Q5._esm?globalThis:Q5._server?global:window),"graphics"==e&&(a._graphics=!0);let n=new Proxy(a,{set:(e,t,r)=>(a[t]=r,a._isGlobal&&(i[t]=r),!0)});a.canvas=a.ctx=a.drawingContext=null,a.pixels=[];let s=null,l=!0;a.frameCount=0,a.deltaTime=16,a._targetFrameRate=0,a._targetFrameDuration=16.666666666666668,a._frameRate=a._fps=60,a._loop=!0,a._hooks={postCanvas:[],preRender:[],postRender:[]};let d=0;a.millis=()=>performance.now()-d,a.noCanvas=()=>{a.canvas?.remove&&a.canvas.remove(),a.canvas=0,n.ctx=n.drawingContext=0},window&&(a.windowWidth=window.innerWidth,a.windowHeight=window.innerHeight,a.deviceOrientation=window.screen?.orientation?.type),a._preloadPromises=[],a._usePreload=!0,a.usePreloadSystem=e=>a._usePreload=e,a.isPreloadSupported=()=>a._usePreload;const c=[];a._incrementPreload=()=>{a._preloadPromises.push(new Promise((e=>c.push(e))))},a._decrementPreload=()=>{c.length&&c.pop()()},a._draw=e=>{let t=e||performance.now();if(a._lastFrameTime??=t-a._targetFrameDuration,a._didResize&&(a.windowResized(),a._didResize=!1),a._loop)if(l)s=u(a._draw);else{let e=t+a._targetFrameDuration,r=e-performance.now();for(;r<0;)r+=a._targetFrameDuration;s=setTimeout((()=>a._draw(e)),r)}else if(a.frameCount&&!a._redraw)return;if(a.frameCount&&l&&!a._redraw){if(t-a._lastFrameTime<a._targetFrameDuration-4)return}n.deltaTime=t-a._lastFrameTime,a._frameRate=1e3/a.deltaTime,n.frameCount++;let r=performance.now();a.resetMatrix(),a._beginRender&&a._beginRender();for(let e of Q5.methods.pre)e.call(a);try{a.draw()}catch(e){throw Q5.errorTolerant||a.noLoop(),a._fes&&a._fes(e),e}for(let e of Q5.methods.post)e.call(a);a.postProcess(),a._render&&a._render(),a._finishRender&&a._finishRender(),n.pmouseX=a.mouseX,n.pmouseY=a.mouseY,n.moveX=n.moveY=0,a._lastFrameTime=t;let i=performance.now();a._fps=Math.round(1e3/(i-r))},a.noLoop=()=>{a._loop=!1,null!=s&&(l?cancelAnimationFrame(s):clearTimeout(s)),s=null},a.loop=()=>{a._loop=!0,a._setupDone&&null==s&&a._draw()},a.isLooping=()=>a._loop,a.redraw=(e=1)=>{a._redraw=!0;for(let t=0;t<e;t++)a._draw();a._redraw=!1},a.remove=()=>{a.noLoop(),a.canvas.remove()},a.frameRate=e=>(e!=a._targetFrameRate&&(a._targetFrameRate=e,a._targetFrameDuration=1e3/e,a._loop&&null!=s&&(l?cancelAnimationFrame(s):clearTimeout(s),s=null),l=e<=60,a._setupDone&&(s=l?u(a._draw):setTimeout((()=>a._draw()),a._targetFrameDuration))),a._frameRate),a.getTargetFrameRate=()=>a._targetFrameRate||60,a.getFPS=()=>a._fps,a.Element=function(e){this.elt=e},a._elements=[],a.describe=()=>{},a.log=a.print=console.log;for(let e in Q5.modules)Q5.modules[e](a,n);let h=Q5.renderers[a._renderer];for(let e in h)h[e](a,n);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(a[e]=Q5[e]);if(a._graphics)return;if("global"==e){let e=Object.assign({},a);delete e.Color,Object.assign(Q5,e),delete Q5.Q5}for(let e of Q5.methods.init)e.call(a);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof a[e]&&(a[e]=t.bind(a));for(let[e,t]of Object.entries(Q5.preloadMethods))a[e]=function(){return a._incrementPreload(),t.apply(a,arguments)};if("global"==e){let e=Object.getOwnPropertyNames(a);for(let t of e)"_"!=t[0]&&(i[t]=a[t]);for(let e of["_incrementPreload","_decrementPreload"])i[e]=a[e]}"function"==typeof e&&e(a),Q5._instanceCount++;let u=window.requestAnimationFrame||function(e){const t=a._lastFrameTime+a._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},p=i||a;a._isTouchAware=p.touchStarted||p.touchMoved||p.touchEnded,a._isGlobal&&(a.preload=p.preload,a.setup=p.setup,a.draw=p.draw,a.postProcess=p.postProcess),a.preload??=()=>{},a.setup??=()=>{},a.draw??=()=>{},a.postProcess??=()=>{};let f=["setup","postProcess","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","mouseWheel","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of f)p[e]?a._isGlobal&&(a[e]=t=>{try{return p[e](t)}catch(e){throw a._fes&&a._fes(e),e}}):a[e]=()=>{};function g(){try{a.preload(),a._startDone||async function(){a._startDone=!0,await Promise.all(a._preloadPromises),a._g&&await Promise.all(a._g._preloadPromises),d=performance.now(),await a.setup(),a._setupDone=!0,a.frameCount||(null===a.ctx&&a.createCanvas(200,200),u(a._draw))}()}catch(e){throw a._fes&&a._fes(e),e}}o?g():setTimeout(g,32)}function createCanvas(e,t,r){if(!Q5._hasGlobal){(new Q5).createCanvas(e,t,r)}}Q5.render="c2d",Q5.renderers={},Q5.modules={},Q5._server="object"==typeof process,Q5._esm=void 0===this,Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{Q5.disableFriendlyErrors||console.error(t+": "+e)},Q5._validateParameters=()=>!0,Q5.methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.methods[e].push(t),Q5.preloadMethods={},Q5.prototype.registerPreloadMethod=(e,t)=>Q5.preloadMethods[e]=t[e],Q5._server&&(global.p5??=global.Q5=Q5),"object"==typeof window?window.p5??=window.Q5=Q5:global.window=0,Q5.version=Q5.VERSION="2.25","object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")})),Q5.modules.canvas=(e,t)=>{e._Canvas=window.OffscreenCanvas||function(){return document.createElement("canvas")},Q5._server?Q5._createServerCanvas&&(t.canvas=Q5._createServerCanvas(100,100)):"image"!=e._scope&&"graphics"!=e._scope||(t.canvas=new e._Canvas(100,100)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas());let r=e.canvas;if(e.width=200,e.height=200,e._pixelDensity=1,e.displayDensity=()=>window.devicePixelRatio||1,r&&(r.width=200,r.height=200,"image"!=e._scope&&(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity()))),e._adjustDisplay=()=>{r.style&&(r.style.width=r.w+"px",r.style.height=r.h+"px")},e.createCanvas=function(t,a,i){"object"==typeof t&&(i=t,t=null),i??=arguments[3],"string"==typeof i&&(i={renderer:i});let o=Object.assign({},Q5.canvasOptions);if("object"==typeof i&&Object.assign(o,i),"image"!=e._scope)if("graphics"==e._scope)e._pixelDensity=this._pixelDensity;else if(window.IntersectionObserver){let t=!1;new IntersectionObserver((a=>{r.visible=a[0].isIntersecting,t||(e._wasLooping=e._loop,t=!0),r.visible?e._wasLooping&&!e._loop&&e.loop():(e._wasLooping=e._loop,e.noLoop())})).observe(r)}e._setCanvasSize(t,a),Object.assign(r,o);let n=e._createCanvas(r.w,r.h,o);if(e._hooks)for(let t of e._hooks.postCanvas)t();return e._addEventMethods&&e._addEventMethods(r),n},e.createGraphics=function(t,r,a={}){"string"==typeof a&&(a={renderer:a});let i=new Q5("graphics",void 0,a.renderer||(e._webgpuFallback?"webgpu-fallback":e._renderer));a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace,i.createCanvas.call(e,t,r,a);let o=i._pixelDensity*e._defaultImageScale;return i.defaultWidth=t*o,i.defaultHeight=r*o,i},e._setCanvasSize=(a,i)=>{i??=a??window.innerHeight,a??=window.innerWidth,r.w=a=Math.ceil(a),r.h=i=Math.ceil(i),t.halfWidth=r.hw=a/2,t.halfHeight=r.hh=i/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(i*e._pixelDensity),e._da?e.flexibleCanvas(e._dau):(t.width=a,t.height=i),e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay()},e._setImageSize=(a,i)=>{t.width=r.w=a,t.height=r.h=i,t.halfWidth=r.hw=a/2,t.halfHeight=r.hh=i/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(i*e._pixelDensity)},e.defaultImageScale=t=>t?e._defaultImageScale=t:e._defaultImageScale,e.defaultImageScale(.5),"image"!=e._scope){if(r&&"graphics"!=e._scope){function a(){let t=e._parent;t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),r.parent(t)}r.parent=t=>{function a(){e.frameCount>1&&(e._didResize=!0,e._adjustDisplay())}r.parentElement&&r.parentElement.removeChild(r),"string"==typeof t&&(t=document.getElementById(t)),t.append(r),"function"==typeof ResizeObserver?(e._ro&&e._ro.disconnect(),e._ro=new ResizeObserver(a),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",a)},document.body?a():document.addEventListener("DOMContentLoaded",a)}e.resizeCanvas=(t,a)=>{if(!e.ctx)return e.createCanvas(t,a);t==r.w&&a==r.h||e._resizeCanvas(t,a)},r&&!Q5._createServerCanvas&&(r.resize=e.resizeCanvas),e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._resizeCanvas(r.w,r.h),t):e._pixelDensity,e.flexibleCanvas=(a=400)=>{a?(e._da=r.width/(a*e._pixelDensity),t.width=e._dau=a,t.height=r.h/r.w*a):e._da=0},e._styleNames=["_fill","_stroke","_strokeWeight","_doStroke","_doFill","_strokeSet","_fillSet","_shadow","_doShadow","_shadowOffsetX","_shadowOffsetY","_shadowBlur","_tint","_colorMode","_colorFormat","Color","_imageMode","_rectMode","_ellipseMode","_textSize","_textAlign","_textBaseline"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t)},e.popStyles=()=>{let r=e._styles.pop();for(let t of e._styleNames)e[t]=r[t];t.Color=r.Color},window&&"graphics"!=e._scope&&window.addEventListener("resize",(()=>{e._didResize=!0,t.windowWidth=window.innerWidth,t.windowHeight=window.innerHeight,t.deviceOrientation=window.screen?.orientation?.type}))}},Q5.CENTER="center",Q5.LEFT="left",Q5.RIGHT="right",Q5.TOP="top",Q5.BOTTOM="bottom",Q5.BASELINE="alphabetic",Q5.MIDDLE="middle",Q5.NORMAL="normal",Q5.ITALIC="italic",Q5.BOLD="bold",Q5.BOLDITALIC="italic bold",Q5.ROUND="round",Q5.SQUARE="butt",Q5.PROJECT="square",Q5.MITER="miter",Q5.BEVEL="bevel",Q5.NONE="none",Q5.SIMPLE="simple",Q5.CHORD_OPEN=0,Q5.PIE_OPEN=1,Q5.PIE=2,Q5.CHORD=3,Q5.RADIUS="radius",Q5.CORNER="corner",Q5.CORNERS="corners",Q5.OPEN=0,Q5.CLOSE=1,Q5.VIDEO="video",Q5.AUDIO="audio",Q5.LANDSCAPE="landscape",Q5.PORTRAIT="portrait",Q5.BLEND="source-over",Q5.REMOVE="destination-out",Q5.ADD="lighter",Q5.DARKEST="darken",Q5.LIGHTEST="lighten",Q5.DIFFERENCE="difference",Q5.SUBTRACT="subtract",Q5.EXCLUSION="exclusion",Q5.MULTIPLY="multiply",Q5.SCREEN="screen",Q5.REPLACE="copy",Q5.OVERLAY="overlay",Q5.HARD_LIGHT="hard-light",Q5.SOFT_LIGHT="soft-light",Q5.DODGE="color-dodge",Q5.BURN="color-burn",Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.SEPIA=9,Q5.BRIGHTNESS=10,Q5.SATURATION=11,Q5.CONTRAST=12,Q5.HUE_ROTATE=13,Q5.C2D=Q5.P2D=Q5.P2DHDR="c2d",Q5.WEBGL="webgl",Q5.WEBGPU="webgpu",Q5.canvasOptions={alpha:!1,colorSpace:"display-p3"},window.matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches?Q5.supportsHDR=!0:Q5.canvasOptions.colorSpace="srgb",Q5.renderers.c2d={},Q5.renderers.c2d.canvas=(e,t)=>{let r=e.canvas;if(e.colorMode&&e.colorMode("rgb",255),e._createCanvas=function(a,i,o){if(r)return t.ctx=t.drawingContext=r.getContext("2d",o),"image"!=e._scope&&(e.ctx.fillStyle=e._fill="white",e.ctx.strokeStyle=e._stroke="black",e.ctx.lineCap="round",e.ctx.lineJoin="miter",e.ctx.textAlign="left",e._strokeWeight=1),e.ctx.scale(e._pixelDensity,e._pixelDensity),e.ctx.save(),r;console.error("q5 canvas could not be created. skia-canvas and jsdom packages not found.")},e.clear=()=>{e.ctx.save(),e.ctx.resetTransform(),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.restore()},"image"==e._scope)return;e.background=function(t){e.ctx.save(),e.ctx.resetTransform(),e.ctx.globalAlpha=1,t.canvas?e.image(t,0,0,e.canvas.width,e.canvas.height):(Q5.Color&&!t._q5Color&&(t=e.color(...arguments)),e.ctx.fillStyle=t.toString(),e.ctx.fillRect(0,0,e.canvas.width,e.canvas.height)),e.ctx.restore()},e._resizeCanvas=(t,a)=>{let i,o={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(o[t]=e.ctx[t]);if(delete o.canvas,e.frameCount>1){i=new e._Canvas(r.width,r.height),i.w=r.w,i.h=r.h,i.getContext("2d").drawImage(r,0,0)}e._setCanvasSize(t,a);for(let t in o)e.ctx[t]=o[t];e.scale(e._pixelDensity),i&&e.ctx.drawImage(i,0,0,i.w,i.h)},e.fill=function(t){if(e._doFill=e._fillSet=!0,Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doFill=!1;e.ctx.fillStyle=e._fill=t.toString()},e.stroke=function(t){if(e._doStroke=e._strokeSet=!0,Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doStroke=!1;e.ctx.strokeStyle=e._stroke=t.toString()},e.strokeWeight=t=>{t||(e._doStroke=!1),e._da&&(t*=e._da),e.ctx.lineWidth=e._strokeWeight=t||1e-4},e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e.opacity=t=>e.ctx.globalAlpha=t,e._doShadow=!1,e._shadowOffsetX=e._shadowOffsetY=e._shadowBlur=10,e.shadow=function(t){if(Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doShadow=!1;e.ctx.shadowColor=e._shadow=t.toString(),e._doShadow=!0,e.ctx.shadowOffsetX||=e._shadowOffsetX,e.ctx.shadowOffsetY||=e._shadowOffsetY,e.ctx.shadowBlur||=e._shadowBlur},e.shadowBox=(t,r,a)=>{e.ctx.shadowOffsetX=e._shadowOffsetX=t,e.ctx.shadowOffsetY=e._shadowOffsetY=r||t,e.ctx.shadowBlur=e._shadowBlur=a||0},e.noShadow=()=>{e._doShadow=!1,e.ctx.shadowOffsetX=e.ctx.shadowOffsetY=e.ctx.shadowBlur=0},e.translate=(t,r)=>{e._da&&(t*=e._da,r*=e._da),e.ctx.translate(t,r)},e.rotate=t=>{e._angleMode&&(t=e.radians(t)),e.ctx.rotate(t)},e.scale=(t,r)=>{t.x&&(r=t.y,t=t.x),r??=t,e.ctx.scale(t,r)},e.applyMatrix=(t,r,a,i,o,n)=>e.ctx.transform(t,r,a,i,o,n),e.shearX=t=>e.ctx.transform(1,0,e.tan(t),1,0,0),e.shearY=t=>e.ctx.transform(1,e.tan(t),0,1,0,0),e.resetMatrix=()=>{e.ctx&&(e.ctx.resetTransform(),e.scale(e._pixelDensity),e._webgpu&&e.translate(e.halfWidth,e.halfHeight))},e.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore();let a=e.popStyles;e.popStyles=()=>{a(),e.ctx.fillStyle=e._fill,e.ctx.strokeStyle=e._stroke,e.ctx.lineWidth=e._strokeWeight,e.ctx.shadowColor=e._shadow,e.ctx.shadowOffsetX=e._doShadow?e._shadowOffsetX:0,e.ctx.shadowOffsetY=e._doShadow?e._shadowOffsetY:0,e.ctx.shadowBlur=e._doShadow?e._shadowBlur:0},e.push=()=>{e.ctx.save(),e.pushStyles()},e.pop=()=>{e.ctx.restore(),a()}},Q5.renderers.c2d.shapes=e=>{e._doStroke=!0,e._doFill=!0,e._strokeSet=!1,e._fillSet=!1,e._ellipseMode=Q5.CENTER,e._rectMode=Q5.CORNER;let t=!0,r=[];function a(){e._doFill&&e.ctx.fill(),e._doStroke&&e.ctx.stroke()}e.blendMode=t=>e.ctx.globalCompositeOperation=t,e.strokeCap=t=>e.ctx.lineCap=t,e.strokeJoin=t=>e.ctx.lineJoin=t,e.ellipseMode=t=>e._ellipseMode=t,e.rectMode=t=>e._rectMode=t,e.curveDetail=()=>{},e.line=(t,r,a,i)=>{e._doStroke&&(e._da&&(t*=e._da,r*=e._da,a*=e._da,i*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(a,i),e.ctx.stroke())};const i=2*Math.PI;function o(t,r,a,o,n,s,l){if(e._angleMode&&(n=e.radians(n),s=e.radians(s)),(n%=i)<0&&(n+=i),(s%=i)<0&&(s+=i),n>s&&(s+=i),n==s)return e.ellipse(t,r,a,o);if(a/=2,o/=2,a=Math.abs(a),o=Math.abs(o),e._doFill||l!=e.PIE_OPEN||(l=e.CHORD_OPEN),e.ctx.beginPath(),e.ctx.ellipse(t,r,a,o,0,n,s),l!=e.PIE&&l!=e.PIE_OPEN||e.ctx.lineTo(t,r),e._doFill&&e.ctx.fill(),e._doStroke){if(l!=e.PIE&&l!=e.CHORD||e.ctx.closePath(),l!=e.PIE_OPEN)return e.ctx.stroke();e.ctx.beginPath(),e.ctx.ellipse(t,r,a,o,0,n,s),e.ctx.stroke()}}function n(t,r,o,n){e.ctx.beginPath(),e.ctx.ellipse(t,r,Math.abs(o/2),Math.abs(n/2),0,0,i),a()}function s(t,r,i,o,n,l,d,c){return void 0===n?function(t,r,i,o){e._da&&(t*=e._da,r*=e._da,i*=e._da,o*=e._da),e.ctx.beginPath(),e.ctx.rect(t,r,i,o),a()}(t,r,i,o):void 0===l?s(t,r,i,o,n,n,n,n):(e._da&&(t*=e._da,r*=e._da,i*=e._da,o*=e._da,n*=e._da,l*=e._da,c*=e._da,d*=e._da),e.ctx.roundRect(t,r,i,o,[n,l,d,c]),void a())}e.arc=(t,r,a,i,n,s,l)=>{if(n==s)return e.ellipse(t,r,a,i);e._da&&(t*=e._da,r*=e._da,a*=e._da,i*=e._da),l??=e.PIE_OPEN,e._ellipseMode==e.CENTER?o(t,r,a,i,n,s,l):e._ellipseMode==e.RADIUS?o(t,r,2*a,2*i,n,s,l):e._ellipseMode==e.CORNER?o(t+a/2,r+i/2,a,i,n,s,l):e._ellipseMode==e.CORNERS&&o((t+a)/2,(r+i)/2,a-t,i-r,n,s,l)},e.ellipse=(t,r,a,i)=>{i??=a,e._da&&(t*=e._da,r*=e._da,a*=e._da,i*=e._da),e._ellipseMode==e.CENTER?n(t,r,a,i):e._ellipseMode==e.RADIUS?n(t,r,2*a,2*i):e._ellipseMode==e.CORNER?n(t+a/2,r+i/2,a,i):e._ellipseMode==e.CORNERS&&n((t+a)/2,(r+i)/2,a-t,i-r)},e.circle=(t,r,o)=>{e._ellipseMode==e.CENTER?(e._da&&(t*=e._da,r*=e._da,o*=e._da),e.ctx.beginPath(),e.ctx.arc(t,r,Math.abs(o/2),0,i),a()):e.ellipse(t,r,o,o)},e.point=(t,r)=>{e._doStroke&&(t.x&&(r=t.y,t=t.x),e._da&&(t*=e._da,r*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(t,r),e.ctx.stroke())},e.rect=(t,r,a,i=a,o,n,l,d)=>{e._rectMode==e.CENTER?s(t-a/2,r-i/2,a,i,o,n,l,d):e._rectMode==e.RADIUS?s(t-a,r-i,2*a,2*i,o,n,l,d):e._rectMode==e.CORNER?s(t,r,a,i,o,n,l,d):e._rectMode==e.CORNERS&&s(t,r,a-t,i-r,o,n,l,d)},e.square=(t,r,a,i,o,n,s)=>e.rect(t,r,a,a,i,o,n,s),e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(a,i)=>{e._da&&(a*=e._da,i*=e._da),r=[],t?e.ctx.moveTo(a,i):e.ctx.lineTo(a,i),t=!1},e.bezierVertex=(t,a,i,o,n,s)=>{e._da&&(t*=e._da,a*=e._da,i*=e._da,o*=e._da,n*=e._da,s*=e._da),r=[],e.ctx.bezierCurveTo(t,a,i,o,n,s)},e.quadraticVertex=(t,a,i,o)=>{e._da&&(t*=e._da,a*=e._da,i*=e._da,o*=e._da),r=[],e.ctx.quadraticCurveTo(t,a,i,o)},e.bezier=(t,r,a,i,o,n,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,i,o,n,s,l),e.endShape()},e.triangle=(t,r,a,i,o,n)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,i),e.vertex(o,n),e.endShape(e.CLOSE)},e.quad=(t,r,a,i,o,n,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,i),e.vertex(o,n),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),a()},e.curveVertex=(a,i)=>{if(e._da&&(a*=e._da,i*=e._da),r.push([a,i]),r.length<4)return;let o=r.at(-4),n=r.at(-3),s=r.at(-2),l=r.at(-1),d=n[0]+(s[0]-o[0])/6,c=n[1]+(s[1]-o[1])/6,h=s[0]-(l[0]-n[0])/6,u=s[1]-(l[1]-n[1])/6;t&&(e.ctx.moveTo(n[0],n[1]),t=!1),e.ctx.bezierCurveTo(d,c,h,u,s[0],s[1])},e.curve=(t,r,a,i,o,n,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,i),e.curveVertex(o,n),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,a,i)=>{const o=i*i*i,n=i*i;return e*(-.5*o+n-.5*i)+t*(1.5*o-2.5*n+1)+r*(-1.5*o+2*n+.5*i)+a*(.5*o-.5*n)},e.bezierPoint=(e,t,r,a,i)=>{const o=1-i;return Math.pow(o,3)*e+3*Math.pow(o,2)*i*t+3*o*Math.pow(i,2)*r+Math.pow(i,3)*a},e.curveTangent=(e,t,r,a,i)=>{const o=i*i;return e*(-3*o/2+2*i-.5)+t*(9*o/2-5*i)+r*(-9*o/2+4*i+.5)+a*(3*o/2-i)},e.bezierTangent=(e,t,r,a,i)=>{const o=1-i;return 3*a*Math.pow(i,2)-3*r*Math.pow(i,2)+6*r*o*i-6*t*o*i+3*t*Math.pow(o,2)-3*e*Math.pow(o,2)},e.erase=function(t,r){255==e._colorFormat&&(t&&(t/=255),r&&(r/=255)),e.ctx.save(),e.ctx.globalCompositeOperation="destination-out",e.ctx.fillStyle=`rgb(0 0 0 / ${t||1})`,e.ctx.strokeStyle=`rgb(0 0 0 / ${r||1})`},e.noErase=function(){e.ctx.globalCompositeOperation="source-over",e.ctx.restore()},e.inFill=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInPath(t*a,r*a)},e.inStroke=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInStroke(t*a,r*a)}},Q5.renderers.c2d.image=(e,t)=>{Q5.Image??=class{constructor(e,r,a={}){let i=this;i._scope="image",i.canvas=i.ctx=i.drawingContext=null,i.pixels=[],Q5.modules.canvas(i,i);let o=Q5.renderers.c2d;for(let e of["canvas","image","soft_filters"])o[e]&&o[e](i,i);i._pixelDensity=a.pixelDensity||1,i.createCanvas(e,r,a);let n=i._pixelDensity*t._defaultImageScale;i.defaultWidth=e*n,i.defaultHeight=r*n,delete i.createCanvas,i._loop=!1}get w(){return this.width}get h(){return this.height}},e._tint=null;let r=null;e.createImage=(t,r,a)=>(a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace||Q5.canvasOptions.colorSpace,new Q5.Image(t,r,a)),e.loadImage=function(t,r,a){if(t.canvas)return t;if("gif"==t.slice(-3).toLowerCase())throw new Error("q5 doesn't support GIFs. Use a video or p5play animation instead. https://github.com/q5js/q5.js/issues/84");let i=[...arguments].at(-1);"object"==typeof i?(a=i,r=null):a=null;let o=e.createImage(1,1,a),n=o._pixelDensity,s=new window.Image;return s.crossOrigin="Anonymous",o.promise=new Promise(((t,a)=>{s.onload=()=>{s._pixelDensity=n,o.defaultWidth=s.width*e._defaultImageScale,o.defaultHeight=s.height*e._defaultImageScale,o.naturalWidth=s.naturalWidth||s.width,o.naturalHeight=s.naturalHeight||s.height,o._setImageSize(Math.ceil(o.naturalWidth/n),Math.ceil(o.naturalHeight/n)),o.ctx.drawImage(s,0,0),r&&r(o),delete o.promise,t(o)},s.onerror=a})),e._preloadPromises.push(o.promise),o.src=s.src=t,e._usePreload?o:o.promise},e.imageMode=t=>e._imageMode=t,e.image=(t,r,a,i,o,n=0,s=0,l,d)=>{if(!t)return;let c=t.canvas||t;i??=t.defaultWidth||c.width||t.videoWidth,o??=t.defaultHeight||c.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*i,a-=.5*o),e._da&&(r*=e._da,a*=e._da,i*=e._da,o*=e._da,n*=e._da,s*=e._da,l*=e._da,d*=e._da);let h=t._pixelDensity||1;if(l?l*=h:l=c.width||c.videoWidth,d?d*=h:d=c.height||c.videoHeight,e._tint){if(t._retint||t._tint!=e._tint){t._tintImg??=e.createImage(t.w,t.h,{pixelDensity:h}),t._tintImg.width==t.width&&t._tintImg.height==t.height||t._tintImg.resize(t.w,t.h);let r=t._tintImg.ctx;r.globalCompositeOperation="copy",r.fillStyle=e._tint,r.fillRect(0,0,t.width,t.height),t.canvas.alpha&&(r.globalCompositeOperation="destination-in",r.drawImage(c,0,0,t.width,t.height)),r.globalCompositeOperation="multiply",r.drawImage(c,0,0,t.width,t.height),t._tint=e._tint,t._retint=!1}c=t._tintImg.canvas}t.flipped&&(e.ctx.save(),e.ctx.translate(r+i,0),e.ctx.scale(-1,1),r=0),e.ctx.drawImage(c,n*h,s*h,l,d,r,a,i,o),t.flipped&&e.ctx.restore()},e.filter=(t,r)=>{e.ctx.save();let a="";if(e.ctx.filter){if("string"==typeof t)a=t;else if(t==Q5.GRAY)a="saturate(0%)";else if(t==Q5.INVERT)a="invert(100%)";else if(t==Q5.BLUR){a=`blur(${Math.ceil(r*e._pixelDensity)||1}px)`}else if(t==Q5.THRESHOLD){r??=.5,a=`saturate(0%) brightness(${Math.floor(.5/Math.max(r,1e-5)*100)}%) contrast(1000000%)`}else if(t==Q5.SEPIA)a=`sepia(${r??1})`;else if(t==Q5.BRIGHTNESS)a=`brightness(${r??1})`;else if(t==Q5.SATURATION)a=`saturate(${r??1})`;else if(t==Q5.CONTRAST)a=`contrast(${r??1})`;else if(t==Q5.HUE_ROTATE){a=`hue-rotate(${r}${0==e._angleMode?"rad":"deg"})`}if(a&&(e.ctx.filter=a,"none"==e.ctx.filter))throw new Error(`Invalid filter format: ${t}`)}a||e._softFilter(t,r),e.ctx.globalCompositeOperation="source-over",e.ctx.drawImage(e.canvas,0,0,e.canvas.w,e.canvas.h),e.ctx.restore(),e.modified=e._retint=!0},"image"==e._scope&&(e.resize=(t,r)=>{let a=e.canvas,i=new e._Canvas(a.width,a.height);i.getContext("2d",{colorSpace:a.colorSpace}).drawImage(a,0,0),e._setImageSize(t,r),e.defaultWidth=a.width*e._defaultImageScale,e.defaultHeight=a.height*e._defaultImageScale,e.ctx.clearRect(0,0,a.width,a.height),e.ctx.drawImage(i,0,0,a.width,a.height),e.modified=e._retint=!0}),e._getImageData=(t,r,a,i)=>e.ctx.getImageData(t,r,a,i,{colorSpace:e.canvas.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,r=e.canvas.width,a=e.canvas.height,i=e._getImageData(0,0,r,a).data,o=r,n=0,s=a,l=0,d=3;for(let e=0;e<a;e++)for(let t=0;t<r;t++)0!==i[d]&&(t<o&&(o=t),t>n&&(n=t),e<s&&(s=e),e>l&&(l=e)),d+=4;return s=Math.floor(s/t),l=Math.floor(l/t),o=Math.floor(o/t),n=Math.floor(n/t),e.get(o,s,n-o+1,l-s+1)},e.mask=t=>{e.ctx.save(),e.ctx.resetTransform();let r=e.ctx.globalCompositeOperation;e.ctx.globalCompositeOperation="destination-in",e.ctx.drawImage(t.canvas,0,0),e.ctx.globalCompositeOperation=r,e.ctx.restore(),e.modified=e._retint=!0},e.inset=(t,r,a,i,o,n,s,l)=>{let d=e._pixelDensity||1;e.ctx.drawImage(e.canvas,t*d,r*d,a*d,i*d,o,n,s,l),e.modified=e._retint=!0},e.copy=()=>{let t=e.get();for(let r in e)"function"==typeof e[r]||/(canvas|ctx|texture|textureIndex)/.test(r)||(t[r]=e[r]);return t},e.get=(t,r,a,i)=>{let o=e._pixelDensity||1;if(void 0!==t&&void 0===a){let a=e._getImageData(t*o,r*o,1,1).data;return[a[0],a[1],a[2],a[3]/255]}t=Math.floor(t||0)*o,r=Math.floor(r||0)*o,a??=e.width,i??=e.height;let n=e.createImage(a,i,{pixelDensity:o});return n.ctx.drawImage(e.canvas,t,r,a*o,i*o,0,0,a,i),n.width=a,n.height=i,n},e.set=(t,r,a)=>{if(t=Math.floor(t),r=Math.floor(r),e.modified=e._retint=!0,a.canvas){let i=e._tint;return e._tint=null,e.image(a,t,r),void(e._tint=i)}e.pixels.length||e.loadPixels();let i=e._pixelDensity||1;for(let o=0;o<i;o++)for(let n=0;n<i;n++){let s=4*((r*i+o)*e.canvas.width+t*i+n);e.pixels[s]=a.r,e.pixels[s+1]=a.g,e.pixels[s+2]=a.b,e.pixels[s+3]=a.a}},e.loadPixels=()=>{r=e._getImageData(0,0,e.canvas.width,e.canvas.height),t.pixels=r.data},e.updatePixels=()=>{null!=r&&(e.ctx.putImageData(r,0,0),e.modified=e._retint=!0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,"image"!=e._scope&&(e._saveCanvas=async(e,t)=>{if((e=e.canvas||e)instanceof OffscreenCanvas){const r=await e.convertToBlob({type:"image/"+t});return await new Promise((e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(r)}))}return e.toDataURL("image/"+t)},e.tint=function(t){e._tint=(t._q5Color?t:e.color(...arguments)).toString()},e.noTint=()=>e._tint=null)},Q5.renderers.c2d.soft_filters=e=>{let t=null;function r(){let r=e.canvas.width*e.canvas.height*4;t&&t.length==r||(t=new Uint8ClampedArray(r))}e._softFilter=(a,i)=>{e._filters||(e._filters=[],e._filters[Q5.THRESHOLD]=(e,t)=>{void 0===t?t=127.5:t*=255;for(let r=0;r<e.length;r+=4){const a=.2126*e[r]+.7152*e[r+1]+.0722*e[r+2];e[r]=e[r+1]=e[r+2]=a>=t?255:0}},e._filters[Q5.GRAY]=e=>{for(let t=0;t<e.length;t+=4){const r=.2126*e[t]+.7152*e[t+1]+.0722*e[t+2];e[t]=e[t+1]=e[t+2]=r}},e._filters[Q5.OPAQUE]=e=>{for(let t=0;t<e.length;t+=4)e[t+3]=255},e._filters[Q5.INVERT]=e=>{for(let t=0;t<e.length;t+=4)e[t]=255-e[t],e[t+1]=255-e[t+1],e[t+2]=255-e[t+2]},e._filters[Q5.POSTERIZE]=(e,t=4)=>{let r=t-1;for(let a=0;a<e.length;a+=4)e[a]=255*(e[a]*t>>8)/r,e[a+1]=255*(e[a+1]*t>>8)/r,e[a+2]=255*(e[a+2]*t>>8)/r},e._filters[Q5.DILATE]=(a,i)=>{i??=Math.max,r(),t.set(a);let[o,n]=[e.canvas.width,e.canvas.height];for(let e=0;e<n;e++)for(let r=0;r<o;r++){let s=4*Math.max(r-1,0),l=4*Math.min(r+1,o-1),d=4*Math.max(e-1,0)*o,c=4*Math.min(e+1,n-1)*o,h=4*e*o,u=4*r;for(let e=0;e<4;e++){let r=e+d,o=e+c,n=e+h;a[h+u+e]=i(t[r+u],t[n+s],t[n+u],t[n+l],t[o+u])}}},e._filters[Q5.ERODE]=t=>{e._filters[Q5.DILATE](t,Math.min)},e._filters[Q5.BLUR]=(a,i)=>{i=i||1,i=Math.floor(i*e._pixelDensity),r(),t.set(a);let o=2*i+1,n=function(e){let t=new Float32Array(e),r=.3*i+.8,a=r*r*2;for(let i=0;i<e;i++){let o=i-e/2,n=Math.exp(-o*o/a)/(2.5066282746*r);t[i]=n}return t}(o),[s,l]=[e.canvas.width,e.canvas.height];for(let e=0;e<l;e++)for(let r=0;r<s;r++){let l=0,d=0,c=0,h=0;for(let a=0;a<o;a++){let o=4*(e*s+Math.min(Math.max(r-i+a,0),s-1));l+=t[o]*n[a],d+=t[o+1]*n[a],c+=t[o+2]*n[a],h+=t[o+3]*n[a]}let u=4*(e*s+r);a[u]=l,a[u+1]=d,a[u+2]=c,a[u+3]=h}t.set(a);for(let e=0;e<l;e++)for(let r=0;r<s;r++){let d=0,c=0,h=0,u=0;for(let a=0;a<o;a++){let o=4*(Math.min(Math.max(e-i+a,0),l-1)*s+r);d+=t[o]*n[a],c+=t[o+1]*n[a],h+=t[o+2]*n[a],u+=t[o+3]*n[a]}let p=4*(e*s+r);a[p]=d,a[p+1]=c,a[p+2]=h,a[p+3]=u}});let o=e._getImageData(0,0,e.canvas.width,e.canvas.height);e._filters[a](o.data,i),e.ctx.putImageData(o,0,0)}},Q5.renderers.c2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic",e._textSize=12;let r="sans-serif",a=!1,i=15,o=3,n="normal",s="normal",l=!1,d=0,c=[],h=!1,u=0,p=e._textCache={};e._textCacheMaxSize=12e3,e.loadFont=(t,r)=>{let a=t.split("/").pop().split(".")[0].replace(" ",""),i=new FontFace(a,`url(${t})`);return document.fonts.add(i),i.promise=(async()=>{let e;try{await i.load()}catch(t){e=t}if(delete i.promise,e)throw e;return r&&r(i),i})(),e._preloadPromises.push(i.promise),e.textFont(a),e._usePreload?i:i.promise},e.textFont=e=>{if(e&&"string"!=typeof e&&(e=e.family),!e||e==r)return r;r=e,l=!0,d=-1},e.textSize=t=>{if(null==t)return e._textSize;e._da&&(t*=e._da),e._textSize=t,l=!0,d=-1,a||(i=1.25*t,o=i-t)},e.textStyle=e=>{if(!e)return n;n=e,l=!0,d=-1},e.textWeight=e=>{if(!e)return s;s=e,l=!0,d=-1},e.textLeading=t=>null==t?i||1.25*e._textSize:(a=!0,t==i?i:(e._da&&(t*=e._da),i=t,o=t-e._textSize,void(d=-1))),e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r)};const f=()=>{e.ctx.font=`${n} ${s} ${e._textSize}px ${r}`,l=!1};e.textWidth=t=>(l&&f(),e.ctx.measureText(t).width),e.textAscent=t=>(l&&f(),e.ctx.measureText(t).actualBoundingBoxAscent),e.textDescent=t=>(l&&f(),e.ctx.measureText(t).actualBoundingBoxDescent),e.textFill=e.fill,e.textStroke=e.stroke;e.createTextImage=(t,r,a)=>{h=!0;let i=e.text(t,0,0,r,a);return h=!1,i};let g=[];e.text=(t,a,s,_,m)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString(),e._da&&(a*=e._da,s*=e._da);let x,v,y,b,w=e.ctx;if(l&&f(),h&&(-1==d&&(()=>{let t=r+e._textSize+n+i,a=5381;for(let e=0;e<t.length;e++)a=33*a^t.charCodeAt(e);d=a>>>0})(),x=p[t],x&&(x=x[d]),x)){if(x._fill==e._fill&&x._stroke==e._stroke&&x._strokeWeight==e._strokeWeight)return x;x.clear()}if(-1==t.indexOf("\n")?g[0]=t:g=t.split("\n"),t.length>_){let e=[];for(let t of g){let r=0;for(;r<t.length;){let a=r+_;if(a>=t.length){e.push(t.slice(r));break}let i=t.lastIndexOf(" ",a);(-1===i||i<r)&&(i=a),e.push(t.slice(r,i)),r=i+1}}g=e}if(h){if(v=0,y=i,x)x.modified=!0;else{let t=e.ctx.textBaseline;e.ctx.textBaseline="alphabetic";let r=w.measureText(" "),a=r.fontBoundingBoxAscent,n=r.fontBoundingBoxDescent;e.ctx.textBaseline=t;let s=0;for(let e of g){let t=w.measureText(e).width;t>s&&(s=t)}let l=Math.ceil(s),d=Math.ceil(i*g.length+n);x=e.createImage.call(e,l,d,{pixelDensity:e._pixelDensity}),x._ascent=a,x._descent=n,x._top=n+o,x._middle=x._top+.5*a+i*(g.length-1)*.5,x._bottom=x._top+a+i*(g.length-1),x._leading=i}x._fill=e._fill,x._stroke=e._stroke,x._strokeWeight=e._strokeWeight,w=x.ctx,w.font=e.ctx.font,w.fillStyle=e._fill,w.strokeStyle=e._stroke,w.lineWidth=e.ctx.lineWidth}else v=a,y=s,"middle"==e._textBaseline?y-=i*(g.length-1)*.5:"bottom"==e._textBaseline&&(y-=i*(g.length-1));e._fillSet||(b=w.fillStyle,w.fillStyle="black");let S=0;for(let t of g)if(e._doStroke&&e._strokeSet&&w.strokeText(t,v,y),e._doFill&&w.fillText(t,v,y),y+=i,S++,S>=m)break;if(g=[],e._fillSet||(w.fillStyle=b),h){if(c.push(d),(p[t]??={})[d]=x,u++,u>e._textCacheMaxSize){let e=Math.ceil(u/2),t=c.splice(0,e);for(let e in p){e=p[e];for(let r of t)delete e[r]}u-=e}return e.save(x),x}},e.textImage=(t,r,a)=>{"string"==typeof t&&(t=e.createTextImage(t));let i=e._imageMode;e._imageMode="corner";let o=e._textAlign;"center"==o?r-=t.canvas.hw:"right"==o&&(r-=t.width);let n=e._textBaseline;"alphabetic"==n?a-=t._leading:"middle"==n?a-=t._middle:"bottom"==n?a-=t._bottom:"top"==n&&(a-=t._top),e.image(t,r,a),e._imageMode=i}},Q5.fonts=[],Q5.modules.color=(e,t)=>{e.RGB=e.RGBA=e.RGBHDR=e._colorMode="rgb",e.HSL="hsl",e.HSB="hsb",e.OKLCH="oklch",e.SRGB="srgb",e.DISPLAY_P3="display-p3",e.colorMode=(r,a,i)=>{e._colorMode=r;let o="srgb"==e.canvas.colorSpace||"srgb"==i;a??="rgb"==r&&(e._c2d||o)?255:1,e._colorFormat="integer"==a||255==a?255:1,"oklch"==r?t.Color=Q5.ColorOKLCH:"hsl"==r?t.Color=o?Q5.ColorHSL:Q5.ColorHSL_P3:"hsb"==r?t.Color=o?Q5.ColorHSB:Q5.ColorHSB_P3:(255==e._colorFormat?t.Color=o?Q5.ColorRGB_8:Q5.ColorRGB_P3_8:t.Color=o?Q5.ColorRGB:Q5.ColorRGB_P3,e._colorMode="rgb")},e._namedColors={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],cyan:[0,255,255],darkviolet:[148,0,211],gold:[255,215,0],green:[0,128,0],gray:[128,128,128],grey:[128,128,128],hotpink:[255,105,180],indigo:[75,0,130],khaki:[240,230,140],lightgreen:[144,238,144],lime:[0,255,0],magenta:[255,0,255],navy:[0,0,128],orange:[255,165,0],olive:[128,128,0],peachpuff:[255,218,185],pink:[255,192,203],purple:[128,0,128],red:[255,0,0],skyblue:[135,206,235],tan:[210,180,140],turquoise:[64,224,208],transparent:[0,0,0,0],white:[255,255,255],violet:[238,130,238],yellow:[255,255,0]},e.color=(t,r,a,i)=>{let o=e.Color;if(t._q5Color)return new o(...t.levels);if(null==r){if("string"==typeof t){if("#"==t[0])t.length<=5?(t.length>4&&(i=parseInt(t[4]+t[4],16)),a=parseInt(t[3]+t[3],16),r=parseInt(t[2]+t[2],16),t=parseInt(t[1]+t[1],16)):(t.length>7&&(i=parseInt(t.slice(7,9),16)),a=parseInt(t.slice(5,7),16),r=parseInt(t.slice(3,5),16),t=parseInt(t.slice(1,3),16));else{if(!e._namedColors[t]){let e=new o(0,0,0);return e._css=t,e.toString=function(){return this._css},e}[t,r,a,i]=e._namedColors[t]}1==e._colorFormat&&(t/=255,r&&(r/=255),a&&(a/=255),i&&(i/=255))}(Array.isArray(t)||t.constructor==Float32Array)&&([t,r,a,i]=t)}return null==a?e._colorMode==Q5.OKLCH?new o(t,0,0,r):new o(t,t,t,r):new o(t,r,a,i)},e.red=e=>e.r,e.green=e=>e.g,e.blue=e=>e.b,e.alpha=e=>e.a,e.lightness=t=>{if(t.l)return t.l;let r=100*(.2126*t.r+.7152*t.g+.0722*t.b);return 255==e._colorFormat?r/255:r},e.hue=t=>{if(t.h)return t.h;let r=t.r,a=t.g,i=t.b;255==e._colorFormat&&(r/=255,a/=255,i/=255);let o,n=Math.max(r,a,i),s=Math.min(r,a,i);return o=n==s?0:n==r?60*(a-i)/(n-s):n==a?60*(i-r)/(n-s)+120:60*(r-a)/(n-s)+240,o<0&&(o+=360),o},e.lerpColor=(t,r,a)=>{if(a=Math.max(0,Math.min(1,a)),"rgb"==e._colorMode)return new e.Color(e.lerp(t.r,r.r,a),e.lerp(t.g,r.g,a),e.lerp(t.b,r.b,a),e.lerp(t.a,r.a,a));{let i=r.h-t.h;i>180&&(i-=360),i<-180&&(i+=360);let o=t.h+a*i;return o<0&&(o+=360),o>360&&(o-=360),new e.Color(e.lerp(t.l,r.l,a),e.lerp(t.c,r.c,a),o,e.lerp(t.a,r.a,a))}}},Q5.Color=class{constructor(){this._q5Color=!0}get alpha(){return this.a}set alpha(e){this.a=e}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,a){super(),this.l=e,this.c=t,this.h=r,this.a=a??1}get levels(){return[this.l,this.c,this.h,this.a]}equals(e){return e&&this.l==e.l&&this.c==e.c&&this.h==e.h&&this.a==e.a}isSameColor(e){return e&&this.l==e.l&&this.c==e.c&&this.h==e.h}toString(){return`oklch(${this.l} ${this.c} ${this.h} / ${this.a})`}get lightness(){return this.l}set lightness(e){this.l=e}get chroma(){return this.c}set chroma(e){this.c=e}get hue(){return this.h}set hue(e){this.h=e}},Q5.ColorRGB=class extends Q5.Color{constructor(e,t,r,a){super(),this.r=e,this.g=t,this.b=r,this.a=a??1}get levels(){return[this.r,this.g,this.b,this.a]}equals(e){return e&&this.r==e.r&&this.g==e.g&&this.b==e.b&&this.a==e.a}isSameColor(e){return e&&this.r==e.r&&this.g==e.g&&this.b==e.b}toString(){return`color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`}get red(){return this.r}set red(e){this.r=e}get green(){return this.g}set green(e){this.g=e}get blue(){return this.b}set blue(e){this.b=e}},Q5.ColorRGB_P3=class extends Q5.ColorRGB{toString(){return`color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGB_8=class extends Q5.ColorRGB{constructor(e,t,r,a){super(e,t,r,a??255)}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGB_P3_8=class extends Q5.ColorRGB_8{constructor(e,t,r,a){super(e,t,r,a??255),this._edited=!0}get r(){return this._r}set r(e){this._r=e,this._edited=!0}get g(){return this._g}set g(e){this._g=e,this._edited=!0}get b(){return this._b}set b(e){this._b=e,this._edited=!0}get a(){return this._a}set a(e){this._a=e,this._edited=!0}toString(){if(this._edited){let e=(this._r/255).toFixed(3),t=(this._g/255).toFixed(3),r=(this._b/255).toFixed(3),a=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${a})`,this._edited=!1}return this._css}},Q5.ColorHSL=class extends Q5.Color{constructor(e,t,r,a){super(),this.h=e,this.s=t,this.l=r,this.a=a??1}get levels(){return[this.h,this.s,this.l,this.a]}equals(e){return e&&this.h==e.h&&this.s==e.s&&this.l==e.l&&this.a==e.a}isSameColor(e){return e&&this.h==e.h&&this.s==e.s&&this.l==e.l}toString(){return`hsl(${this.h} ${this.s} ${this.l} / ${this.a})`}get hue(){return this.h}set hue(e){this.h=e}get saturation(){return this.s}set saturation(e){this.s=e}get lightness(){return this.l}set lightness(e){this.l=e}},Q5.ColorHSL_P3=class extends Q5.ColorHSL{toString(){return`color(display-p3 ${Q5.HSLtoRGB(this.h,this.s,this.l).join(" ")} / ${this.a})`}},Q5.ColorHSB=class extends Q5.ColorHSL{constructor(e,t,r,a){super(e,t,r,a),delete this.l,this.b=r}get levels(){return[this.h,this.s,this.b,this.a]}equals(e){return e&&this.h==e.h&&this.s==e.s&&this.b==e.b&&this.a==e.a}isSameColor(e){return e&&this.h==e.h&&this.s==e.s&&this.b==e.b}toString(){return`hsl(${Q5.HSBtoHSL(this.h,this.s,this.b).join(" ")} / ${this.a})`}get v(){return this.b}set v(e){this.b=e}get brightness(){return this.b}set brightness(e){this.b=e}get value(){return this.b}set value(e){this.b=e}},Q5.ColorHSB_P3=class extends Q5.ColorHSB{toString(){return`color(display-p3 ${Q5.HSLtoRGB(...Q5.HSBtoHSL(this.h,this.s,this.b)).join(" ")} / ${this.a})`}},Q5.HSLtoRGB=(e,t,r)=>{r/=100;let a=t/100*Math.min(r,1-r),i=(t,i=(t+e/30)%12)=>r-a*Math.max(Math.min(i-3,9-i,1),-1);return[i(0),i(8),i(4)]},Q5.HSBtoHSL=(e,t,r,a=r*(1-t/200))=>[e,a&&100!=a?(r-a)/Math.min(a,100-a)*100:0,a];{const e=(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2],e[3]*t[0]+e[4]*t[1]+e[5]*t[2],e[6]*t[0]+e[7]*t[1]+e[8]*t[2]],t=(e,t,r)=>[e,isNaN(r)?0:t*Math.cos(r*Math.PI/180),isNaN(r)?0:t*Math.sin(r*Math.PI/180)],r=e=>e.map((e=>Math.max(0,Math.min(1,Math.abs(e)>.0031308?(e<0?-1:1)*(1.055*Math.abs(e)**(1/2.4)-.055):12.92*e)))),a=t=>{const r=e([1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092],t);return e([1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],r.map((e=>e**3)))},i=t=>e([3.2409699419045226,-1.537383177570094,-.4986107602930034,-.9692436362808796,1.8759675015077202,.04155505740717559,.05563007969699366,-.20397695888897652,1.0569715142428786],t);Q5.OKLCHtoRGB=(e,o,n)=>r(i(a(t(e,o,n))))}Q5.modules.display=e=>{if(!e.canvas||"graphics"==e._scope)return;let t=e.canvas;e.MAXED="maxed",e.SMOOTH="smooth",e.PIXELATED="pixelated",0!=Q5._instanceCount||Q5._server||document.head.insertAdjacentHTML("beforeend","<style>\nhtml, body {\n\tmargin: 0;\n\tpadding: 0;\n}\n.q5Canvas {\n\toutline: none;\n\t-webkit-touch-callout: none;\n\t-webkit-text-size-adjust: none;\n\t-webkit-user-select: none;\n\toverscroll-behavior: none;\n}\n.q5-pixelated {\n\timage-rendering: pixelated;\n\tfont-smooth: never;\n\t-webkit-font-smoothing: none;\n}\n.q5-centered,\n.q5-maxed {\n display: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\nmain.q5-centered,\nmain.q5-maxed {\n\theight: 100vh;\n}\nmain {\n\toverscroll-behavior: none;\n}\n</style>"),e._adjustDisplay=()=>{let r=t.style,a=t.parentElement;r&&a&&t.displayMode&&("pixelated"==t.renderQuality&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.defaultImageScale(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),"normal"==t.displayMode?(a.classList.remove("q5-centered","q5-maxed"),r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"):(a.classList.add("q5-"+t.displayMode),a=a.getBoundingClientRect(),t.w/t.h>a.width/a.height?("centered"==t.displayMode?(r.width=t.w*t.displayScale+"px",r.maxWidth="100%"):r.width="100%",r.height="auto",r.maxHeight=""):(r.width="auto",r.maxWidth="","centered"==t.displayMode?(r.height=t.h*t.displayScale+"px",r.maxHeight="100%"):r.height="100%")))},e.displayMode=(r="normal",a="smooth",i=1)=>{"string"==typeof i&&(i=parseFloat(i.slice(1))),"fullscreen"==r&&(r="maxed"),"center"==r&&(r="centered"),Object.assign(t,{displayMode:r,renderQuality:a,displayScale:i}),e.ctx&&e.pushStyles(),e._adjustDisplay(),e.ctx&&e.popStyles()},e.fullscreen=e=>{if(null==e)return document.fullscreenElement;e?document.body.requestFullscreen():document.body.exitFullscreen()}},Q5.modules.dom=(e,t)=>{e.elementMode=t=>e._elementMode=t,e.createElement=(t,r)=>{let a=document.createElement(t);return"center"==e._elementMode&&(a.style.transform="translate(-50%, -50%)"),r&&(a.innerHTML=r),Object.defineProperty(a,"x",{get:()=>a._x,set:t=>{let r=a.style.position;r&&"relative"!=r||(a.style.position="absolute");let i=e.canvas.offsetLeft+t;a.style.left=i+"px",a._x=i}}),Object.defineProperty(a,"y",{get:()=>a._y,set:t=>{let r=a.style.position;r&&"relative"!=r||(a.style.position="absolute");let i=e.canvas.offsetTop+t;a.style.top=i+"px",a._y=i}}),Object.defineProperty(a,"width",{get:()=>parseFloat(a.style.width||0),set:e=>a.style.width=e+"px"}),Object.defineProperty(a,"height",{get:()=>parseFloat(a.style.height||0),set:e=>a.style.height=e+"px"}),a.position=(e,t,r)=>(r&&(a.style.position=r),a.x=e,a.y=t,a),Object.defineProperty(a,"size",{writable:!0}),a.size=(e,t)=>(a.width=e,a.height=t,a),a.center=()=>(a.style.position="absolute",a.x=e.canvas.hw,a.y=e.canvas.hh,a),a.show=()=>(a.style.display="",a),a.hide=()=>(a.style.display="none",a),a.parent=e=>(e.append(a),a),e._addEventMethods(a),e._elements.push(a),e.canvas?e.canvas.parentElement.append(a):document.body.append(a),a.elt=a,a},e.createEl=e.createElement,e._addEventMethods=e=>{let t=e.addEventListener;e.mousePressed=e=>t("mousedown",e),e.mouseReleased=e=>t("mouseup",e),e.mouseClicked=e=>t("click",e),e.mouseMoved=e=>t("mousemove",e),e.mouseWheel=e=>t("wheel",e)},e.createA=(t,r,a)=>{let i=e.createEl("a",r);return i.href=t,i.target=a?"_blank":"_self",i},e.createButton=t=>e.createEl("button",t),e.createCheckbox=(t="",r=!1)=>{let a=e.createEl("input");a.type="checkbox",a.checked=r;let i=e.createEl("label",t);return i.addEventListener("click",(()=>{a.checked=!a.checked,a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}))})),a.insertAdjacentElement("afterend",i),a.label=i,a},e.createColorPicker=(t="#ffffff")=>{let r=e.createEl("input");return r.type="color",r.value=t.toString(),r},e.createDiv=t=>e.createEl("div",t),e.createImg=t=>{let r=e.createEl("img");return r.crossOrigin="anonymous",r.src=t,r},e.createInput=(t="",r="text")=>{let a=e.createEl("input");return a.value=t,a.type=r,a.style.boxSizing="border-box",a},e.createP=t=>e.createEl("p",t);let r=0;e.createRadio=t=>{let a=e.createEl("div");return a.name=t||"radio"+r++,a.buttons=[],Object.defineProperty(a,"value",{get:()=>a.selected?.value,set:e=>{let t=a.buttons.find((t=>t.value==e));t&&(t.checked=!0,a.selected=t)}}),a.option=(t,r)=>{let i=e.createEl("input");i.type="radio",i.name=a.name,i.value=r||t,i.addEventListener("input",(()=>a.selected=i));let o=e.createEl("label",t);return o.addEventListener("click",(()=>{i.checked=!0,a.selected=i,i.dispatchEvent(new Event("input",{bubbles:!0})),i.dispatchEvent(new Event("change",{bubbles:!0}))})),i.label=o,a.append(i),a.append(o),a.buttons.push(i),a},a},e.createSelect=t=>{let r=e.createEl("select");if(t){let a=e.createEl("option",t);a.disabled=!0,a.selected=!0,r.append(a)}return Object.defineProperty(r,"selected",{get:()=>r.multiple?Array.from(r.selectedOptions).map((e=>e.textContent)):r.selectedOptions[0]?.textContent,set:e=>{if(r.multiple)Array.from(r.options).forEach((t=>{t.selected=e.includes(t.textContent)}));else{const t=Array.from(r.options).find((t=>t.textContent===e));t&&(t.selected=!0)}}}),Object.defineProperty(r,"value",{get:()=>r.multiple?Array.from(r.selectedOptions).map((e=>e.value)):r.selectedOptions[0]?.value,set:e=>{if(r.multiple)r.options.forEach((t=>t.selected=e.includes(t.value)));else{let t;for(let a=0;a<r.options.length;a++)if(r.options[a].value==e){t=r.options[a];break}t&&(t.selected=!0)}}}),r.option=(t,a)=>{let i=e.createEl("option",t);return i.value=a||t,r.append(i),r},r},e.createSlider=(t,r,a,i)=>{let o=e.createEl("input");return o.type="range",o.min=t,o.max=r,o.value=a,o.step=i,o.val=()=>parseFloat(o.value),o},e.createSpan=t=>e.createEl("span",t),e.createVideo=t=>{let r=e.createEl("video");return r.crossOrigin="anonymous",r._load=()=>{r.width||=r.videoWidth,r.height||=r.videoHeight,r.defaultWidth=r.width*e._defaultImageScale,r.defaultHeight=r.height*e._defaultImageScale,r.ready=!0},t&&(r.promise=new Promise((e=>{r.addEventListener("loadeddata",(()=>{r._load(),e(r)})),r.src=t})),e._preloadPromises.push(r.promise),!e._usePreload)?r.promise:r},e.createCapture=function(t,r=!0,a){let i="string"==typeof t?{[t]:!0}:t||{video:!0,audio:!0};!0===i.video&&(i.video={width:3840,height:2160}),i.video.facingMode??="user";let o=e.createVideo();return o.playsinline=o.autoplay=!0,r&&(o.flipped=!0,o.style.transform="scale(-1, 1)"),o.loadPixels=()=>{let t=e.createGraphics(o.videoWidth,o.videoHeight,{renderer:"c2d"});t.image(o,0,0),t.loadPixels(),o.pixels=t.pixels,t.remove()},o.promise=(async()=>{let e;try{e=await navigator.mediaDevices.getUserMedia(i)}catch(e){throw e}return o.srcObject=e,await new Promise((e=>o.addEventListener("loadeddata",e))),o._load(),a&&a(o),o})(),e._preloadPromises.push(o.promise),e._usePreload?o:o.promise},e.findElement=e=>document.querySelector(e),e.findElements=e=>document.querySelectorAll(e)},Q5.modules.fes=e=>{e._fes=async e=>{if(Q5.disableFriendlyErrors)return;let t=e.stack?.split("\n");if(!e.stack||t.length<=1)return;let r=1,a="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(r=0,a="@");t[r].indexOf("q5")>=0;)r++;let i=t[r].split(a).at(-1);i.startsWith("blob:")&&(i=i.slice(5));let o=i.split(":"),n=parseInt(o.at(-2));o[o.length-1]=o.at(-1).split(")")[0];let s=o.slice(0,-2).join(":"),l=s.split("/").at(-1);try{let e=(await(await fetch(s)).text()).split("\n")[n-1].trim(),t=["🐛","🐞","🐜","🦗","🦋","🪲"][Math.floor(6*Math.random())];console.log("%cq5.js "+t+"%c Error in "+l+" on line "+n+":\n\n"+e,"background: #b7ebff; color: #000;","")}catch(e){}}},Q5.modules.input=(e,t)=>{if("graphics"==e._scope)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.mouseButton="",e.keyIsPressed=!1,e.mouseIsPressed=!1,e.key="",e.keyCode=0,e.UP_ARROW=38,e.DOWN_ARROW=40,e.LEFT_ARROW=37,e.RIGHT_ARROW=39,e.SHIFT=16,e.TAB=9,e.BACKSPACE=8,e.ENTER=e.RETURN=13,e.ALT=e.OPTION=18,e.CONTROL=17,e.DELETE=46,e.ESCAPE=27,e.ARROW="default",e.CROSS="crosshair",e.HAND="pointer",e.MOVE="move",e.TEXT="text";let r={},a=[Q5.LEFT,Q5.CENTER,Q5.RIGHT],i=e.canvas;e._startAudio=()=>{Q5.aud&&"running"==Q5.aud?.state||e.userStartAudio()},e._updateMouse=r=>{if(!r.changedTouches){if(i){let a=i.getBoundingClientRect(),o=i.scrollWidth/e.width||1,n=i.scrollHeight/e.height||1;t.mouseX=(r.clientX-a.left)/o,t.mouseY=(r.clientY-a.top)/n,e._webgpu&&(t.mouseX-=i.hw,t.mouseY-=i.hh)}else t.mouseX=r.clientX,t.mouseY=r.clientY;t.moveX=r.movementX,t.moveY=r.movementY}};let o=0;function n(t){const r=e.canvas.getBoundingClientRect(),a=e.canvas.scrollWidth/e.width||1,i=e.canvas.scrollHeight/e.height||1;let o=0,n=0;return e._webgpu&&(o=e.halfWidth,n=e.halfHeight),{x:(t.clientX-r.left)/a-o,y:(t.clientY-r.top)/i-n,id:t.identifier}}if(e._onmousedown=r=>{o++,e._startAudio(),e._updateMouse(r),t.mouseIsPressed=!0,t.mouseButton=a[r.button],e.mousePressed(r)},e._onmousemove=t=>{e._updateMouse(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t)},e._onmouseup=r=>{e._updateMouse(r),t.mouseIsPressed=!1,e.mouseReleased(r)},e._onclick=r=>{e._updateMouse(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e._onwheel=t=>{e._updateMouse(t),t.delta=t.deltaY,(0==e.mouseWheel(t)||e._noScroll)&&t.preventDefault()},e.cursor=(t,r,a)=>{let i="";t.includes(".")&&(t=`url("${t}")`,i=", auto"),void 0!==r&&(t+=" "+r+" "+a),e.canvas.style.cursor=t+i},e.noCursor=()=>e.canvas.style.cursor="none",e.noScroll=()=>e._noScroll=!0,window&&(e.lockMouse=document.body?.requestPointerLock,e.unlockMouse=document.exitPointerLock),e._onkeydown=a=>{a.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(a),1==a.key.length&&e.keyTyped(a))},e._onkeyup=a=>{t.keyIsPressed=!1,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(a)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._ontouchstart=r=>{e._startAudio(),t.touches=[...r.touches].map(n),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,t.mouseIsPressed=!0,t.mouseButton=e.LEFT,e.mousePressed(r)),e.touchStarted(r)},e._ontouchmove=r=>{t.touches=[...r.touches].map(n),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,e.mouseDragged(r)||r.preventDefault()),e.touchMoved(r)||r.preventDefault()},e._ontouchend=r=>{t.touches=[...r.touches].map(n),e._isTouchAware||e.touches.length||(t.mouseIsPressed=!1,e.mouseReleased(r)||r.preventDefault()),e.touchEnded(r)||r.preventDefault()},i){let t=i.addEventListener.bind(i);t("mousedown",(t=>e._onmousedown(t))),t("wheel",(t=>e._onwheel(t))),t("click",(t=>e._onclick(t))),t("touchstart",(t=>e._ontouchstart(t))),t("touchmove",(t=>e._ontouchmove(t))),t("touchend",(t=>e._ontouchend(t))),t("touchcancel",(t=>e._ontouchend(t)))}if(window){let t=window.addEventListener;t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1),i||(t("mousedown",(t=>e._onmousedown(t))),t("wheel",(t=>e._onwheel(t))),t("click",(t=>e._onclick(t)))),t("mousemove",(t=>e._onmousemove(t)),!1),t("mouseup",(t=>{o>0&&(o--,e._onmouseup(t))}))}},Q5.modules.math=(e,t)=>{e.RADIANS=0,e.DEGREES=1,e.PI=Math.PI,e.HALF_PI=Math.PI/2,e.QUARTER_PI=Math.PI/4,e.TWO_PI=e.TAU=2*Math.PI,e.abs=Math.abs,e.ceil=Math.ceil,e.exp=Math.exp,e.floor=e.int=Math.floor,e.loge=Math.log,e.mag=Math.hypot,e.max=Math.max,e.min=Math.min,e.pow=Math.pow,e.sqrt=Math.sqrt,e.SHR3=1,e.LCG=2,e.round=(e,t=0)=>{let r=10**t;return Math.round(e*r)/r};let r=e._angleMode=0;e.angleMode=t=>(r=e._angleMode=0==t||"radians"==t?0:1,r?"degrees":"radians");let a=e._DEGTORAD=Math.PI/180,i=e._RADTODEG=180/Math.PI;function o(){let e,t,r=4294967295;return{setSeed(a){e=t=(a??Math.random()*r)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/r)}}e.degrees=t=>t*e._RADTODEG,e.radians=t=>t*e._DEGTORAD,e.map=Q5.prototype.map=(e,t,r,a,i,o)=>{let n=a+1*(e-t)/(r-t)*(i-a);return o?a<i?Math.min(Math.max(n,a),i):Math.min(Math.max(n,i),a):n},e.dist=function(){let e=arguments;return 2==e.length?Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y):4==e.length?Math.hypot(e[0]-e[2],e[1]-e[3]):Math.hypot(e[0]-e[3],e[1]-e[4],e[2]-e[5])},e.lerp=(e,t,r)=>e*(1-r)+t*r,e.constrain=(e,t,r)=>Math.min(Math.max(e,t),r),e.norm=(t,r,a)=>e.map(t,r,a,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*a:e),e.cos=e=>Math.cos(r?e*a:e),e.tan=e=>Math.tan(r?e*a:e),e.asin=e=>{let t=Math.asin(e);return r?t*i:t},e.acos=e=>{let t=Math.acos(e);return r?t*i:t},e.atan=e=>{let t=Math.atan(e);return r?t*i:t},e.atan2=(e,t)=>{let a=Math.atan2(e,t);return r?a*i:a};let n=o();n.setSeed(),e.randomSeed=e=>n.setSeed(e),e.random=(e,t)=>void 0===e?n.rand():"number"==typeof e?void 0!==t?n.rand()*(t-e)+e:n.rand()*e:e[Math.trunc(e.length*n.rand())],e.jit=(t=1)=>e.random(-t,t),e.randomGenerator=t=>{t==e.LCG?n=function(){const e=4294967296;let t,r;return{setSeed(a){r=t=(a??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(n=o()),n.setSeed()};var s=new function(){var e,t,r,a=new Array(128),i=new Array(256),o=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*n.rand()-2147483648,h=()=>.5+2.328306e-10*(c()|0),u=()=>{for(var t,i,n,l,d=3.44262;;){if(t=r*o[e],0==e){do{n=h(),l=h(),t=.2904764*-Math.log(n),i=-Math.log(l)}while(i+i<t*t);return r>0?d+t:-d-t}if(s[e]+h()*(s[e-1]-s[e])<Math.exp(-.5*t*t))return t;if(r=c(),e=127&r,Math.abs(r)<a[e])return r*o[e]}},p=()=>{for(var r;;){if(0==e)return 7.69711-Math.log(h());if(r=t*l[e],d[e]+h()*(d[e-1]-d[e])<Math.exp(-r))return r;if((t=c())<i[e=255&t])return t*l[e]}};this.SHR3=c,this.UNI=h,this.RNOR=()=>(r=c(),e=127&r,Math.abs(r)<a[e]?r*o[e]:u()),this.REXP=()=>(t=c()>>>0)<a[e=255&t]?t*l[e]:p(),this.zigset=()=>{var e,t,r=2147483648,n=4294967296,c=3.442619855899,h=c,u=.00991256303526217,p=7.697117470131487,f=p,g=.003949659822581572;for(e=u/Math.exp(-.5*c*c),a[0]=Math.floor(c/e*r),a[1]=0,o[0]=e/r,o[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),a[t+1]=Math.floor(c/h*r),h=c,s[t]=Math.exp(-.5*c*c),o[t]=c/r;for(e=g/Math.exp(-p),i[0]=Math.floor(p/e*n),i[1]=0,l[0]=e/n,l[255]=p/n,d[0]=1,d[255]=Math.exp(-p),t=254;t>=1;t--)p=-Math.log(g/p+Math.exp(-p)),i[t+1]=Math.floor(p/f*n),f=p,d[t]=Math.exp(-p),l[t]=p/n}};let l;s.hasInit=!1,e.randomGaussian=(e,t)=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.RNOR()*t+e),e.randomExponential=()=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.REXP()),e.PERLIN="perlin",e.SIMPLEX="simplex",e.BLOCKY="blocky",e.NoiseGenerator=Q5.PerlinNoise,e.noiseMode=e=>{t.NoiseGenerator=Q5[e[0].toUpperCase()+e.slice(1)+"Noise"],l=null},e.noiseSeed=t=>{l=new e.NoiseGenerator(t)},e.noise=(t=0,r=0,a=0)=>(l??=new e.NoiseGenerator,l.noise(t,r,a)),e.noiseDetail=(t,r)=>{l??=new e.NoiseGenerator,t>0&&(l.octaves=t),r>0&&(l.falloff=r)}},Q5.NoiseGenerator=class{},Q5.PerlinNoise=class extends Q5.NoiseGenerator{constructor(e){super(),this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.octaves=1,this.falloff=.5,this.p=null==e?Array.from({length:256},(()=>Math.floor(256*Math.random()))):this.seedPermutation(e),this.p=this.p.concat(this.p)}seedPermutation(e){let t,r,a=[];for(let e=0;e<256;e++)a[e]=e;for(let i=255;i>0;i--)t=(e=16807*e%2147483647)%(i+1),r=a[i],a[i]=a[t],a[t]=r;return a}dot(e,t,r,a){return e[0]*t+e[1]*r+e[2]*a}mix(e,t,r){return(1-r)*e+r*t}fade(e){return e*e*e*(e*(6*e-15)+10)}noise(e,t,r){let a=this,i=0,o=1,n=1,s=0;for(let l=0;l<a.octaves;l++){const l=255&Math.floor(e*o),d=255&Math.floor(t*o),c=255&Math.floor(r*o),h=e*o-Math.floor(e*o),u=t*o-Math.floor(t*o),p=r*o-Math.floor(r*o),f=a.fade(h),g=a.fade(u),_=a.fade(p),m=a.p[l]+d,x=a.p[m]+c,v=a.p[m+1]+c,y=a.p[l+1]+d,b=a.p[y]+c,w=a.p[y+1]+c,S=a.mix(a.dot(a.grad3[a.p[x]%12],h,u,p),a.dot(a.grad3[a.p[b]%12],h-1,u,p),f),M=a.mix(a.dot(a.grad3[a.p[v]%12],h,u-1,p),a.dot(a.grad3[a.p[w]%12],h-1,u-1,p),f),C=a.mix(a.dot(a.grad3[a.p[x+1]%12],h,u,p-1),a.dot(a.grad3[a.p[b+1]%12],h-1,u,p-1),f),Q=a.mix(a.dot(a.grad3[a.p[v+1]%12],h,u-1,p-1),a.dot(a.grad3[a.p[w+1]%12],h-1,u-1,p-1),f),P=a.mix(S,M,g),E=a.mix(C,Q,g);i+=a.mix(P,E,_)*n,s+=n,n*=a.falloff,o*=2}return(i/s+1)/2}},Q5.modules.record=(e,t)=>{let r,a,i,o,n,s,l;function d(t={}){document.head.insertAdjacentHTML("beforeend","<style>\n.rec {\n\tdisplay: flex;\n\tz-index: 1000;\n\tgap: 6px;\n\tbackground: #1a1b1d;\n\tpadding: 6px 8px;\n\tborder-radius: 21px;\n\tbox-shadow: #0000001a 0px 4px 12px;\n\tborder: 2px solid transparent; \n\topacity: 0.6;\n\ttransition: all 0.3s;\n\twidth: 134px;\n\toverflow: hidden;\n}\n\n.rec:hover {\n\twidth: unset;\n\topacity: 0.96;\n}\n\n.rec.recording { border-color: #cc3e44; }\n\n.rec button,\n.rec select { cursor: pointer; }\n\n.rec button,\n.rec select,\n.rec input,\n.rec span {\n\tfont-family: sans-serif;\n\tfont-size: 14px;\n\tpadding: 2px 10px;\n\tborder-radius: 18px;\n\toutline: none;\n\tbackground: #232529;\n\tcolor: #d4dae6;\n\tbox-shadow: #0000001a 0px 4px 12px;\n\tborder: 1px solid #46494e;\n\tvertical-align: middle;\n\tline-height: 18px;\n\ttransition: all 0.3s;\n}\n\n.rec .audio-toggle {\n\tfont-size: 16px;\n\tpadding: 2px 10px;\n}\n\n.rec .bitrate input {\n\tborder-radius: 18px 0 0 18px;\n\tborder-right: 0;\n\twidth: 40px;\n\tpadding: 2px 5px 2px 10px;\n\ttext-align: right;\n}\n\n.rec .bitrate span {\n\tborder-radius: 0 18px 18px 0;\n\tborder-left: 0;\n\tpadding: 2px 10px 2px 5px;\n\tbackground: #333;\n}\n\n.rec .record-button { \n\tcolor: #cc3e44;\n\tfont-size: 18px;\n}\n\n.rec select:hover,\n.rec button:hover { background: #32343b; }\n\n.rec button:disabled {\n\topacity: 0.5;\n\tcolor: #969ba5;\n\tcursor: not-allowed;\n}\n</style>"),r=e.createEl("div"),r.className="rec",r.innerHTML='\n<button class="record-button"></button>\n<span class="record-timer"></span>\n<button></button>\n',[a,o,i]=r.children,r.x=r.y=8,r.resetTimer=()=>r.time={hours:0,minutes:0,seconds:0,frames:0},r.resetTimer();let d="video/mp4; codecs=";r.formats={"H.264":d+'"avc1.42E01E"',VP9:d+"vp9"};let u=d+'"avc1.640034"';e.canvas.width*e.canvas.height>32e5&&MediaRecorder.isTypeSupported(u)&&(r.formats["H.264"]=u),Object.assign(r.formats,t.formats),n=e.createSelect("format");for(const e in r.formats)n.option(e,r.formats[e]);n.title="Video Format",r.append(n);let g=e.createEl("div");g.className="bitrate",g.style.display="flex",r.append(g),s=e.createInput();let _=document.createElement("span");function m(){r.encoderSettings.mimeType=n.value}function x(){r.encoderSettings.videoBitsPerSecond=1e6*s.value}_.textContent="mbps",s.title=_.title="Video Bitrate",g.append(s),g.append(_),l=e.createEl("button"),l.className="audio-toggle active",l.textContent="🔊",l.title="Toggle Audio Recording",r.append(l),r.captureAudio=!0,l.addEventListener("click",(()=>{r.captureAudio=!r.captureAudio,l.textContent=r.captureAudio?"🔊":"🔇",l.classList.toggle("active",r.captureAudio)})),r.encoderSettings={},n.addEventListener("change",m),s.addEventListener("change",x),Object.defineProperty(r,"bitrate",{get:()=>s.value,set:e=>{s.value=e,x()}}),Object.defineProperty(r,"format",{get:()=>n.selected,set:e=>{e=e.toUpperCase(),r.formats[e]&&(n.selected=e,m())}}),r.format="H.264";let v=e.canvas.height;r.bitrate=v>=4320?96:v>=2160?64:v>=1440?48:v>=1080?32:v>=720?26:16,a.addEventListener("click",(()=>{e.recording?r.paused?h():e.pauseRecording():c()})),i.addEventListener("click",(()=>{r.paused?e.saveRecording():e.deleteRecording()})),p(),e.registerMethod("post",f)}function c(){if(!e.recording){if(e.userStartAudio(),!r.stream){r.frameRate??=e.getTargetFrameRate();let t=e.canvas.captureStream(r.frameRate);if(r.videoTrack=t.getVideoTracks()[0],r.captureAudio&&e.getAudioContext){let t=e.getAudioContext(),a=t.createMediaStreamDestination();t.destination.input?t.destination.input.connect(a):Q5.soundOut.connect(a),r.audioTrack=a.stream.getAudioTracks()[0],r.stream=new MediaStream([r.videoTrack,r.audioTrack])}else r.stream=t}r.mediaRecorder=new MediaRecorder(r.stream,r.encoderSettings),r.chunks=[],r.mediaRecorder.addEventListener("dataavailable",(e=>{e.data.size>0&&r.chunks.push(e.data)})),r.mediaRecorder.start(),t.recording=!0,r.paused=!1,r.classList.add("recording"),r.resetTimer(),p(!0)}}function h(){e.recording&&r.paused&&(r.mediaRecorder.resume(),r.paused=!1,p(!0))}function u(){e.recording&&(r.resetTimer(),r.mediaRecorder.stop(),t.recording=!1,r.paused=!1,r.classList.remove("recording"))}function p(e){a.textContent=e?"⏸":"⏺",a.title=(e?"Pause":"Start")+" Recording",i.textContent=e?"🗑️":"💾",i.title=(e?"Delete":"Save")+" Recording",i.disabled=!e}function f(){if(e.recording&&!r.paused){r.time.frames++;let t=e.getTargetFrameRate();r.time.frames>=t&&(r.time.seconds+=Math.floor(r.time.frames/t),r.time.frames%=t,r.time.seconds>=60&&(r.time.minutes+=Math.floor(r.time.seconds/60),r.time.seconds%=60,r.time.minutes>=60&&(r.time.hours+=Math.floor(r.time.minutes/60),r.time.minutes%=60)))}o.textContent=function(){let{hours:e,minutes:t,seconds:a,frames:i}=r.time;return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}:${String(a).padStart(2,"0")}:${String(i).padStart(2,"0")}`}()}e.recording=!1,e.createRecorder=e=>(r||d(e),r),e.record=t=>{r||(d(t),r.hide()),e.recording?r.paused&&h():c()},e.pauseRecording=()=>{e.recording&&!r.paused&&(r.mediaRecorder.pause(),r.paused=!0,p(),a.title="Resume Recording",i.disabled=!1)},e.deleteRecording=()=>{u(),p(),t.recording=!1},e.saveRecording=async a=>{if(!e.recording)return;await new Promise((e=>{r.mediaRecorder.onstop=e,u()}));let i=r.encoderSettings.mimeType,o=i.slice(6,i.indexOf(";")),n=URL.createObjectURL(new Blob(r.chunks,{type:i})),s=document.createElement("iframe"),l=document.createElement("a");s.style.display="none",s.name="download_"+Date.now(),document.body.append(s),l.target=s.name,l.href=n,a??=document.title+" "+(new Date).toLocaleString(void 0,{hour12:!1}).replace(","," at").replaceAll("/","-").replaceAll(":","_"),l.download=`${a}.${o}`,await new Promise((e=>{s.onload=()=>{document.body.removeChild(s),e()},l.click()})),setTimeout((()=>URL.revokeObjectURL(n)),1e3),p(),t.recording=!1}},Q5.modules.sound=(e,t)=>{e.Sound=Q5.Sound;let r=[];e.loadSound=(t,a)=>{let i=new Q5.Sound;return r.push(i),i.promise=(async()=>{let e;try{await i.load(t)}catch(t){e=t}if(delete i.promise,e)throw e;return a&&a(i),i})(),e._preloadPromises.push(i.promise),e._usePreload?i:i.promise},e.loadAudio=(t,r)=>{let a=new Audio(t);return a.crossOrigin="Anonymous",a.promise=new Promise(((e,t)=>{a.addEventListener("canplaythrough",(()=>{a.loaded||(a.loaded=!0,r&&r(a),e(a))})),a.addEventListener("suspend",e),a.addEventListener("error",t)})),e._preloadPromises.push(a.promise),e._usePreload?a:a.promise},e.getAudioContext=()=>Q5.aud,e.userStartAudio=()=>{if(window.AudioContext){if(Q5._offlineAudio){Q5._offlineAudio=!1,Q5.aud=new window.AudioContext,Q5.soundOut=Q5.aud.createGain(),Q5.soundOut.connect(Q5.aud.destination);for(let e of r)e.init()}return Q5.aud.resume()}}},window.OfflineAudioContext&&(Q5.aud=new window.OfflineAudioContext(2,1,44100),Q5._offlineAudio=!0,Q5.soundOut=Q5.aud.createGain(),Q5.soundOut.connect(Q5.aud.destination)),Q5.Sound=class{constructor(){this.sources=new Set,this.loaded=this.paused=!1}async load(e){this.url=e;let t=await fetch(e);this.buffer=await t.arrayBuffer(),this.buffer=await Q5.aud.decodeAudioData(this.buffer)}init(){this.gainNode=Q5.aud.createGain(),this.pannerNode=Q5.aud.createStereoPanner(),this.gainNode.connect(this.pannerNode),this.pannerNode.connect(Q5.soundOut),this.loaded=!0,this._volume&&(this.volume=this._volume),this._pan&&(this.pan=this._pan)}_newSource(e,t){let r=Q5.aud.createBufferSource();r.buffer=this.buffer,r.connect(this.gainNode),r.loop=this._loop,r._startedAt=Q5.aud.currentTime,r._offset=e,r._duration=t,r.start(0,r._offset,r._duration),this.sources.add(r),r.onended=()=>{this.paused||(this.ended=!0,this.sources.delete(r))}}play(e=0,t){if(this.loaded){if(this.paused){let e=[];for(let t of this.sources)e.push(t._offset,t._duration),this.sources.delete(t);for(let t=0;t<e.length;t+=2)this._newSource(e[t],e[t+1])}else this._newSource(e,t);this.paused=this.ended=!1}}pause(){if(this.isPlaying()){for(let e of this.sources){e.stop();let t=Q5.aud.currentTime-e._startedAt;e._offset+=t,e._duration&&(e._duration-=t)}this.paused=!0}}stop(){for(let e of this.sources)e.stop(),this.sources.delete(e);this.paused=!1,this.ended=!0}get volume(){return this._volume}set volume(e){this.loaded&&(this.gainNode.gain.value=e),this._volume=e}get pan(){return this._pan}set pan(e){this.loaded&&(this.pannerNode.pan.value=e),this._pan=e}get loop(){return this._loop}set loop(e){this.sources.forEach((t=>t.loop=e)),this._loop=e}get playing(){return!this.paused&&this.sources.size>0}setVolume(e){this.volume=e}setPan(e){this.pan=e}setLoop(e){this.loop=e}isLoaded(){return this.loaded}isPlaying(){return this.playing}isPaused(){return this.paused}isLooping(){return this._loop}},Q5.modules.util=(e,t)=>{e._loadFile=(t,r,a)=>{let i={};return i.promise=new Promise(((o,n)=>{fetch(t).then((e=>e.ok?"json"==a?e.json():e.text():(n("error loading file"),null))).then((t=>{"csv"==a&&(t=e.CSV.parse(t)),"string"==typeof t?i.text=t:Object.assign(i,t),delete i.promise,r&&r(t),o(t)}))})),i},e.loadText=(t,r)=>e._loadFile(t,r,"text"),e.loadJSON=(t,r)=>e._loadFile(t,r,"json"),e.loadCSV=(t,r)=>e._loadFile(t,r,"csv");const r=/(jpe?g|png|gif|webp|avif|svg)/i,a=/(ttf|otf|woff2?|eot|json)/i,i=/(serif|sans-serif|monospace|cursive|fantasy)/i,o=/(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/i;async function n(t,a,i){if(a=a||"untitled",i=i||"png",r.test(i))t="webgpu"==e.canvas?.renderer&&"c2d"==t.canvas.renderer?await e._g._saveCanvas(t,i):await e._saveCanvas(t,i);else{let e="text/plain";"json"==i&&("string"!=typeof t&&(t=JSON.stringify(t)),e="text/json"),t=new Blob([t],{type:e}),t=URL.createObjectURL(t)}let o=document.createElement("a");o.href=t,o.download=a+"."+i,o.click(),setTimeout((()=>URL.revokeObjectURL(o.href)),1e3)}e.load=function(...t){Array.isArray(t[0])&&(t=t[0]);let n=[];for(let s of t){let t,l=s.split(".").pop().toLowerCase();t="json"!=l||s.includes("-msdf.")?"csv"==l?e.loadCSV(s):r.test(l)?e.loadImage(s):a.test(l)||i.test(s)?e.loadFont(s):o.test(l)?e.loadSound(s):e.loadText(s):e.loadJSON(s),n.push(t.promise)}return 1==t.length?n[0]:Promise.all(n)},e.save=(t,r,a)=>{if((!t||"string"==typeof t&&(!r||!a&&r.length<5))&&(a=r,r=t,t=e.canvas),a)n(t,r,a);else if(r){let e=r.lastIndexOf(".");n(t,r.slice(0,e),r.slice(e+1))}else n(t)},e.CSV={},e.CSV.parse=(e,t=",",r="\n")=>{if(!e.length)return[];let a=[],i=e.split(r),o=i[0].split(t).map((e=>e.replaceAll('"',"")));for(let e=1;e<i.length;e++){let r={},n=i[e].split(t);o.forEach(((e,t)=>r[e]=JSON.parse(n[t]))),a.push(r)}return a},e.canvas&&!Q5._createServerCanvas&&(e.canvas.save=e.saveCanvas=e.save),"object"==typeof localStorage&&(e.storeItem=localStorage.setItem,e.getItem=localStorage.getItem,e.removeItem=localStorage.removeItem,e.clearStorage=localStorage.clear),e.year=()=>(new Date).getFullYear(),e.day=()=>(new Date).getDay(),e.hour=()=>(new Date).getHours(),e.minute=()=>(new Date).getMinutes(),e.second=()=>(new Date).getSeconds(),e.nf=(e,t,r)=>{let a=e<0,i=(e=Math.abs(e)).toFixed(r).split(".");i[0]=i[0].padStart(t,"0");let o=i.join(".");return a&&(o="-"+o),o},e.shuffle=(t,r)=>{r||(t=[...t]);for(let r=t.length-1;r>0;r--){let a=Math.floor(e.random()*(r+1));[t[r],t[a]]=[t[a],t[r]]}return t}},Q5.modules.vector=e=>{e.Vector=Q5.Vector,e.createVector=(t,r,a)=>new e.Vector(t,r,a,e)},Q5.Vector=class{constructor(e,t,r,a){this.x=e||0,this.y=t||0,this.z=r||0,this._$=a||window,this._cn=null,this._cnsq=null}set(e,t,r){return this.x=e?.x||e||0,this.y=e?.y||t||0,this.z=e?.z||r||0,this}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,r){return void 0!==e?.x?e:void 0!==t?{x:e,y:t,z:r||0}:{x:e,y:e,z:e}}_calcNorm(){this._cnsq=this.x*this.x+this.y*this.y+this.z*this.z,this._cn=Math.sqrt(this._cnsq)}add(){let e=this._arg2v(...arguments);return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}rem(){let e=this._arg2v(...arguments);return this.x%=e.x,this.y%=e.y,this.z%=e.z,this}sub(){let e=this._arg2v(...arguments);return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}mult(){let e=this._arg2v(...arguments);return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}div(){let e=this._arg2v(...arguments);return e.x?this.x/=e.x:this.x=0,e.y?this.y/=e.y:this.y=0,e.z?this.z/=e.z:this.z=0,this}mag(){return this._calcNorm(),this._cn}magSq(){return this._calcNorm(),this._cnsq}dot(){let e=this._arg2v(...arguments);return this.x*e.x+this.y*e.y+this.z*e.z}dist(){let e=this._arg2v(...arguments),t=this.x-e.x,r=this.y-e.y,a=this.z-e.z;return Math.sqrt(t*t+r*r+a*a)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,a=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=a,this}normalize(){this._calcNorm();let e=this._cn;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._cn=1,this._cnsq=1,this}limit(e){this._calcNorm();let t=this._cn;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._cn=e,this._cnsq=e*e}return this}setMag(e){this._calcNorm();let t=e/this._cn;return this.x*=t,this.y*=t,this.z*=t,this._cn=e,this._cnsq=e*e,this}heading(){return this._$.atan2(this.y,this.x)}setHeading(e){let t=this.mag();return this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),a=this.x*t-this.y*r,i=this.x*r+this.y*t;return this.x=a,this.y=i,this}angleBetween(){let e=this._arg2v(...arguments),t=Q5.Vector.cross(this,e);return this._$.atan2(t.mag(),this.dot(e))*Math.sign(t.z||1)}lerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));return this.x+=(r.x-this.x)*t,this.y+=(r.y-this.y)*t,this.z+=(r.z-this.z)*t,this}slerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));if(1==t)return this.set(r);let a=this.mag(),i=r.mag();if(0==a||0==i)return this.mult(1-t).add(r.mult(t));let o=Q5.Vector.cross(this,r),n=o.mag(),s=Math.atan2(n,this.dot(r));if(n>0)o.div(n);else{if(s<this._$.HALF_PI)return this.mult(1-t).add(r.mult(t));0==this.z&&0==r.z?o.set(0,0,1):0!=this.x?o.set(this.y,-this.x,0).normalize():o.set(1,0,0)}let l=o.cross(this),d=1-t+t*i/a,c=d*Math.cos(t*s),h=d*Math.sin(t*s);return this.x=this.x*c+l.x*h,this.y=this.y*c+l.y*h,this.z=this.z*c+l.z*h,this}reflect(e){return e.normalize(),this.sub(e.mult(2*this.dot(e)))}array(){return[this.x,this.y,this.z]}equals(e,t){return t??=Number.EPSILON||0,Math.abs(e.x-this.x)<t&&Math.abs(e.y-this.y)<t&&Math.abs(e.z-this.z)<t}fromAngle(e,t){return void 0===t&&(t=1),this._cn=t,this._cnsq=t*t,this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this.z=0,this}fromAngles(e,t,r){void 0===r&&(r=1),this._cn=r,this._cnsq=r*r;const a=this._$.cos(t),i=this._$.sin(t),o=this._$.cos(e),n=this._$.sin(e);return this.x=r*n*i,this.y=-r*o,this.z=r*n*a,this}random2D(){return this._cn=this._cnsq=1,this.fromAngle(Math.random()*Math.PI*2)}random3D(){return this._cn=this._cnsq=1,this.fromAngles(Math.random()*Math.PI*2,Math.random()*Math.PI*2)}toString(){return`[${this.x}, ${this.y}, ${this.z}]`}},Q5.Vector.add=(e,t)=>e.copy().add(t),Q5.Vector.cross=(e,t)=>e.copy().cross(t),Q5.Vector.dist=(e,t)=>Math.hypot(e.x-t.x,e.y-t.y,e.z-t.z),Q5.Vector.div=(e,t)=>e.copy().div(t),Q5.Vector.dot=(e,t)=>e.copy().dot(t),Q5.Vector.equals=(e,t,r)=>e.equals(t,r),Q5.Vector.lerp=(e,t,r)=>e.copy().lerp(t,r),Q5.Vector.slerp=(e,t,r)=>e.copy().slerp(t,r),Q5.Vector.limit=(e,t)=>e.copy().limit(t),Q5.Vector.heading=e=>this._$.atan2(e.y,e.x),Q5.Vector.magSq=e=>e.x*e.x+e.y*e.y+e.z*e.z,Q5.Vector.mag=e=>Math.sqrt(Q5.Vector.magSq(e)),Q5.Vector.mult=(e,t)=>e.copy().mult(t),Q5.Vector.normalize=e=>e.copy().normalize(),Q5.Vector.rem=(e,t)=>e.copy().rem(t),Q5.Vector.sub=(e,t)=>e.copy().sub(t),Q5.Vector.reflect=(e,t)=>e.copy().reflect(t),Q5.Vector.random2D=()=>(new Q5.Vector).random2D(),Q5.Vector.random3D=()=>(new Q5.Vector).random3D(),Q5.Vector.fromAngle=(e,t)=>(new Q5.Vector).fromAngle(e,t),Q5.Vector.fromAngles=(e,t,r)=>(new Q5.Vector).fromAngles(e,t,r),Q5.renderers.webgpu={},Q5.renderers.webgpu.canvas=(e,t)=>{let r=e.canvas;e.colorMode&&e.colorMode("rgb",1),e._baseShaderCode="\nstruct Q5 {\n\twidth: f32,\n\theight: f32,\n\thalfWidth: f32,\n\thalfHeight: f32,\n\tpixelDensity: f32,\n\tframeCount: f32,\n\ttime: f32,\n\tdeltaTime: f32,\n\tmouseX: f32,\n\tmouseY: f32,\n\tmouseIsPressed: f32,\n\tkeyCode: f32,\n\tkeyIsPressed: f32\n}",e._g=e.createGraphics(1,1,"c2d"),e._g.colorMode&&e._g.colorMode(e.RGB,1);let a,i,o,n,s,l,d,c,h=1,u=8;e._pipelineConfigs=[],e._pipelines=[],e._buffers=[],e._prevFramePL=0,e._framePL=0;let p=e._drawStack=[],f=e._colorStack=new Float32Array(1e6);f.set([0,0,0,1,1,1,1,1]);let g=Q5.device.createBindGroupLayout({label:"mainLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]});e._bindGroupLayouts=[g];let _=Q5.device.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),m=()=>{let t=[e.canvas.width,e.canvas.height],r="bgra8unorm";o=Q5.device.createTexture({size:t,sampleCount:4,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}).createView();let a=GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT;e._frameA=n=Q5.device.createTexture({size:t,format:r,usage:a}),e._frameB=s=Q5.device.createTexture({size:t,format:r,usage:a}),e.canvas.texture=n,e._frameShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex: u32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f\n}\n\nconst ndc = array(vec2f(-1,-1), vec2f(1,-1), vec2f(-1,1), vec2f(1,1));\nconst quad = array(vec2f(0,1), vec2f(1,1), vec2f(0,0), vec2f(1,0));\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var samp: sampler;\n@group(0) @binding(2) var tex: texture_2d<f32>;\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar f: FragParams;\n\tf.position = vec4f(ndc[v.vertexIndex], 0.0, 1.0);\n\tf.texCoord = quad[v.vertexIndex];\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams ) -> @location(0) vec4f {\n\treturn textureSample(tex, samp, f.texCoord);\n}";let i=Q5.device.createShaderModule({label:"frameShader",code:e._frameShaderCode});d=Q5.device.createSampler({magFilter:"linear",minFilter:"linear"}),l=Q5.device.createBindGroupLayout({label:"frameLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]});let c=Q5.device.createPipelineLayout({bindGroupLayouts:[l]});e._pipelineConfigs[0]={layout:c,vertex:{module:i,entryPoint:"vertexMain"},fragment:{module:i,entryPoint:"fragMain",targets:[{format:r}]},primitive:{topology:"triangle-strip"},multisample:{count:4}},e._pipelines[0]=Q5.device.createRenderPipeline(e._pipelineConfigs[0])};e._createCanvas=(a,i,o)=>(t.ctx=t.drawingContext=r.getContext("webgpu"),o.format??=navigator.gpu.getPreferredCanvasFormat(),o.device??=Q5.device,o.alpha&&(o.alphaMode="premultiplied"),e.ctx.configure(o),m(),r),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r),m()};let x=!0,v=1;if(e.colorMode){let t=e.colorMode;e.colorMode=function(){t(...arguments),x="rgb"==e._colorMode,v=e._colorFormat}}let y=(t,r,a,i)=>{if("string"==typeof t||!1===x?t=e.color(t,r,a,i):void 0===a&&(i=r??v,r=a=t),i??=v,t._q5Color){let e=t;null!=e.r?({r:t,g:r,b:a,a:i}=e):(i=e.a,e=null!=e.c?Q5.OKLCHtoRGB(e.l,e.c,e.h):null!=e.l?Q5.HSLtoRGB(e.h,e.s,e.l):Q5.HSLtoRGB(...Q5.HSBtoHSL(e.h,e.s,e.b)),[t,r,a]=e)}255===v&&(t/=255,r/=255,a/=255,i/=255);let o=f,n=u;o[n++]=t,o[n++]=r,o[n++]=a,o[n++]=i,u=n,h++};e._stroke=0,e._fill=e._tint=e._globalAlpha=1,e._doFill=e._doStroke=!0,e.fill=(t,r,a,i)=>{y(t,r,a,i),e._doFill=e._fillSet=!0,e._fill=h},e.stroke=(t,r,a,i)=>{y(t,r,a,i),e._doStroke=e._strokeSet=!0,e._stroke=h},e.tint=(t,r,a,i)=>{y(t,r,a,i),e._tint=h},e.opacity=t=>e._globalAlpha=t,e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e.noTint=()=>e._tint=1,e._strokeWeight=1,e._hsw=.5,e._scaledSW=1,e.strokeWeight=t=>{t=Math.abs(t),e._strokeWeight=t,e._scaledSW=t*e._scale,e._hsw=t/2};const b=e._graphics?1e3:1e7,w=new Float32Array(16*b);let S,M=[],C=[];e._matrixDirty=!1,M.push([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),w.set(M[0]),e.resetMatrix=()=>{S=M[0].slice(),e._matrixIndex=0},e.resetMatrix(),e.translate=(t,r,a=0)=>{if(!t&&!r&&!a)return;let i=S;i[12]+=t*i[0],i[13]-=r*i[5],i[14]+=a*i[10],e._matrixDirty=!0},e.rotate=e.rotateZ=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.cos(t),a=Math.sin(t),i=S,o=i[0],n=i[1],s=i[4],l=i[5];1!=o||n||s||1!=l?(i[0]=o*r+n*a,i[1]=n*r-o*a,i[4]=s*r+l*a,i[5]=l*r-s*a):(i[0]=r,i[1]=-a,i[4]=a,i[5]=r),e._matrixDirty=!0},e._scale=1,e.scale=(t=1,r,a=1)=>{r??=t,e._scale=Math.max(Math.abs(t),Math.abs(r)),e._scaledSW=e._strokeWeight*e._scale;let i=S;i[0]*=t,i[1]*=t,i[2]*=t,i[3]*=t,i[4]*=r,i[5]*=r,i[6]*=r,i[7]*=r,i[8]*=a,i[9]*=a,i[10]*=a,i[11]*=a,e._matrixDirty=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=S,i=a[0],o=a[1],n=a[4],s=a[5];a[0]=i+n*r,a[1]=o+s*r,e._matrixDirty=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=S,i=a[0],o=a[1],n=a[4],s=a[5];a[4]=n+i*r,a[5]=s+o*r,e._matrixDirty=!0},e.applyMatrix=(...t)=>{let r;if(r=1==t.length?t[0]:t,9==r.length)r=[r[0],r[1],0,r[2],r[3],r[4],0,r[5],0,0,1,0,r[6],r[7],0,r[8]];else if(16!=r.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");S=r.slice(),e._matrixDirty=!0},e._saveMatrix=()=>{w.set(S,16*M.length),e._matrixIndex=M.length,M.push(S.slice()),e._matrixDirty=!1},e.pushMatrix=()=>{e._matrixDirty&&e._saveMatrix(),C.push(e._matrixIndex)},e.popMatrix=()=>{if(!C.length)return console.warn("Matrix index stack is empty!");let t=C.pop();S=M[t].slice(),e._matrixIndex=t,e._matrixDirty=!1};let Q=e.pushStyles;e.pushStyles=()=>{Q(),e.strokeWeight(e._strokeWeight)},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()},e._calcBox=(e,t,r,a,i)=>{let o,n,s,l;if(i&&"corner"!=i)if("center"==i){let i=r/2,d=a/2;o=e-i,n=e+i,s=-(t-d),l=-(t+d)}else o=e,n=r,s=-t,l=-a;else o=e,n=e+r,s=-t,l=-(t+a);return[o,n,s,l]};let P=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],E=["add","subtract","reverse-subtract","min","max"];const R={"source-over":[2,3,0,2,3,0],"destination-over":[6,1,0,6,1,0],"source-in":[5,0,0,5,0,0],"destination-in":[0,2,0,0,2,0],"source-out":[6,0,0,6,0,0],"destination-out":[0,3,0,0,3,0],"source-atop":[5,3,0,5,3,0],"destination-atop":[6,2,0,6,2,0],lighter:[1,1,0,1,1,0],darken:[1,1,3,3,5,0],lighten:[1,1,4,3,5,0],replace:[1,0,0,1,0,0]};e._blendModeNames=Object.keys(R),e.blendConfigs={};for(const[t,r]of Object.entries(R))e.blendConfigs[t]={color:{srcFactor:P[r[0]],dstFactor:P[r[1]],operation:E[r[2]]},alpha:{srcFactor:P[r[3]],dstFactor:P[r[4]],operation:E[r[5]]}};let I;e._blendMode="source-over",e.blendMode=t=>{if(t==e._blendMode)return;e._blendMode=t;let r=e._blendModeNames.indexOf(t);-1!=r?p.push(0,r):console.error(`Blend mode "${t}" not supported in q5.js WebGPU.`)},e.clear=()=>{I=!0},e.background=(t,a,i,o)=>{if(e.push(),e.resetMatrix(),t.canvas){let a=t;e._imageMode="corner",e.image(a,-r.hw,-r.hh,r.w,r.h)}else e._rectMode="corner",e.fill(t,a,i,o),e._doStroke=!1,e.rect(-r.hw,-r.hh,r.w,r.h);e.pop()},e._beginRender=()=>{const t=n;n=s,s=t,a=Q5.device.createCommandEncoder(),e._pass=i=a.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:o,resolveTarget:n.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:_}},{binding:1,resource:d},{binding:2,resource:s.createView()}]}),I||(i.setPipeline(e._pipelines[e._prevFramePL]),i.setBindGroup(0,c),i.draw(4)),I=!1},e._render=()=>{let t=Q5.device.createBuffer({size:16*M.length*4,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(w.slice(0,16*M.length)),t.unmap(),e._buffers.push(t);let r=Q5.device.createBuffer({size:4*u,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(r.getMappedRange()).set(f.slice(0,u)),r.unmap(),e._buffers.push(r),e._uniforms=[e.width,e.height,e.halfWidth,e.halfHeight,e._pixelDensity,e.frameCount,performance.now(),e.deltaTime,e.mouseX,e.mouseY,e.mouseIsPressed?1:0,e.keyCode,e.keyIsPressed?1:0],Q5.device.queue.writeBuffer(_,0,new Float32Array(e._uniforms));let a=Q5.device.createBindGroup({layout:g,entries:[{binding:0,resource:{buffer:_}},{binding:1,resource:{buffer:t}},{binding:2,resource:{buffer:r}}]});i.setBindGroup(0,a);for(let t of e._hooks.preRender)t();let o=0,n=0,s=0,l=-1;for(let t=0;t<p.length;t+=2){let r=p[t+1];if(p[t]!=l){if(0==p[t]){let t=e._blendModeNames[r];for(let r=1;r<e._pipelines.length;r++)e._pipelineConfigs[r].fragment.targets[0].blend=e.blendConfigs[t],e._pipelines[r]=Q5.device.createRenderPipeline(e._pipelineConfigs[r]);continue}l=p[t],i.setPipeline(e._pipelines[l])}if(4==l||l>=4e3){let a=p[t+2];i.setBindGroup(1,e._fonts[a].bindGroup),i.setBindGroup(2,e._textBindGroup),i.draw(4,r,0,s),s+=r,t++}else 2==l||3==l||l>=2e3?(i.setBindGroup(1,e._textureBindGroups[r]),i.draw(4,1,n),n+=4):(i.draw(r,1,o),o+=r)}},e._finishRender=async()=>{i.end(),i=a.beginRenderPass({colorAttachments:[{view:o,resolveTarget:e.ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:_}},{binding:1,resource:d},{binding:2,resource:n.createView()}]}),i.setPipeline(e._pipelines[e._framePL]),i.setBindGroup(0,c),i.draw(4),i.end(),Q5.device.queue.submit([a.finish()]),e._pass=i=a=null,Q5.device.queue.onSubmittedWorkDone().then((()=>{for(let t of e._buffers)t.destroy();e._buffers=[]})),p.splice(0,p.length),h=1,u=8,M=[M[0]],C=[];for(let t of e._hooks.postRender)t()}},Q5.initWebGPU=async()=>{if(!navigator.gpu)return console.warn("q5 WebGPU not supported on this browser! Use Google Chrome or Edge."),!1;if(!Q5.requestedGPU){let e=await navigator.gpu.requestAdapter();if(!e)return console.warn("q5 WebGPU could not start! No appropriate GPUAdapter found, vulkan may need to be enabled."),!1;Q5.device=await e.requestDevice(),Q5.device.lost.then((e=>{console.error("WebGPU crashed!"),console.error(e)}))}return!0},Q5.WebGPU=async function(e,t){return e&&"global"!=e||(Q5._hasGlobal=!0),await Q5.initWebGPU()?new Q5(e,t,"webgpu"):new Q5(e,t,"webgpu-fallback")},Q5.webgpu=Q5.WebGPU,Q5.renderers.webgpu.shapes=e=>{e._shapesPL=1,e._shapesShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@location(0) pos: vec2f,\n\t@location(1) colorIndex: f32,\n\t@location(2) matrixIndex: f32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) color: vec4f\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\n\tvar f: FragParams;\n\tf.position = vert;\n\tf.color = colors[i32(v.colorIndex)];\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\treturn f.color;\n}\n";let t=Q5.device.createShaderModule({label:"shapesShader",code:e._shapesShaderCode}),r=(e.canvas,e._drawStack),a=new Float32Array(e._graphics?1e3:1e7),i=0;const o=2*Math.PI,n=Math.PI/2;let s=Q5.device.createPipelineLayout({label:"shapesPipelineLayout",bindGroupLayouts:e._bindGroupLayouts});e._pipelineConfigs[1]={label:"shapesPipeline",layout:s,vertex:{module:t,entryPoint:"vertexMain",buffers:[{arrayStride:16,attributes:[{format:"float32x2",offset:0,shaderLocation:0},{format:"float32",offset:8,shaderLocation:1},{format:"float32",offset:12,shaderLocation:2}]}]},fragment:{module:t,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[1]=Q5.device.createRenderPipeline(e._pipelineConfigs[1]);const l=(e,t,r,o)=>{let n=a,s=i;n[s++]=e,n[s++]=t,n[s++]=r,n[s++]=o,i=s},d=(t,o,n,s,l,d,c,h,u,p)=>{let f=a,g=i;f[g++]=t,f[g++]=o,f[g++]=u,f[g++]=p,f[g++]=n,f[g++]=s,f[g++]=u,f[g++]=p,f[g++]=c,f[g++]=h,f[g++]=u,f[g++]=p,f[g++]=l,f[g++]=d,f[g++]=u,f[g++]=p,i=g,r.push(e._shapesPL,4)},c=(t,o,n,s,l,d,c,h,u)=>{let p=(d-l)/c,f=l,g=a,_=i;for(let e=0;e<=c;e++){g[_++]=t,g[_++]=o,g[_++]=h,g[_++]=u;let e=t+n*Math.cos(f),r=o-s*Math.sin(f);g[_++]=e,g[_++]=r,g[_++]=h,g[_++]=u,f+=p}i=_,r.push(e._shapesPL,2*(c+1))},h=(t,o,n,s,l,d,c,h,u,p,f)=>{let g=(h-c)/u,_=c,m=a,x=i;for(let e=0;e<=u;e++){let e=t+n*Math.cos(_),r=o-s*Math.sin(_),a=t+l*Math.cos(_),i=o-d*Math.sin(_);m[x++]=e,m[x++]=r,m[x++]=p,m[x++]=f,m[x++]=a,m[x++]=i,m[x++]=p,m[x++]=f,_+=g}i=x,r.push(e._shapesPL,2*(u+1))};e.rectMode=t=>e._rectMode=t,e.rect=(t,r,a,i,o=0)=>{i??=a;let s,l,[p,f,g,_]=e._calcBox(t,r,a,i,e._rectMode);if(e._matrixDirty&&e._saveMatrix(),l=e._matrixIndex,!o){if(e._doFill&&(s=e._fill,d(p,g,f,g,f,_,p,_,s,l)),e._doStroke){s=e._stroke;let t=e._strokeWeight/2,r=p-t,a=f+t,i=g+t,o=_-t,n=p+t,c=f-t,h=g-t,u=_+t;d(r,h,a,h,a,i,r,i,s,l),d(r,o,a,o,a,u,r,u,s,l),i=g-t,o=_+t,d(r,i,n,i,n,o,r,o,s,l),d(c,i,a,i,a,o,c,o,s,l)}return}p+=o,f-=o,g-=o,_+=o,o=Math.min(o,Math.min(a,i)/2);let m=u(o*e._scale),x=g+o,v=_-o,y=p-o,b=f+o;if(e._doFill&&(s=e._fill,c(f,_,o,o,0,n,m,s,l),c(p,_,o,o,Math.PI,n,m,s,l),c(p,g,o,o,-Math.PI,-n,m,s,l),c(f,g,o,o,-n,0,m,s,l),d(p,x,f,x,f,v,p,v,s,l),d(p,g,y,g,y,_,p,_,s,l),d(b,g,f,g,f,_,b,_,s,l)),e._doStroke){s=e._stroke;let t=e._hsw,r=o+t,a=o+t,i=o-t,c=o-t;h(f,_,r,a,i,c,0,n,m,s,l),h(p,_,r,a,i,c,Math.PI,n,m,s,l),h(p,g,r,a,i,c,-Math.PI,-n,m,s,l),h(f,g,r,a,i,c,-n,0,m,s,l);let u=y-t,w=y+t,S=b-t,M=b+t,C=x-t,Q=x+t,P=v-t,E=v+t;d(u,g,w,g,w,_,u,_,s,l),d(S,g,M,g,M,_,S,_,s,l),d(p,C,f,C,f,Q,p,Q,s,l),d(p,P,f,P,f,E,p,E,s,l)}},e.square=(t,r,a)=>e.rect(t,r,a,a),e.plane=(t,r,a,i)=>{i??=a;let[o,n,s,l]=e._calcBox(t,r,a,i,"center");e._matrixDirty&&e._saveMatrix(),d(o,s,n,s,n,l,o,l,e._fill,e._matrixIndex)};const u=e=>e<4?6:e<6?8:e<10?10:e<16?12:e<20?14:e<22?16:e<24?18:e<28?20:e<34?22:e<42?24:e<48?26:e<56?28:e<64?30:e<72?32:e<84?34:e<96?36:e<98?38:e<113?40:e<149?44:e<199?48:e<261?52:e<353?56:e<461?60:e<585?64:e<1200?70:e<1800?80:e<2400?90:100;e._ellipseMode=Q5.CENTER,e.ellipseMode=t=>e._ellipseMode=t,e.ellipse=(t,r,a,i)=>{let n=u(Math.max(Math.abs(a),Math.abs(i))*e._scale),s=a/2,l=a==i?s:i/2;e._matrixDirty&&e._saveMatrix();let d=e._matrixIndex;if(e._doFill&&c(t,-r,s,l,0,o,n,e._fill,d),e._doStroke){let a=e._strokeWeight/2;h(t,-r,s+a,l+a,s-a,l-a,0,o,n,e._stroke,d)}},e.circle=(t,r,a)=>e.ellipse(t,r,a,a),e.arc=(t,r,a,i,n,s)=>{if(n===s)return e.ellipse(t,r,a,i);if(e._angleMode&&(n=e.radians(n),s=e.radians(s)),(n%=o)<0&&(n+=o),(s%=o)<0&&(s+=o),n>s&&(s+=o),n==s)return e.ellipse(t,r,a,i);let l,d;e._ellipseMode==e.CENTER?(l=a/2,d=i/2):e._ellipseMode==e.RADIUS?(l=a,d=i):e._ellipseMode==e.CORNER?(t+=a/2,r+=i/2,l=a/2,d=i/2):e._ellipseMode==e.CORNERS&&(l=(a-(t=(t+a)/2))/2,d=(i-(r=(r+i)/2))/2),e._matrixDirty&&e._saveMatrix();let p=e._matrixIndex,f=u(Math.max(Math.abs(a),Math.abs(i))*e._scale);if(e._doFill&&c(t,-r,l,d,n,s,f,e._fill,p),e._doStroke){let a=e._hsw;h(t,-r,l+a,d+a,l-a,d-a,n,s,f,e._stroke,p),"round"==e._strokeCap&&(c(t+l*Math.cos(n),-r-d*Math.sin(n),a,a,0,o,f,e._stroke,p),c(t+l*Math.cos(s),-r-d*Math.sin(s),a,a,0,o,f,e._stroke,p))}},e.point=(t,r)=>{e._matrixDirty&&e._saveMatrix();let a=e._matrixIndex,i=e._stroke,n=e._strokeWeight;if(e._scaledSW<2){let[o,s,l,c]=e._calcBox(t,r,n,n,"corner");d(o,l,s,l,s,c,o,c,i,a)}else{let s=u(e._scaledSW);n/=2,c(t,-r,n,n,0,o,s,i,a)}},e._strokeCap=e._strokeJoin="round",e.strokeCap=t=>e._strokeCap=t,e.strokeJoin=t=>e._strokeJoin=t,e.lineMode=()=>{e._strokeCap="square",e._strokeJoin="none"},e.line=(t,r,a,i)=>{e._matrixDirty&&e._saveMatrix();let n=e._matrixIndex,s=e._stroke,l=(e._strokeWeight,e._hsw),h=a-t,p=i-r,f=Math.hypot(h,p),g=-p/f*l,_=h/f*l;if(d(t+g,-r-_,t-g,-r+_,a-g,-i+_,a+g,-i-_,s,n),e._scaledSW>2&&"square"!=e._strokeCap){let d=u(e._scaledSW);c(t,-r,l,l,0,o,d,s,n),c(a,-i,l,l,0,o,d,s,n)}};let p,f=20;e.curveDetail=e=>f=e;let g=[],_=[];e.beginShape=()=>{p=0,g=[],_=[]},e.vertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),g.push(t,-r,e._fill,e._matrixIndex),p++},e.curveVertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),_.push({x:t,y:-r})},e.bezierVertex=function(t,r,a,i,o,n){if(0===p)throw new Error("Shape needs a vertex()");e._matrixDirty&&e._saveMatrix();let s,l,d=4*(p-1),c=g[d],h=g[d+1],u=1/f,_=4==arguments.length;_&&(o=a,n=i);let m=1+u;for(let d=u;d<=m;d+=u){let u=d*d,f=1-d,m=f*f;if(_)s=m*c+2*f*d*t+u*o,l=m*h+2*f*d*-r+u*-n;else{let e=u*d,p=m*f;s=p*c+3*m*d*t+3*f*u*a+e*o,l=p*h+3*m*d*-r+3*f*u*-i+e*-n}g.push(s,l,e._fill,e._matrixIndex),p++}},e.quadraticVertex=(t,r,a,i)=>e.bezierVertex(t,r,a,i),e.endShape=t=>{if(_.length>0){let t=[..._];if(t.length<4)for(;t.length<4;)t.unshift(t[0]),t.push(t[t.length-1]);for(let r=0;r<t.length-3;r++){let a=t[r],i=t[r+1],o=t[r+2],n=t[r+3];for(let t=0;t<=1;t+=.1){let r=t*t,s=r*t,l=.5*(2*i.x+(-a.x+o.x)*t+(2*a.x-5*i.x+4*o.x-n.x)*r+(-a.x+3*i.x-3*o.x+n.x)*s),d=.5*(2*i.y+(-a.y+o.y)*t+(2*a.y-5*i.y+4*o.y-n.y)*r+(-a.y+3*i.y-3*o.y+n.y)*s);g.push(l,d,e._fill,e._matrixIndex),p++}}}if(p){if(1==p)return e.point(g[0],-g[1]);if(2==p)return e.line(g[0],-g[1],g[4],-g[5]);if(t){let e=0,t=4*(p-1),r=g[e],a=g[e+1],i=g[t],o=g[t+1];r===i&&a===o||(g.push(r,a,g[e+2],g[e+3]),p++)}if(e._doFill)if(5==p)l(g[0],g[1],g[2],g[3]),l(g[4],g[5],g[6],g[7]),l(g[12],g[13],g[14],g[15]),l(g[8],g[9],g[10],g[11]),r.push(e._shapesPL,4);else{for(let e=1;e<p-1;e++){let t=0,r=4*e,a=4*(e+1);l(g[t],g[t+1],g[t+2],g[t+3]),l(g[r],g[r+1],g[r+2],g[r+3]),l(g[a],g[a+1],g[a+2],g[a+3])}r.push(e._shapesPL,3*(p-2))}if(e._doStroke){let r=e._hsw,a=u(e._scaledSW),i=e._matrixIndex,n=e._strokeCap;e._strokeCap="square";for(let t=0;t<p-1;t++){let n=4*t,s=4*(t+1);e.line(g[n],-g[n+1],g[s],-g[s+1]),c(g[n],g[n+1],r,r,0,o,a,e._stroke,i)}let s=4*(p-1),l=0;t&&e.line(g[s],-g[s+1],g[l],-g[l+1]),c(g[s],g[s+1],r,r,0,o,a,e._stroke,i),e._strokeCap=n}p=0,g=[],_=[]}},e.curve=(t,r,a,i,o,n,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,i),e.curveVertex(o,n),e.curveVertex(s,l),e.endShape()},e.bezier=(t,r,a,i,o,n,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,i,o,n,s,l),e.endShape()},e.triangle=(t,r,a,i,o,n)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,i),e.vertex(o,n),e.endShape(!0)},e.quad=(t,r,a,i,o,n,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,i),e.vertex(o,n),e.vertex(s,l),e.endShape(!0)},e._hooks.preRender.push((()=>{e._pass.setPipeline(e._pipelines[1]);let t=Q5.device.createBuffer({size:4*i,usage:GPUBufferUsage.VERTEX,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(a.slice(0,i)),t.unmap(),e._pass.setVertexBuffer(0,t),e._buffers.push(t)})),e._hooks.postRender.push((()=>{i=0}))},Q5.renderers.webgpu.image=(e,t)=>{e._imagePL=2,e._videoPL=3,e._imageShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@location(0) pos: vec2f,\n\t@location(1) texCoord: vec2f,\n\t@location(2) tintIndex: f32,\n\t@location(3) matrixIndex: f32,\n\t@location(4) imageAlpha: f32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f,\n\t@location(1) tintColor: vec4f,\n\t@location(2) imageAlpha: f32\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\n@group(1) @binding(0) var samp: sampler;\n@group(1) @binding(1) var tex: texture_2d<f32>;\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0f, 1f);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\nfn applyTint(texColor: vec4f, tintColor: vec4f) -> vec4f {\n\t// apply the tint color to the sampled texture color at full strength\n\tlet tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a);\n\t// mix in the tint using the tint alpha as the blend strength\n\treturn mix(texColor, tinted, tintColor.a);\n}\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\n\tvar f: FragParams;\n\tf.position = vert;\n\tf.texCoord = v.texCoord;\n\tf.tintColor = colors[i32(v.tintIndex)];\n\tf.imageAlpha = v.imageAlpha;\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tvar texColor = textureSample(tex, samp, f.texCoord);\n\ttexColor.a *= f.imageAlpha;\n\treturn applyTint(texColor, f.tintColor);\n}\n";let r=Q5.device.createShaderModule({label:"imageShader",code:e._imageShaderCode});e._videoShaderCode=e._imageShaderCode.replace("texture_2d<f32>","texture_external").replace("textureSample","textureSampleBaseClampToEdge");let a=Q5.device.createShaderModule({label:"videoShader",code:e._videoShaderCode}),i=new Float32Array(e._graphics?1e3:1e7),o=0,n={arrayStride:28,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"},{shaderLocation:2,offset:16,format:"float32"},{shaderLocation:3,offset:20,format:"float32"},{shaderLocation:4,offset:24,format:"float32"}]},s=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]}),l=Q5.device.createBindGroupLayout({label:"videoTextureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,externalTexture:{}}]}),d=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,s]}),c=Q5.device.createPipelineLayout({label:"videoPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,l]});e._pipelineConfigs[2]={label:"imagePipeline",layout:d,vertex:{module:r,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},n]},fragment:{module:r,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[2]=Q5.device.createRenderPipeline(e._pipelineConfigs[2]),e._pipelineConfigs[3]={label:"videoPipeline",layout:c,vertex:{module:a,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},n]},fragment:{module:a,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[3]=Q5.device.createRenderPipeline(e._pipelineConfigs[3]),e._textureBindGroups=[],e._saveCanvas=async(t,r)=>{t._graphics&&t._drawStack?.length&&t._completeFrame();let a=t.texture,i=a.width,o=a.height,n=256*Math.ceil(4*i/256),s=Q5.device.createBuffer({size:n*o,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});e._buffers.push(s);let l=Q5.device.createCommandEncoder();l.copyTextureToBuffer({texture:a},{buffer:s,bytesPerRow:n,rowsPerImage:o},{width:i,height:o}),Q5.device.queue.submit([l.finish()]),await s.mapAsync(GPUMapMode.READ);let d=new Uint8Array(s.getMappedRange()),c=new Uint8Array(i*o*4);for(let e=0;e<o;e++){const t=e*n,r=e*i*4;for(let e=0;e<i;e++){const a=t+4*e,i=r+4*e;c[i+0]=d[a+2],c[i+1]=d[a+1],c[i+2]=d[a+0],c[i+3]=d[a+3]}}s.unmap();let h=e.canvas.colorSpace;c=new Uint8ClampedArray(c.buffer),c=new ImageData(c,i,o,{colorSpace:h});let u=new e._Canvas(i,o);u.getContext("2d",{colorSpace:h}).putImageData(c,0,0);let p=await u.convertToBlob({type:"image/"+r});return await new Promise((e=>{let t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(p)}))};let h=t=>{e._imageSampler=Q5.device.createSampler({magFilter:t,minFilter:t})};e.smooth=()=>h("linear"),e.noSmooth=()=>h("nearest"),e.smooth();let u=0,p=0;e._addTexture=(t,r)=>{let a=t.canvas||t,i=[a.width,a.height,1];r||(r=Q5.device.createTexture({size:i,format:"bgra8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),Q5.device.queue.copyExternalImageToTexture({source:a},{texture:r,colorSpace:e.canvas.colorSpace},i)),t.texture=r,t.textureIndex=u+p,e._textureBindGroups[t.textureIndex]=Q5.device.createBindGroup({label:t.src||"canvas",layout:s,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r.createView()}]}),u++};let f=Q5.Image;Q5.Image=function(t,r){let a=new f(...arguments);return t>1&&r>1&&(e._addTexture(a),img.modified=!0),a},e.loadImage=(t,r)=>{let a=e._g.loadImage(t,(t=>{e._addTexture(t),r&&r(a)}));return a},e.createImage=e._g.createImage;let g=e.createGraphics;e.createGraphics=(t,r,a)=>{let i=g(t,r,a);return i.canvas.webgpu?(e._addTexture(i,i._frameA),e._addTexture(i,i._frameB),i._beginRender()):i.modified=!0,i},e.imageMode=t=>e._imageMode=t;const _=(e,t,r,a,n,s,l)=>{let d=i,c=o;d[c++]=e,d[c++]=t,d[c++]=r,d[c++]=a,d[c++]=n,d[c++]=s,d[c++]=l,o=c};e.image=(t,r=0,a=0,i,o,n=0,s=0,d,c)=>{let h;if(null==t.textureIndex){if(h="VIDEO"==t.tagName,!h||!t.width||!t.currentTime)return;t.flipped&&e.scale(-1,1)}let u=t.canvas||t;e._matrixDirty&&e._saveMatrix();let p=u.width,f=u.height,g=t._pixelDensity||1;t._graphics&&t._drawStack?.length&&t._completeFrame(),t.modified&&(Q5.device.queue.copyExternalImageToTexture({source:u},{texture:t.texture,colorSpace:e.canvas.colorSpace},[p,f,1]),t.modified=!1),i??=t.defaultWidth||t.videoWidth,o??=t.defaultHeight||t.videoHeight,d??=p,c??=f,n*=g,s*=g;let[m,x,v,y]=e._calcBox(r,a,i,o,e._imageMode),b=n/p,w=s/f,S=(n+d)/p,M=(s+c)/f,C=e._matrixIndex,Q=e._tint,P=e._globalAlpha;if(_(m,v,b,w,Q,C,P),_(x,v,S,w,Q,C,P),_(m,y,b,M,Q,C,P),_(x,y,S,M,Q,C,P),h){let r=Q5.device.importExternalTexture({source:t});e._textureBindGroups.push(Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r}]})),e._drawStack.push(e._videoPL,e._textureBindGroups.length-1),t.flipped&&e.scale(-1,1)}else e._drawStack.push(e._imagePL,t.textureIndex)},e._completeFrame=()=>{e._render(),e._finishRender(),e.textureIndex+=e.frameCount%2==0?-1:1,e.resetMatrix(),e._beginRender(),e.frameCount++},e._hooks.preRender.push((()=>{if(!o)return;e._pass.setPipeline(e._pipelines[2]);let t=Q5.device.createBuffer({size:5*o,usage:GPUBufferUsage.VERTEX,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(i.slice(0,o)),t.unmap(),e._pass.setVertexBuffer(1,t),e._buffers.push(t),p&&(e._pass.setPipeline(e._pipelines[3]),e._pass.setVertexBuffer(1,t))})),e._hooks.postRender.push((()=>{o=0,e._textureBindGroups.splice(u,p),p=0}))},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.webgpu.text=(e,t)=>{e._textPL=4,e._textShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@builtin(instance_index) instanceIndex : u32\n}\nstruct FragParams {\n\t@builtin(position) position : vec4f,\n\t@location(0) texCoord : vec2f,\n\t@location(1) fillColor : vec4f,\n\t@location(2) strokeColor : vec4f,\n\t@location(3) strokeWeight : f32,\n\t@location(4) edge : f32\n}\nstruct Char {\n\ttexOffset: vec2f,\n\ttexExtent: vec2f,\n\tsize: vec2f,\n\toffset: vec2f,\n}\nstruct Text {\n\tpos: vec2f,\n\tscale: f32,\n\tmatrixIndex: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tstrokeWeight: f32,\n\tedge: f32\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\n@group(1) @binding(0) var fontTexture: texture_2d<f32>;\n@group(1) @binding(1) var fontSampler: sampler;\n@group(1) @binding(2) var<storage> fontChars: array<Char>;\n\n@group(2) @binding(0) var<storage> textChars: array<vec4f>;\n@group(2) @binding(1) var<storage> textMetadata: array<Text>;\n\nconst quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));\nconst uvs = array(vec2f(0, 1), vec2f(1, 1), vec2f(0, 0), vec2f(1, 0));\n\nfn calcPos(i: u32, char: vec4f, fontChar: Char, text: Text) -> vec2f {\n\treturn ((quad[i] * fontChar.size + char.xy + fontChar.offset) *\n\t\ttext.scale) + text.pos;\n}\n\nfn calcUV(i: u32, fontChar: Char) -> vec2f {\n\treturn uvs[i] * fontChar.texExtent + fontChar.texOffset;\n}\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\nfn calcDist(texCoord: vec2f, edgeWidth: f32) -> f32 {\n\tlet c = textureSample(fontTexture, fontSampler, texCoord);\n\tlet sigDist = max(min(c.r, c.g), min(max(c.r, c.g), c.b)) - edgeWidth;\n\n\tlet pxRange = 4.0;\n\tlet sz = vec2f(textureDimensions(fontTexture, 0));\n\tlet dx = sz.x * length(vec2f(dpdxFine(texCoord.x), dpdyFine(texCoord.x)));\n\tlet dy = sz.y * length(vec2f(dpdxFine(texCoord.y), dpdyFine(texCoord.y)));\n\tlet toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);\n\treturn sigDist * toPixels;\n}\n\n@vertex\nfn vertexMain(v : VertexParams) -> FragParams {\n\tlet char = textChars[v.instanceIndex];\n\tlet text = textMetadata[i32(char.w)];\n\tlet fontChar = fontChars[i32(char.z)];\n\tlet pos = calcPos(v.vertexIndex, char, fontChar, text);\n\n\tvar vert = transformVertex(pos, text.matrixIndex);\n\n\tvar f : FragParams;\n\tf.position = vert;\n\tf.texCoord = calcUV(v.vertexIndex, fontChar);\n\tf.fillColor = colors[i32(text.fillIndex)];\n\tf.strokeColor = colors[i32(text.strokeIndex)];\n\tf.strokeWeight = text.strokeWeight;\n\tf.edge = text.edge;\n\treturn f;\n}\n\n@fragment\nfn fragMain(f : FragParams) -> @location(0) vec4f {\n\tlet edge = f.edge;\n\tlet dist = calcDist(f.texCoord, edge);\n\n\tif (f.strokeWeight == 0.0) {\n\t\tlet fillAlpha = smoothstep(-edge, edge, dist);\n\t\tlet color = vec4f(f.fillColor.rgb, f.fillColor.a * fillAlpha);\n\t\tif (color.a < 0.01) {\n\t\t\tdiscard;\n\t\t}\n\t\treturn color;\n\t}\n\n\tlet halfStroke = f.strokeWeight / 2.0;\n\tlet fillAlpha = smoothstep(-edge, edge, dist - halfStroke);\n\tlet strokeAlpha = smoothstep(-edge, edge, dist + halfStroke);\n\tvar color = mix(f.strokeColor, f.fillColor, fillAlpha);\n\tcolor = vec4f(color.rgb, color.a * strokeAlpha);\n\tif (color.a < 0.01) {\n\t\tdiscard;\n\t}\n\treturn color;\n}\n";let r=Q5.device.createShaderModule({label:"textShader",code:e._textShaderCode}),a=Q5.device.createBindGroupLayout({label:"textBindGroupLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),i=Q5.device.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:16}),o=Q5.device.createBindGroupLayout({label:"fontBindGroupLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),n=Q5.device.createPipelineLayout({bindGroupLayouts:[...e._bindGroupLayouts,o,a]});e._pipelineConfigs[4]={label:"textPipeline",layout:n,vertex:{module:r,entryPoint:"vertexMain"},fragment:{module:r,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[4]=Q5.device.createRenderPipeline(e._pipelineConfigs[4]);class s{constructor(e,t,r,a){this.bindGroup=e,this.lineHeight=t,this.chars=r,this.kernings=a;let i=Object.values(r);this.charCount=i.length,this.defaultChar=i[0]}getChar(e){return this.chars[e]??this.defaultChar}getXAdvance(e,t=-1){let r=this.getChar(e);if(t>=0){let a=this.kernings.get(e);if(a)return r.xadvance+(a.get(t)??0)}return r.xadvance}}e._fonts=[];let l={};e.loadFont=(t,r)=>{let a=t.slice(t.lastIndexOf(".")+1);if(t==a)return e._loadDefaultFont(t,r);if("json"!=a)return e._g.loadFont(t,r);let n=t.slice(t.lastIndexOf("/")+1,t.lastIndexOf("-")),d={family:n};return d.promise=async function(t,r,a){let n=await fetch(t);if(404==n.status)return"";let d=await n.json(),c=t.lastIndexOf("/"),h=-1!=c?t.substring(0,c+1):"";n=await fetch(h+d.pages[0]);let u=await createImageBitmap(await n.blob()),p=[u.width,u.height,1],f=Q5.device.createTexture({label:`MSDF ${r}`,size:p,format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:u},{texture:f},p),"string"==typeof d.chars&&(d.chars=e.CSV.parse(d.chars," "),d.kernings=e.CSV.parse(d.kernings," "));let g=d.chars.length,_=Q5.device.createBuffer({size:32*g,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),m=new Float32Array(_.getMappedRange()),x=1/d.common.scaleW,v=1/d.common.scaleH,y={},b=0;for(let[e,t]of d.chars.entries())y[t.id]=t,y[t.id].charIndex=e,m[b]=t.x*x,m[b+1]=t.y*v,m[b+2]=t.width*x,m[b+3]=t.height*v,m[b+4]=t.width,m[b+5]=t.height,m[b+6]=t.xoffset,m[b+7]=-t.yoffset,b+=8;_.unmap();let w=Q5.device.createBindGroup({label:"fontBindGroup",layout:o,entries:[{binding:0,resource:f.createView()},{binding:1,resource:i},{binding:2,resource:{buffer:_}}]}),S=new Map;if(d.kernings)for(let e of d.kernings){let t=S.get(e.first);t||(t=new Map,S.set(e.first,t)),t.set(e.second,e.amount)}e._font=new s(w,d.common.lineHeight,y,S),e._font.index=e._fonts.length,e._fonts.push(e._font),l[r]=e._font,a&&a(r)}(t,n,(()=>{delete d.promise,r&&r(d)})),e._preloadPromises.push(d.promise),e._usePreload?d:d.promise},e._loadDefaultFont=(t,r)=>{l[t]=null;let a=`https://q5js.org/fonts/${t}-msdf.json`;return navigator.onLine||(a=`/node_modules/q5/builtinFonts/${t}-msdf.json`),e.loadFont(a,r)},e._textSize=18,e._textAlign="left",e._textBaseline="alphabetic";let d=!1,c=22.5,h=4.5,u=1.25;e.textFont=t=>{if(!t)return e._font;"string"!=typeof t&&(t=t.family);let r=l[t];if(r)e._font=r;else if(void 0===r)return e._loadDefaultFont(t)},e.textSize=t=>{if(null==t)return e._textSize;e._textSize=t,d||(c=t*u,h=c-t)};let p={thin:100,extralight:200,light:300,normal:400,regular:400,medium:500,semibold:600,bold:700,bolder:800,extrabold:800,black:900,heavy:900};e._textEdge=.5,e.textWeight=t=>{if(!t)return e._textWeight;if("string"==typeof t&&!(t=p[t.toLowerCase().replace(/[ _-]/g,"")]))throw new Error(`Invalid font weight: ${t}`);e._textEdge=.6875-375e-6*t},e.textLeading=t=>{e._font.lineHeight=c=t,h=c-e._textSize,u=c/e._textSize,d=!0},e.textAlign=(t,r)=>{e._textAlign=t,r&&(e._textBaseline=r)};let f=[],g=[],_=(e,t,r)=>{let a=0,i=0,o=0,n=0,s=0,l=[],d=t.charCodeAt(0);for(let c=0;c<t.length;++c){let h=d;switch(d=c<t.length-1?t.charCodeAt(c+1):-1,h){case 10:l.push(i),n++,a=Math.max(a,i),i=0,o-=e.lineHeight*u;break;case 13:break;case 32:i+=e.getXAdvance(h);break;case 9:i+=2*e.getXAdvance(h);break;default:r&&r(i,o,n,e.getChar(h)),i+=e.getXAdvance(h,d),s++}}return l.push(i),a=Math.max(a,i),{width:a,height:l.length*e.lineHeight*u,lineWidths:l,printedCharCount:s}};e.text=(t,r,a,i,o)=>{if(!e._font)return void(null!==e._font&&e.textFont("sans-serif"));let n=typeof t;if("string"!=n&&("object"==n?t=t.toString():t+=""),t.length>i){let e=[],r=0;for(;r<t.length&&e.length<o;){let a=r+i;if(a>=t.length){e.push(t.slice(r));break}let o=t.lastIndexOf(" ",a);(-1==o||o<r)&&(o=a),e.push(t.slice(r,o)),r=o+1}t=e.join("\n")}let s;for(let e=0;e<t.length;e++){switch(t[e]){case"\n":s=!0;case"\r":case"\t":case" ":0}}let l,d=[],h=e._textAlign,u=e._textBaseline,p=g.length,m=0;if("left"!=h||s){l=_(e._font,t);let r=0;"alphabetic"==u?a-=e._textSize:"center"==u?r=.5*l.height:"bottom"==u&&(r=l.height),_(e._font,t,((e,t,a,i)=>{let o=0;"center"==h?o=-.5*l.width- -.5*(l.width-l.lineWidths[a]):"right"==h&&(o=-l.lineWidths[a]),d[m]=e+o,d[m+1]=t+r,d[m+2]=i.charIndex,d[m+3]=p,m+=4}))}else l=_(e._font,t,((e,t,r,a)=>{d[m]=e,d[m+1]=t,d[m+2]=a.charIndex,d[m+3]=p,m+=4})),"alphabetic"==u?a-=e._textSize:"center"==u?a-=.5*e._textSize:"bottom"==u&&(a-=c);f.push(d);let x=[];e._matrixDirty&&e._saveMatrix(),x[0]=r,x[1]=-a,x[2]=e._textSize/42,x[3]=e._matrixIndex,x[4]=e._doFill&&e._fillSet?e._fill:0,x[5]=e._stroke,x[6]=e._doStroke&&e._strokeSet?e._strokeWeight:0,x[7]=e._textEdge,g.push(x),e._drawStack.push(e._textPL,l.printedCharCount,e._font.index)},e.textWidth=t=>e._font?_(e._font,t).width:0,e.createTextImage=(t,r,a)=>{if(e._g.textSize(e._textSize),e._doFill&&e._fillSet){let t=4*e._fill;e._g.fill(e._colorStack.slice(t,t+4))}if(e._doStroke&&e._strokeSet){let t=4*e._stroke;e._g.stroke(e._colorStack.slice(t,t+4))}let i=e._g.createTextImage(t,r,a);if(null==i.textureIndex){e._createTexture(i);let t=i.copy;i.copy=function(){let r=t();return e._createTexture(r),r}}return i},e.textImage=(t,r,a)=>{"string"==typeof t&&(t=e.createTextImage(t));let i=e._imageMode;e._imageMode="corner";let o=e._textAlign;"center"==o?r-=t.canvas.hw:"right"==o&&(r-=t.width);let n=e._textBaseline;"alphabetic"==n?a-=t._leading:"center"==n?a-=t._middle:"bottom"==n?a-=t._bottom:"top"==n&&(a-=t._top),e.image(t,r,a),e._imageMode=i},e._hooks.preRender.push((()=>{if(!f.length)return;let t=0;for(let e of f)t+=4*e.length;let r=Q5.device.createBuffer({size:t,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(r.getMappedRange()).set(f.flat()),r.unmap();let i=8*g.length*4,o=Q5.device.createBuffer({label:"textBuffer",size:i,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(o.getMappedRange()).set(g.flat()),o.unmap(),e._buffers.push(r,o),e._textBindGroup=Q5.device.createBindGroup({label:"textBindGroup",layout:a,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:o}}]})})),e._hooks.postRender.push((()=>{f=[],g=[]}))},Q5.renderers.webgpu.shaders=e=>{let t=["frame","shapes","image","video","text"],r={frame:10,shapes:1e3,image:2e3,video:3e3,text:4e3};e._createShader=(a,i="shapes")=>{a=a.trim();let o=e["_"+i+"ShaderCode"],n=o.indexOf("@vertex"),s=o.indexOf("@fragment");a=a.includes("@fragment")?a.includes("@vertex")?o.slice(0,n)+a:o.slice(0,s)+a:o.slice(0,n)+a+"\n\n"+o.slice(s);let l=Q5.device.createShaderModule({label:i+"Shader",code:a});l.type=i;let d=t.indexOf(i),c=Object.assign({},e._pipelineConfigs[d]);c.vertex.module=c.fragment.module=l;let h=r[i];return e._pipelines[h]=Q5.device.createRenderPipeline(c),e._pipelines[h].shader=l,l.pipelineIndex=h,r[i]++,l},e.createShader=e.createShapesShader=e._createShader,e.createFrameShader=t=>e._createShader(t,"frame"),e.createImageShader=t=>e._createShader(t,"image"),e.createVideoShader=t=>e._createShader(t,"video"),e.createTextShader=t=>e._createShader(t,"text"),e.shader=t=>{t.applyBeforeDraw?e._prevFramePL=t.pipelineIndex:e["_"+t.type+"PL"]=t.pipelineIndex},e.resetShader=(r="shapes")=>{"frame"==r&&(e._prevFramePL=0),e["_"+r+"PL"]=t.indexOf(r)},e.resetShaders=()=>{e._prevFramePL=e._framePL=0,e._shapesPL=1,e._imagePL=2,e._videoPL=3,e._textPL=4}};