q5 3.7.1 → 3.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/defs/q5-c2d-es.d.ts +1 -1
- package/defs/q5-es.d.ts +1 -1
- package/deno.json +1 -1
- package/package.json +1 -1
- package/q5.js +74 -46
- package/q5.min.js +1 -1
package/defs/q5-c2d-es.d.ts
CHANGED
package/defs/q5-es.d.ts
CHANGED
package/deno.json
CHANGED
package/package.json
CHANGED
package/q5.js
CHANGED
|
@@ -295,9 +295,6 @@ function Q5(scope, parent, renderer) {
|
|
|
295
295
|
|
|
296
296
|
function wrapWithFES(name) {
|
|
297
297
|
const fn = t[name] || $[name];
|
|
298
|
-
if (fn == undefined) {
|
|
299
|
-
log('hi');
|
|
300
|
-
}
|
|
301
298
|
$[name] = (event) => {
|
|
302
299
|
try {
|
|
303
300
|
return fn(event);
|
|
@@ -313,7 +310,7 @@ function Q5(scope, parent, renderer) {
|
|
|
313
310
|
|
|
314
311
|
readyResolve();
|
|
315
312
|
|
|
316
|
-
if ($.preload) {
|
|
313
|
+
if (t.preload || $.preload) {
|
|
317
314
|
wrapWithFES('preload');
|
|
318
315
|
$.preload();
|
|
319
316
|
}
|
|
@@ -8468,64 +8465,80 @@ Q5.WebGPU = async function (scope, parent) {
|
|
|
8468
8465
|
await q.ready;
|
|
8469
8466
|
return q;
|
|
8470
8467
|
};
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
};
|
|
8494
|
-
} else return;
|
|
8468
|
+
const libLangs = `
|
|
8469
|
+
# core
|
|
8470
|
+
createCanvas -> es:crearLienzo ja:キャンバスを作成する
|
|
8471
|
+
|
|
8472
|
+
# color
|
|
8473
|
+
background -> es:fondo ja:背景
|
|
8474
|
+
|
|
8475
|
+
# display
|
|
8476
|
+
windowWidth -> es:anchoVentana
|
|
8477
|
+
windowHeight -> es:altoVentana
|
|
8478
|
+
frameCount -> es:cuadroActual
|
|
8479
|
+
noLoop -> es:pausar
|
|
8480
|
+
redraw -> es:redibujar
|
|
8481
|
+
loop -> es:reanudar
|
|
8482
|
+
frameRate -> es:frecuenciaRefresco
|
|
8483
|
+
getTargetFrameRate -> es:frecuenciaIdeal
|
|
8484
|
+
getFPS -> es:frecuenciaMaxima
|
|
8485
|
+
deltaTime -> es:ultimoTiempo
|
|
8486
|
+
|
|
8487
|
+
# shape
|
|
8488
|
+
circle -> es:círculo
|
|
8489
|
+
`;
|
|
8495
8490
|
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8491
|
+
const userLangs = `
|
|
8492
|
+
update -> es:actualizar
|
|
8493
|
+
draw -> es:dibujar
|
|
8494
|
+
postProcess -> es:retocarDibujo
|
|
8495
|
+
`;
|
|
8496
|
+
|
|
8497
|
+
const parseLangs = function (data, lang) {
|
|
8498
|
+
let map = {};
|
|
8499
|
+
for (let l of data.split('\n')) {
|
|
8500
|
+
let i = l.indexOf(' ' + lang + ':');
|
|
8501
|
+
if (i > 0 && l[0] != '#') {
|
|
8502
|
+
map[l.split(' ')[0]] = l.slice(i + 4).split(' ')[0];
|
|
8503
|
+
}
|
|
8499
8504
|
}
|
|
8500
|
-
|
|
8505
|
+
return map;
|
|
8506
|
+
};
|
|
8507
|
+
|
|
8508
|
+
Q5._lang = 'en';
|
|
8501
8509
|
|
|
8502
8510
|
Object.defineProperty(Q5, 'lang', {
|
|
8503
|
-
get: () => Q5._lang
|
|
8511
|
+
get: () => Q5._lang,
|
|
8504
8512
|
set: (val) => {
|
|
8513
|
+
if (val == Q5._lang) return;
|
|
8514
|
+
|
|
8505
8515
|
Q5._lang = val;
|
|
8506
8516
|
|
|
8507
|
-
|
|
8517
|
+
if (val == 'en') {
|
|
8518
|
+
// reset to English only user functions
|
|
8519
|
+
Q5._userFns = Q5._userFns.slice(0, 17);
|
|
8520
|
+
Q5._libMap = Q5._userFnsMap = {};
|
|
8521
|
+
return;
|
|
8522
|
+
}
|
|
8508
8523
|
|
|
8509
|
-
|
|
8510
|
-
if (typeof window == 'object') {
|
|
8511
|
-
window.crearLienzo = createCanvas;
|
|
8512
|
-
}
|
|
8524
|
+
let libMap = parseLangs(libLangs, val);
|
|
8513
8525
|
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
} else return;
|
|
8526
|
+
if (typeof window == 'object') {
|
|
8527
|
+
window[libMap.createCanvas] = createCanvas;
|
|
8528
|
+
}
|
|
8529
|
+
|
|
8530
|
+
let userFnsMap = parseLangs(userLangs, val);
|
|
8520
8531
|
|
|
8521
8532
|
for (let name in userFnsMap) {
|
|
8522
|
-
|
|
8533
|
+
let translatedName = userFnsMap[name];
|
|
8534
|
+
if (Q5.hasOwnProperty(translatedName)) continue;
|
|
8523
8535
|
Object.defineProperty(Q5, translatedName, {
|
|
8524
8536
|
get: () => Q5[name],
|
|
8525
8537
|
set: (fn) => (Q5[name] = fn)
|
|
8526
8538
|
});
|
|
8527
8539
|
}
|
|
8528
8540
|
|
|
8541
|
+
Q5._libMap = libMap;
|
|
8529
8542
|
Q5._userFnsMap = userFnsMap;
|
|
8530
8543
|
Q5._userFns.push(...Object.values(userFnsMap));
|
|
8531
8544
|
}
|
|
@@ -8535,10 +8548,25 @@ Q5.modules.lang = ($) => {
|
|
|
8535
8548
|
let userFnsMap = Q5._userFnsMap;
|
|
8536
8549
|
|
|
8537
8550
|
for (let name in userFnsMap) {
|
|
8538
|
-
|
|
8551
|
+
let translatedName = userFnsMap[name];
|
|
8539
8552
|
Object.defineProperty($, translatedName, {
|
|
8540
8553
|
get: () => $[name],
|
|
8541
8554
|
set: (fn) => ($[name] = fn)
|
|
8542
8555
|
});
|
|
8543
8556
|
}
|
|
8557
|
+
|
|
8558
|
+
let libMap = Q5._libMap;
|
|
8559
|
+
|
|
8560
|
+
if (libMap?.createCanvas) {
|
|
8561
|
+
$[libMap.createCanvas] = $.createCanvas;
|
|
8562
|
+
}
|
|
8544
8563
|
};
|
|
8564
|
+
|
|
8565
|
+
Q5.addHook('presetup', ($) => {
|
|
8566
|
+
let libMap = Q5._libMap;
|
|
8567
|
+
|
|
8568
|
+
for (let name in libMap) {
|
|
8569
|
+
let translatedName = libMap[name];
|
|
8570
|
+
$[translatedName] = $[name];
|
|
8571
|
+
}
|
|
8572
|
+
});
|
package/q5.min.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* @license LGPL-3.0
|
|
7
7
|
* @class Q5
|
|
8
8
|
*/
|
|
9
|
-
function Q5(e,t,r){let n,i=this;i._isQ5=i._q5=!0,i._parent=t,i.ready=new Promise((e=>{n=e})),"webgpu-fallback"==r?(i._renderer="c2d",i._webgpu=i._webgpuFallback=!0):(i._renderer=r||"c2d",i["_"+i._renderer]=!0);let a,o="auto"==e;if(e??="global","auto"==e){if(!(window.setup||window.update||Q5.update||window.draw||Q5.draw))return;e="global"}"global"==e&&(Q5._hasGlobal=i._isGlobal=!0,a=Q5._esm?globalThis:Q5._server?global:window),"graphics"==e&&(i._isGraphics=!0),"image"==e&&(i._isImage=!0);let s=new Proxy(i,{set:(e,t,r)=>(i[t]=r,i._isGlobal&&(a[t]=r),!0)});i.canvas=i.ctx=i.drawingContext=null,i.pixels=[];let l=null,d=!0;async function c(e){for(let t of Q5.hooks[e])await t.call(i,s)}i.frameCount=0,i.deltaTime=16,i._targetFrameRate=0,i._targetFrameDuration=16.666666666666668,i._frameRate=i._fps=60,i._loop=!0;let u=0;i.millis=()=>performance.now()-u,i.noCanvas=()=>{i.canvas?.remove&&i.canvas.remove(),i.canvas=0,s.ctx=s.drawingContext=0},window&&(i.windowWidth=window.innerWidth,i.windowHeight=window.innerHeight,i.deviceOrientation=window.screen?.orientation?.type),i._loaders=[],i.loadAll=()=>{let e=[...i._loaders];return i._loaders=[],i._g&&(e=e.concat(i._g._loaders),i._g._loaders=[]),Promise.all(e)},i.isPreloadSupported=()=>!0,i.disablePreload=()=>i._disablePreload=!0;const h=[];async function f(e){let t=e||performance.now();if(i._didResize&&(i.windowResized(),i._didResize=!1),i._loop)if(d)l=g(f);else{let e=t+i._targetFrameDuration,r=e-performance.now();for(;r<0;)r+=i._targetFrameDuration;l=setTimeout((()=>f(e)),r)}else if(i.frameCount&&!i._redraw)return;if(i.frameCount&&d&&!i._redraw){if(t-i._lastFrameTime<i._targetFrameDuration-4)return}s.deltaTime=t-i._lastFrameTime,i._frameRate=1e3/i.deltaTime,s.frameCount++;let r=performance.now();i.resetMatrix(),i._beginRender&&i._beginRender(),await c("predraw");try{await i.draw()}catch(e){throw Q5.errorTolerant||i.noLoop(),i._fes&&i._fes(e),e}await c("postdraw"),await i.postProcess(),i._render&&i._render(),i._finishRender&&i._finishRender(),s.pmouseX=i.mouseX,s.pmouseY=i.mouseY,s.moveX=s.moveY=0,i._lastFrameTime=t;let n=performance.now();i._fps=Math.round(1e3/(n-r))}i._incrementPreload=()=>{i._loaders.push(new Promise((e=>h.push(e))))},i._decrementPreload=()=>{h.length&&h.pop()()},i.noLoop=()=>{i._loop=!1,null!=l&&(d&&window.cancelAnimationFrame?cancelAnimationFrame(l):clearTimeout(l)),l=null},i.loop=()=>{i._loop=!0,i._setupDone&&null==l&&f()},i.isLooping=()=>i._loop,i.redraw=async(e=1)=>{i._redraw=!0;for(let t=0;t<e;t++)await f();i._redraw=!1},i.remove=async()=>{i.noLoop(),i.canvas.remove(),await c("remove")},i.frameRate=e=>(e&&e!=i._targetFrameRate&&(i._targetFrameRate=e,i._targetFrameDuration=1e3/e,i._loop&&null!=l&&(d&&window.cancelAnimationFrame?cancelAnimationFrame(l):clearTimeout(l),l=null),d=e<=60,i._setupDone&&(l=d?g(f):setTimeout((()=>f()),i._targetFrameDuration))),i._frameRate),i.getTargetFrameRate=()=>i._targetFrameRate||60,i.getFPS=()=>i._fps,i.Element=function(e){this.elt=e},i._elements=[],i.describe=()=>{},i.log=i.print=console.log;for(let e in Q5.modules)Q5.modules[e](i,s);let p=Q5.renderers[i._renderer];for(let e in p)p[e](i,s);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(i[e]=Q5[e]);if(i._isGraphics)return;if(i._isGlobal){let e=Object.assign({},i);delete e.Color,Object.assign(Q5,e),delete Q5.Q5}for(let e of Q5.hooks.init)e.call(i,s);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof i[e]&&(i[e]=t.bind(i));for(let[e,t]of Object.entries(Q5.preloadMethods))i[e]=function(){return i._incrementPreload(),t.apply(i,arguments)};if(i._isGlobal){let e=Object.getOwnPropertyNames(i);for(let t of e)"_"!=t[0]&&(a[t]=i[t]);for(let e of["_incrementPreload","_decrementPreload"])a[e]=i[e]}"function"==typeof e&&e(i),Q5._instanceCount++;let g=window.requestAnimationFrame||function(e){const t=i._lastFrameTime+i._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},m=a||i,_=Q5._userFns.slice(0,15);for(let e of _)i[e]??=()=>{};if(i._isGlobal){let e=Q5._userFns.slice(0,17);for(let t of e)Q5[t]?i[t]=Q5[t]:Object.defineProperty(Q5,t,{get:()=>i[t],set:e=>i[t]=e})}function x(e){const t=m[e]||i[e];null==t&&log("hi"),i[e]=e=>{try{return t(e)}catch(e){throw i._fes&&i._fes(e),e}}}async function v(){await c("presetup"),n(),i.preload&&(x("preload"),i.preload()),await Promise.race([new Promise((e=>{!function t(){i.setup||i.update||i.draw||m.setup||m.update||m.draw?e():i._setupDone||(i.canvas?.ready&&i._render&&(i._beginRender(),i._render(),i._finishRender()),g(t))}()})),new Promise((e=>{setTimeout((()=>{i._loaders.length||e()}),500)}))]),i._disablePreload||await i.loadAll(),i.setup??=m.setup||(()=>{}),x("setup");for(let e of _)x(e);i.draw??=m.draw||(()=>{}),u=performance.now(),await i.setup(),i._setupDone=!0,null===i.ctx&&i.createCanvas(200,200),await c("postsetup"),i.frameCount||(i._lastFrameTime=performance.now()-15,g(f))}Q5.instances.push(i),o||Q5._esm?v():setTimeout(v,32)}function createCanvas(e,t,r){if(Q5._hasGlobal)return;if("c2d"==e||"c2d"==t||"c2d"==r||"c2d"==r?.renderer||!Q5._esm){let n=new Q5,i=n.createCanvas(e,t,r);return n.ready.then((()=>i))}return Q5.WebGPU().then((n=>n.createCanvas(e,t,r)))}Q5.renderers={},Q5.modules={},Q5._server="object"==typeof process,Q5._esm=void 0===this,Q5._instanceCount=0,Q5.instances=[],Q5._friendlyError=(e,t)=>{Q5.disableFriendlyErrors||console.error(t+": "+e)},Q5._validateParameters=()=>!0,Q5._userFns=["postProcess","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","doubleClicked","mouseWheel","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized","update","draw"],Q5.hooks={init:[],presetup:[],postsetup:[],predraw:[],postdraw:[],remove:[]},Q5.addHook=(e,t)=>Q5.hooks[e].push(t),Q5.registerAddon=e=>{let t={};e(Q5,Q5.prototype,t);for(let e in t)Q5.hooks[e].push(t[e])},Q5.prototype.registerMethod=(e,t)=>{("beforeSetup"==e||e.includes("Preload"))&&(e="presetup"),"afterSetup"==e&&(e="postsetup"),"pre"==e&&(e="predraw"),"post"==e&&(e="postdraw"),Q5.hooks[e].push(t)},Q5.preloadMethods={},Q5.prototype.registerPreloadMethod=(e,t)=>Q5.preloadMethods[e]=t[e],Q5._server&&(global.q5=global.Q5=Q5,global.p5??=Q5),"object"==typeof window?(window.q5=window.Q5=Q5,window.p5??=Q5,window.createCanvas=createCanvas,window.C2D="c2d",window.WEBGPU="webgpu"):global.window=0,Q5.version=Q5.VERSION="3.7","object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||(Q5.update||Q5.draw?Q5.WebGPU():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(200,200)):(e._isImage||e._isGraphics)&&(t.canvas=new e._Canvas(200,200)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas()),e.displayDensity=()=>window.devicePixelRatio||1,e.width=200,e.height=200,e._pixelDensity=1;let r=e.canvas;if(r&&(r.width=200,r.height=200,r.colorSpace=Q5.canvasOptions.colorSpace,e._isImage||(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity()))),e._adjustDisplay=e=>{let t=r.style;t&&e&&(t.width=r.w+"px",t.height=r.h+"px")},e.createCanvas=function(t,i,a){(isNaN(t)||"string"==typeof t&&!t.includes(":"))&&(a=t,t=null),"number"!=typeof i&&(a=i,i=null),a??=arguments[3],"string"==typeof a&&(a={renderer:a});let o=Object.assign({},Q5.canvasOptions);if("object"==typeof a&&Object.assign(o,a),!e._isImage)if(e._isGraphics)e._pixelDensity=this._pixelDensity;else if(Q5._server)r.visible=!0;else{let t=r,i=document.body||document.documentElement;for(;t&&t.parentElement!=i;)t=t.parentElement;if(t||(document.getElementById(r.id)?.remove(),n()),window.IntersectionObserver){let t=!1;new IntersectionObserver((n=>{if(n[0].isIntersecting)r.visible=!0;else{let e=r.getBoundingClientRect();r.visible=e.top<window.innerHeight&&e.bottom>0&&e.left<window.innerWidth&&e.right>0}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,i),Object.assign(r,o);let s=e._createCanvas(r.w,r.h,o);return e._addEventMethods&&e._addEventMethods(r),e.canvas.ready=!0,s},e.createGraphics=function(t,r,n={}){"string"==typeof n&&(n={renderer:n});let i=new Q5("graphics",void 0,n.renderer||(e._webgpuFallback?"webgpu-fallback":e._renderer));n.alpha??=!0,n.colorSpace??=e.canvas.colorSpace,n.pixelDensity??=e._pixelDensity,i._defaultImageScale=e._defaultImageScale,i.createCanvas.call(e,t,r,n);let a=i._pixelDensity*e._defaultImageScale;return i.defaultWidth=t*a,i.defaultHeight=r*a,i},e._setCanvasSize=(n,i)=>{i??=n??window.innerHeight,n??=window.innerWidth,r.w=n=Math.ceil(n),r.h=i=Math.ceil(i),t.halfWidth=r.hw=n/2,t.halfHeight=r.hh=i/2,r.width=Math.ceil(n*e._pixelDensity),r.height=Math.ceil(i*e._pixelDensity),t.width=n,t.height=i,e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay(!0)},e._setImageSize=(n,i)=>{t.width=r.w=n,t.height=r.h=i,t.halfWidth=r.hw=n/2,t.halfHeight=r.hh=i/2,r.width=Math.ceil(n*e._pixelDensity),r.height=Math.ceil(i*e._pixelDensity)},e.defaultImageScale=t=>t?(e._g&&(e._g._defaultImageScale=t),e._defaultImageScale=t):e._defaultImageScale,e.defaultImageScale(.5),!e._isImage){if(r&&!e._isGraphics){function n(){let t=e._parent;if(t??=document.getElementsByTagName("main")[0],!t){t=document.createElement("main"),(document.body||document.documentElement).appendChild(t)}r.parent(t),document.body||document.addEventListener("DOMContentLoaded",(()=>{document.body&&document.body.appendChild(t)}))}r.parent=t=>{function n(){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(n),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",n)},n()}e.resizeCanvas=(t,n)=>{if(!e.ctx)return e.createCanvas(t,n);t==r.w&&n==r.h||e._resizeCanvas(t,n)},r&&!Q5._createServerCanvas&&(r.resize=e.resizeCanvas),e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._resizeCanvas(r.w,r.h),e._g&&e._g.pixelDensity(t),t):e._pixelDensity,window&&!e._isGraphics&&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.GPU=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;function n(){let t=e._styles.pop();for(let r of e._styleNames)e[r]=t[r]}e.colorMode&&e.colorMode("rgb",e._webgpu?1:255),e._createCanvas=function(n,i,a){if(r)return t.ctx=t.drawingContext=r.getContext("2d",a),e._isImage||(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()},e._isImage||(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._isColor&&(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,n)=>{let i,a={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(a[t]=e.ctx[t]);if(delete a.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,n);for(let t in a)e.ctx[t]=a[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._isColor||"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._isColor||"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.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._getFillIdx=()=>e._fill,e._setFillIdx=t=>e._fill=t,e._getStrokeIdx=()=>e._stroke,e._setStrokeIdx=t=>e._stroke=t,e._doShadow=!1,e._shadowOffsetX=e._shadowOffsetY=e._shadowBlur=10,e.shadow=function(t){if(Q5.Color&&(t._isColor||"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,n)=>{e.ctx.shadowOffsetX=e._shadowOffsetX=t,e.ctx.shadowOffsetY=e._shadowOffsetY=r||t,e.ctx.shadowBlur=e._shadowBlur=n||0},e.noShadow=()=>{e._doShadow=!1,e.ctx.shadowOffsetX=e.ctx.shadowOffsetY=e.ctx.shadowBlur=0},e.translate=(t,r)=>{t.x&&(r=t.y,t=t.x),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,n,i,a,o)=>e.ctx.transform(t,r,n,i,a,o),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._styleNames=["_fill","_stroke","_strokeWeight","_doFill","_doStroke","_fillSet","_strokeSet","_shadow","_doShadow","_shadowOffsetX","_shadowOffsetY","_shadowBlur","_tint","_textSize","_textAlign","_textBaseline","_imageMode","_rectMode","_ellipseMode","_colorMode","_colorFormat","Color"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t),e._fontMod&&e._updateFont()},e.popStyles=()=>{n(),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.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore(),e.push=()=>{e.pushStyles(),e.ctx.save()},e.pop=()=>{e.ctx.restore(),n()})},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 n(){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,n,i)=>{e._doStroke&&(e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(n,i),e.ctx.stroke())};const i=2*Math.PI;function a(t,r,n,a,o,s,l){if(e._angleMode&&(o=e.radians(o),s=e.radians(s)),(o%=i)<0&&(o+=i),(s%=i)<0&&(s+=i),o>s&&(s+=i),o==s)return e.ellipse(t,r,n,a);if(n/=2,a/=2,n=Math.abs(n),a=Math.abs(a),e._doFill||l!=e.PIE_OPEN||(l=e.CHORD_OPEN),e.ctx.beginPath(),e.ctx.ellipse(t,r,n,a,0,o,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,n,a,0,o,s),e.ctx.stroke()}}function o(t,r,a,o){e.ctx.beginPath(),e.ctx.ellipse(t,r,Math.abs(a/2),Math.abs(o/2),0,0,i),n()}function s(t,r,i,a,o,l,d,c){return void 0===o?function(t,r,i,a){e.ctx.beginPath(),e.ctx.rect(t,r,i,a),n()}(t,r,i,a):void 0===l?s(t,r,i,a,o,o,o,o):(e.ctx.beginPath(),e.ctx.roundRect(t,r,i,a,[o,l,d,c]),void n())}e.arc=(t,r,n,i,o,s,l)=>{if(o==s)return e.ellipse(t,r,n,i);l??=e.PIE_OPEN,e._ellipseMode==e.CENTER?a(t,r,n,i,o,s,l):e._ellipseMode==e.RADIUS?a(t,r,2*n,2*i,o,s,l):e._ellipseMode==e.CORNER?a(t+n/2,r+i/2,n,i,o,s,l):e._ellipseMode==e.CORNERS&&a((t+n)/2,(r+i)/2,n-t,i-r,o,s,l)},e.ellipse=(t,r,n,i)=>{i??=n,e._ellipseMode==e.CENTER?o(t,r,n,i):e._ellipseMode==e.RADIUS?o(t,r,2*n,2*i):e._ellipseMode==e.CORNER?o(t+n/2,r+i/2,n,i):e._ellipseMode==e.CORNERS&&o((t+n)/2,(r+i)/2,n-t,i-r)},e.circle=(t,r,a)=>{e._ellipseMode==e.CENTER?(e.ctx.beginPath(),e.ctx.arc(t,r,Math.abs(a/2),0,i),n()):e.ellipse(t,r,a,a)},e.point=(t,r)=>{e._doStroke&&(t.x&&(r=t.y,t=t.x),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(t,r),e.ctx.stroke())},e.rect=(t,r,n,i=n,a,o,l,d)=>{e._rectMode==e.CENTER?s(t-n/2,r-i/2,n,i,a,o,l,d):e._rectMode==e.RADIUS?s(t-n,r-i,2*n,2*i,a,o,l,d):e._rectMode==e.CORNER?s(t,r,n,i,a,o,l,d):e._rectMode==e.CORNERS&&s(t,r,n-t,i-r,a,o,l,d)},e.square=(t,r,n,i,a,o,s)=>e.rect(t,r,n,n,i,a,o,s),e.capsule=(t,r,i,a,o)=>{const s=i-t,l=a-r,d=Math.hypot(s,l);if(0===d)return e.circle(t,r,2*o);const c=Math.atan2(l,s),u=-l/d*o,h=s/d*o;e.ctx.beginPath(),e.ctx.moveTo(t-u,r-h),e.ctx.arc(t,r,o,c-e.HALF_PI,c+e.HALF_PI,!0),e.ctx.lineTo(i+u,a+h),e.ctx.arc(i,a,o,c+e.HALF_PI,c-e.HALF_PI,!0),e.ctx.closePath(),n()},e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(n,i)=>{r=[],t?e.ctx.moveTo(n,i):e.ctx.lineTo(n,i),t=!1},e.bezierVertex=(t,n,i,a,o,s)=>{r=[],e.ctx.bezierCurveTo(t,n,i,a,o,s)},e.quadraticVertex=(t,n,i,a)=>{r=[],e.ctx.quadraticCurveTo(t,n,i,a)},e.bezier=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(n,i,a,o,s,l),e.endShape()},e.triangle=(t,r,n,i,a,o)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.endShape(e.CLOSE)},e.quad=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),n()},e.curveVertex=(n,i)=>{if(r.push([n,i]),r.length<4)return;let a=r.at(-4),o=r.at(-3),s=r.at(-2),l=r.at(-1),d=o[0]+(s[0]-a[0])/6,c=o[1]+(s[1]-a[1])/6,u=s[0]-(l[0]-o[0])/6,h=s[1]-(l[1]-o[1])/6;t&&(e.ctx.moveTo(o[0],o[1]),t=!1),e.ctx.bezierCurveTo(d,c,u,h,s[0],s[1])},e.curve=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(n,i),e.curveVertex(a,o),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,n,i)=>{const a=i*i*i,o=i*i;return e*(-.5*a+o-.5*i)+t*(1.5*a-2.5*o+1)+r*(-1.5*a+2*o+.5*i)+n*(.5*a-.5*o)},e.bezierPoint=(e,t,r,n,i)=>{const a=1-i;return Math.pow(a,3)*e+3*Math.pow(a,2)*i*t+3*a*Math.pow(i,2)*r+Math.pow(i,3)*n},e.curveTangent=(e,t,r,n,i)=>{const a=i*i;return e*(-3*a/2+2*i-.5)+t*(9*a/2-5*i)+r*(-9*a/2+4*i+.5)+n*(3*a/2-i)},e.bezierTangent=(e,t,r,n,i)=>{const a=1-i;return 3*n*Math.pow(i,2)-3*r*Math.pow(i,2)+6*r*a*i-6*t*a*i+3*t*Math.pow(a,2)-3*e*Math.pow(a,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 n=e._pixelDensity;return e.ctx.isPointInPath(t*n,r*n)},e.inStroke=(t,r)=>{const n=e._pixelDensity;return e.ctx.isPointInStroke(t*n,r*n)}},Q5.renderers.c2d.image=(e,t)=>{const r=e.canvas;r&&(r.convertToBlob??=e=>new Promise((t=>{r.toBlob((e=>t(e)),e.type,e.quality)}))),e._tint=null;let n=null,i=null;e.createImage=(t,r,n={})=>(n.colorSpace??=e.canvas.colorSpace,n.defaultImageScale??=e._defaultImageScale,new Q5.Image(t,r,n)),e.loadImage=function(t,r,n){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?(n=i,r=null):n=void 0;let a=e.createImage(1,1,n),o=a._pixelDensity,s=new window.Image;return s.crossOrigin="Anonymous",a.promise=new Promise(((t,i)=>{s.onload=()=>{delete a.then,a._usedAwait&&(a=e.createImage(1,1,n)),s._pixelDensity=o,a.defaultWidth=s.width*e._defaultImageScale,a.defaultHeight=s.height*e._defaultImageScale,a.naturalWidth=s.naturalWidth||s.width,a.naturalHeight=s.naturalHeight||s.height,a._setImageSize(Math.ceil(a.naturalWidth/o),Math.ceil(a.naturalHeight/o)),a.ctx.drawImage(s,0,0),r&&r(a),t(a)},s.onerror=i})),e._loaders.push(a.promise),a.then=(e,t)=>(a._usedAwait=!0,a.promise.then(e,t)),a.src=s.src=t,a},e._imageMode=Q5.CORNER,e.imageMode=t=>e._imageMode=t,e.image=(t,r,n,i,a,o=0,s=0,l,d)=>{if(!t)return;let c=t.canvas||t;i??=t.defaultWidth||c.width||t.videoWidth,a??=t.defaultHeight||c.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*i,n-=.5*a);let u=t._pixelDensity||1;if(l?l*=u:l=c.width||c.videoWidth,d?d*=u:d=c.height||c.videoHeight,e._tint){if(t._retint||t._tint!=e._tint){t._tintImg??=e.createImage(t.w,t.h,{pixelDensity:u}),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,o*u,s*u,l,d,r,n,i,a),t.flipped&&e.ctx.restore()},e.filter=(t,n)=>{e.ctx.save();let i="";if(e.ctx.filter){if("string"==typeof t)i=t;else if(t==Q5.GRAY)i="saturate(0%)";else if(t==Q5.INVERT)i="invert(100%)";else if(t==Q5.BLUR){i=`blur(${Math.ceil(n*e._pixelDensity)||1}px)`}else if(t==Q5.THRESHOLD){n??=.5,i=`saturate(0%) brightness(${Math.floor(.5/Math.max(n,1e-5)*100)}%) contrast(1000000%)`}else if(t==Q5.SEPIA)i=`sepia(${n??1})`;else if(t==Q5.BRIGHTNESS)i=`brightness(${n??1})`;else if(t==Q5.SATURATION)i=`saturate(${n??1})`;else if(t==Q5.CONTRAST)i=`contrast(${n??1})`;else if(t==Q5.HUE_ROTATE){i=`hue-rotate(${n}${0==e._angleMode?"rad":"deg"})`}if(i&&(e.ctx.filter=i,"none"==e.ctx.filter))throw new Error(`Invalid filter format: ${t}`)}i||e._softFilter(t,n),e.ctx.globalCompositeOperation="source-over",e.ctx.drawImage(r,0,0,r.w,r.h),e.ctx.restore(),e.modified=e._retint=!0},e._isImage&&(e.resize=(t,n)=>{let i=new e._Canvas(r.width,r.height);i.getContext("2d",{colorSpace:r.colorSpace}).drawImage(r,0,0),e._setImageSize(t,n),e.defaultWidth=r.width*e._defaultImageScale,e.defaultHeight=r.height*e._defaultImageScale,e.ctx.clearRect(0,0,r.width,r.height),e.ctx.drawImage(i,0,0,r.width,r.height),e.modified=e._retint=!0}),e._getImageData=(t,n,i,a)=>e.ctx.getImageData(t,n,i,a,{colorSpace:r.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,n=r.width,i=r.height,a=e._getImageData(0,0,n,i).data,o=n,s=0,l=i,d=0,c=3;for(let e=0;e<i;e++)for(let t=0;t<n;t++)0!==a[c]&&(t<o&&(o=t),t>s&&(s=t),e<l&&(l=e),e>d&&(d=e)),c+=4;return l=Math.floor(l/t),d=Math.floor(d/t),o=Math.floor(o/t),s=Math.floor(s/t),e.get(o,l,s-o+1,d-l+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,n,i,a,o,s,l,d)=>{let c=e._pixelDensity||1;e.ctx.drawImage(r,t*c,n*c,i*c,a*c,o,s,l,d),e.modified=e._retint=!0},e.copy=()=>{let t=e.get();for(let r in e)"function"==typeof e[r]||/(canvas|ctx|texture)/.test(r)||(t[r]=e[r]);return t},e.get=(t,n,a,o)=>{let s=e._pixelDensity||1;if(void 0!==t&&void 0===a){i||e.loadPixels();let a=Math.floor(t*s),o=4*(Math.floor(n*s)*r.width+a);return[i[o],i[o+1],i[o+2],i[o+3]]}t=Math.floor(t||0)*s,n=Math.floor(n||0)*s,a??=e.width,o??=e.height;let l=e.createImage(a,o,{pixelDensity:s});return l.ctx.drawImage(r,t,n,a*s,o*s,0,0,a,o),l.width=a,l.height=o,e._owner?._makeDrawable&&e._owner._makeDrawable(l),l},e.set=(t,n,a)=>{if(t=Math.floor(t),n=Math.floor(n),e.modified=e._retint=!0,a.canvas){let r=e._tint;return e._tint=null,e.image(a,t,n),void(e._tint=r)}i||e.loadPixels();let o=e._pixelDensity||1,s=a.r,l=a.g,d=a.b,c=a.a;1==(e._colorFormat||e._owner?._colorFormat)&&(s*=255,l*=255,d*=255,c*=255);for(let e=0;e<o;e++)for(let a=0;a<o;a++){let u=4*((n*o+e)*r.width+t*o+a);i[u]=s,i[u+1]=l,i[u+2]=d,i[u+3]=c}},e.loadPixels=()=>{n=e._getImageData(0,0,r.width,r.height),t.pixels=i=n.data},e.updatePixels=()=>{null!=n&&(e.ctx.putImageData(n,0,0),e.modified=e._retint=!0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,e._isImage||(e.tint=function(t){e._tint=(t._isColor?t:e.color(...arguments)).toString()},e.noTint=()=>e._tint=null)},Q5.Image=class{constructor(e,t,r={}){r.alpha??=!0,r.colorSpace??=Q5.canvasOptions.colorSpace;let n=this;n._isImage=!0,n.canvas=n.ctx=n.drawingContext=null,n.pixels=[],Q5.modules.canvas(n,n);let i=Q5.renderers.c2d;for(let e of["canvas","image","softFilters"])i[e]&&i[e](n,n);n._pixelDensity=r.pixelDensity||1,n._defaultImageScale=r.defaultImageScale||2,n.createCanvas(e,t,r);let a=n._pixelDensity*n._defaultImageScale;n.defaultWidth=e*a,n.defaultHeight=t*a,delete n.createCanvas,n._loop=!1}get w(){return this.width}get h(){return this.height}},Q5.renderers.c2d.softFilters=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=(n,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 n=.2126*e[r]+.7152*e[r+1]+.0722*e[r+2];e[r]=e[r+1]=e[r+2]=n>=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 n=0;n<e.length;n+=4)e[n]=255*(e[n]*t>>8)/r,e[n+1]=255*(e[n+1]*t>>8)/r,e[n+2]=255*(e[n+2]*t>>8)/r},e._filters[Q5.DILATE]=(n,i)=>{i??=Math.max,r(),t.set(n);let[a,o]=[e.canvas.width,e.canvas.height];for(let e=0;e<o;e++)for(let r=0;r<a;r++){let s=4*Math.max(r-1,0),l=4*Math.min(r+1,a-1),d=4*Math.max(e-1,0)*a,c=4*Math.min(e+1,o-1)*a,u=4*e*a,h=4*r;for(let e=0;e<4;e++){let r=e+d,a=e+c,o=e+u;n[u+h+e]=i(t[r+h],t[o+s],t[o+h],t[o+l],t[a+h])}}},e._filters[Q5.ERODE]=t=>{e._filters[Q5.DILATE](t,Math.min)},e._filters[Q5.BLUR]=(n,i)=>{i=i||1,i=Math.floor(i*e._pixelDensity),r(),t.set(n);let a=2*i+1,o=function(e){let t=new Float32Array(e),r=.3*i+.8,n=r*r*2;for(let i=0;i<e;i++){let a=i-e/2,o=Math.exp(-a*a/n)/(2.5066282746*r);t[i]=o}return t}(a),[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,u=0;for(let n=0;n<a;n++){let a=4*(e*s+Math.min(Math.max(r-i+n,0),s-1));l+=t[a]*o[n],d+=t[a+1]*o[n],c+=t[a+2]*o[n],u+=t[a+3]*o[n]}let h=4*(e*s+r);n[h]=l,n[h+1]=d,n[h+2]=c,n[h+3]=u}t.set(n);for(let e=0;e<l;e++)for(let r=0;r<s;r++){let d=0,c=0,u=0,h=0;for(let n=0;n<a;n++){let a=4*(Math.min(Math.max(e-i+n,0),l-1)*s+r);d+=t[a]*o[n],c+=t[a+1]*o[n],u+=t[a+2]*o[n],h+=t[a+3]*o[n]}let f=4*(e*s+r);n[f]=d,n[f+1]=c,n[f+2]=u,n[f+3]=h}});let a=e._getImageData(0,0,e.canvas.width,e.canvas.height);e._filters[n](a.data,i),e.ctx.putImageData(a,0,0)}},Q5.renderers.c2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic",e._textSize=12;let r="sans-serif",n=!1,i=15,a=3,o="normal",s="normal",l=0,d=!1,c=0;e._fontMod=!1;let u=e._textCache={};e.loadFont=(t,r)=>{let n;if(t.includes("fonts.googleapis.com/css"))n=function(e,t){e.startsWith("http")||(e="https://"+e);const r=new URL(e).searchParams,n=r.get("family");if(!n)return console.error("Invalid Google Fonts URL: missing family parameter"),null;const i=n.split(":")[0];let a={family:i};return a.promise=(async()=>{try{const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch Google Font: ${r.status} ${r.statusText}`);let n,o=await r.text(),s=/@font-face\s*{([^}]*)}/g,l=/src:\s*url\(([^)]+)\)[^;]*;/,d=/font-family:\s*['"]([^'"]+)['"]/,c=/font-weight:\s*([^;]+);/,u=/font-style:\s*([^;]+);/,h=[];for(;null!==(n=s.exec(o));){let e=n[1],t=l.exec(e);if(!t)continue;let r=t[1],i=d.exec(e);if(!i)continue;let a=i[1],o=c.exec(e),s=o?o[1]:"400",f=u.exec(e),p=f?f[1]:"normal",g=`${a}-${s}-${p}`.replace(/\s+/g,"-"),m=new FontFace(a,`url(${r})`,{weight:s,style:p});document.fonts.add(m);try{await m.load(),h.push(m)}catch(e){console.error(`Failed to load font face: ${g}`,e)}}return a._usedAwait&&(a={family:i}),a.faces=h,delete a.then,t&&t(a),a}catch(e){throw console.error("Error loading Google Font:",e),e}})(),a}(t,r);else{let e=t.split("/").pop().split(".")[0].replace(" ","");n={family:e};let i=new FontFace(e,`url(${encodeURI(t)})`);document.fonts.add(i),n.promise=new Promise(((e,t)=>{i.load().then((()=>{delete n.then,r&&r(i),e(i)})).catch((e=>{t(e)}))}))}return e._loaders.push(n.promise),e.textFont(n.family),n.then=(e,t)=>(n._usedAwait=!0,n.promise.then(e,t)),n},e.textFont=t=>{if(t&&"string"!=typeof t&&(t=t.family),!t||t==r)return r;r=t,e._fontMod=!0,l=-1},e.textSize=t=>{if(null==t)return e._textSize;e._textSize=t,e._fontMod=!0,l=-1,n||(i=1.25*t,a=i-t)},e.textStyle=t=>{if(!t)return o;o=t,e._fontMod=!0,l=-1},e.textWeight=t=>{if(!t)return s;s=t,e._fontMod=!0,l=-1},e.textLeading=t=>null==t?i||1.25*e._textSize:(n=!0,t==i?i:(i=t,a=t-e._textSize,void(l=-1))),e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r)},e._updateFont=()=>{e.ctx.font=`${o} ${s} ${e._textSize}px ${r}`,e._fontMod=!1},e.textWidth=t=>(e._fontMod&&e._updateFont(),e.ctx.measureText(t).width),e.textAscent=t=>(e._fontMod&&e._updateFont(),e.ctx.measureText(t).actualBoundingBoxAscent),e.textDescent=t=>(e._fontMod&&e._updateFont(),e.ctx.measureText(t).actualBoundingBoxDescent),e.textFill=e.fill,e.textStroke=e.stroke;e.createTextImage=(t,r,n)=>{d=!0;let i=e.text(t,0,0,r,n);return d=!1,i};let h=[];e.text=(t,n,s,f,p)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString();let g,m,_,x,v,b,y,w,S=e.ctx;if(e._fontMod&&e._updateFont(),d)if(-1==l&&(()=>{let t=r+e._textSize+o+i,n=5381;for(let e=0;e<t.length;e++)n=33*n^t.charCodeAt(e);l=n>>>0})(),m=e._fill+e._stroke+e._strokeWeight,_=u[t],_?x=_[l]:_=u[t]={},x){if(g=x[m],g)return g;if(x.size>=4){for(let e in x){g=x[e],delete x[e];break}v=!0}}else x=_[l]={};if(-1==t.indexOf("\n")?h[0]=t:h=t.split("\n"),t.length>f){let e=[];for(let t of h){let r=0;for(;r<t.length;){let n=r+f;if(n>=t.length){e.push(t.slice(r));break}let i=t.lastIndexOf(" ",n);(-1===i||i<r)&&(i=n),e.push(t.slice(r,i)),r=i+1}}h=e}if(d){if(b=0,y=i,g){let e=g.canvas;g.ctx.clearRect(0,0,e.width,e.height),g.modified=!0}else{let t=e.ctx.textBaseline;e.ctx.textBaseline="alphabetic";let r=S.measureText(" "),n=r.fontBoundingBoxAscent,o=r.fontBoundingBoxDescent;e.ctx.textBaseline=t;let s=0;for(let e of h){let t=S.measureText(e).width;t>s&&(s=t)}let l=Math.ceil(s),d=Math.ceil(i*h.length+o);g=e.createImage.call(e,l,d,{pixelDensity:e._pixelDensity,defaultImageScale:1/e._pixelDensity}),g._ascent=n,g._descent=o,g._top=o+a,g._middle=g._top+.5*n+i*(h.length-1)*.5,g._bottom=g._top+n+i*(h.length-1),g._leading=i}S=g.ctx,S.font=e.ctx.font,S.fillStyle=e._fill,S.strokeStyle=e._stroke,S.lineWidth=e.ctx.lineWidth}else b=n,y=s,"middle"==e._textBaseline?y-=i*(h.length-1)*.5:"bottom"==e._textBaseline&&(y-=i*(h.length-1));e._fillSet||(w=S.fillStyle,S.fillStyle="black");let C=0;for(let t of h)if(e._doStroke&&e._strokeSet&&S.strokeText(t,b,y),e._doFill&&S.fillText(t,b,y),y+=i,C++,C>=p)break;if(h=[],e._fillSet||(S.fillStyle=w),d){if(x[m]=g,v||(x.size||(Object.defineProperty(x,"size",{writable:!0,enumerable:!1}),x.size=0),x.size++,c++),c>Q5.MAX_TEXT_IMAGES){for(const e in u){_=u[e];for(const e in _){x=_[e];for(let e in x){let t=x[e];t._texture&&t._texture.destroy(),delete x[e]}}}c=0}return g}},e.textImage=(t,r,n)=>{"string"==typeof t&&(t=e.createTextImage(t));let i=e._imageMode;e._imageMode="corner";let a=e._textAlign;"center"==a?r-=t.canvas.hw:"right"==a&&(r-=t.width);let o=e._textBaseline;"alphabetic"==o?n-=t._leading:"middle"==o?n-=t._middle:"bottom"==o?n-=t._bottom:"top"==o&&(n-=t._top),e.image(t,r,n),e._imageMode=i}},Q5.fonts=[],Q5.MAX_TEXT_IMAGES=5e3,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,n,i)=>{e._colorMode=r;let a="srgb"==e.canvas.colorSpace||"srgb"==i;e._srgb=a,n??="rgb"==r&&(e._c2d||a)?255:1,e._colorFormat="integer"==n||255==n?255:1,"oklch"==r?t.Color=Q5.ColorOKLCH:"hsl"==r?t.Color=a?Q5.ColorHSL:Q5.ColorHSL_P3:"hsb"==r?t.Color=a?Q5.ColorHSB:Q5.ColorHSB_P3:(255==e._colorFormat?t.Color=a?Q5.ColorRGB_8:Q5.ColorRGB_P3_8:t.Color=a?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],coral:[255,127,80],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],silver:[192,192,192],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,n,i)=>{let a=e.Color;if(t._isColor)return new a(...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)),n=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)),n=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 a(0,0,0);return e._css=t,e.toString=function(){return this._css},e}if([t,r,n,i]=e._namedColors[t],"rgb"!=e._colorMode)return a=e._srgb?Q5.ColorRGB_8:Q5.ColorRGB_P3_8,new a(t,r,n,i)}1==e._colorFormat&&(t/=255,r&&(r/=255),n&&(n/=255),i&&(i/=255))}(Array.isArray(t)||t.constructor==Float32Array)&&([t,r,n,i]=t)}return null==n?e._colorMode==Q5.OKLCH?new a(t,0,0,r):new a(t,t,t,r):new a(t,r,n,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,n=t.g,i=t.b;255==e._colorFormat&&(r/=255,n/=255,i/=255);let a,o=Math.max(r,n,i),s=Math.min(r,n,i);return a=o==s?0:o==r?60*(n-i)/(o-s):o==n?60*(i-r)/(o-s)+120:60*(r-n)/(o-s)+240,a<0&&(a+=360),a},e.lerpColor=(t,r,n)=>{if(n=Math.max(0,Math.min(1,n)),"rgb"==e._colorMode)return new e.Color(e.lerp(t.r,r.r,n),e.lerp(t.g,r.g,n),e.lerp(t.b,r.b,n),e.lerp(t.a,r.a,n));{let i=r.h-t.h;i>180&&(i-=360),i<-180&&(i+=360);let a=t.h+n*i;return a<0&&(a+=360),a>360&&(a-=360),new e.Color(e.lerp(t.l,r.l,n),e.lerp(t.c,r.c,n),a,e.lerp(t.a,r.a,n))}}},Q5.Color=class{constructor(){this._isColor=!0,this._q5Color=!0}get alpha(){return this.a}set alpha(e){this.a=e}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,n){super(),this.l=e,this.c=t,this.h=r,this.a=n??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,n){super(),this.r=e,this.g=t,this.b=r,this.a=n??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,n){super(e,t,r,n??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,n){super(e,t,r,n??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),n=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${n})`,this._edited=!1}return this._css}},Q5.ColorHSL=class extends Q5.Color{constructor(e,t,r,n){super(),this.h=e,this.s=t,this.l=r,this.a=n??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,n){super(e,t,r,n),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 n=t/100*Math.min(r,1-r),i=(t,i=(t+e/30)%12)=>r-n*Math.max(Math.min(i-3,9-i,1),-1);return[i(0),i(8),i(4)]},Q5.HSBtoHSL=(e,t,r,n=r*(1-t/200))=>[e,n&&100!=n?(r-n)/Math.min(n,100-n)*100:0,n];{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)))),n=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,a,o)=>r(i(n(t(e,a,o))))}Q5.modules.display=e=>{if(!e.canvas||e._isGraphics)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=e=>{let r=t.style;if(r)if("normal"==t.displayMode){if(!e)return;r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"}else{let e=t.parentElement.getBoundingClientRect();t.w/t.h>e.width/e.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",n="smooth",i=1)=>{Q5._server||("string"==typeof i&&(i=parseFloat(i.slice(1))),"fullscreen"==r&&(r="maxed"),"center"==r&&(r="centered"),t.displayMode&&(t.parentElement.classList.remove("q5-"+t.displayMode),t.classList.remove("q5-pixelated")),t.parentElement.classList.add("q5-"+r),"pixelated"==n&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.defaultImageScale(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),Object.assign(t,{displayMode:r,renderQuality:n,displayScale:i}),e.ctx&&e.pushStyles(),e._adjustDisplay(!0),e.ctx&&e.popStyles())},e.fullscreen=e=>{if(null==e)return document.fullscreenElement;e?document.body.requestFullscreen():document.exitFullscreen()}},Q5.modules.dom=(e,t)=>{e.elementMode=t=>e._elementMode=t,e.createElement=(t,r)=>{let n=document.createElement(t);return"center"==e._elementMode&&(n.style.transform="translate(-50%, -50%)"),r&&(n.innerHTML=r),Object.defineProperty(n,"x",{get:()=>n._x,set:t=>{let r=n.style.position;r&&"relative"!=r||(n.style.position="absolute");let i=e.canvas.offsetLeft+t;n.style.left=i+"px",n._x=i}}),Object.defineProperty(n,"y",{get:()=>n._y,set:t=>{let r=n.style.position;r&&"relative"!=r||(n.style.position="absolute");let i=e.canvas.offsetTop+t;n.style.top=i+"px",n._y=i}}),Object.defineProperty(n,"width",{get:()=>parseFloat(n.style.width||0),set:e=>n.style.width=e+"px"}),Object.defineProperty(n,"height",{get:()=>parseFloat(n.style.height||0),set:e=>n.style.height=e+"px"}),n.position=(e,t,r)=>(r&&(n.style.position=r),n.x=e,n.y=t,n),Object.defineProperty(n,"size",{writable:!0}),n.size=(e,t)=>(n.width=e,n.height=t,n),n.center=()=>(n.style.position="absolute",n.x=e.canvas.hw,n.y=e.canvas.hh,n),n.show=()=>(n.style.display="",n),n.hide=()=>(n.style.display="none",n),n.parent=e=>(e.append(n),n),e._addEventMethods(n),e._elements.push(n),e.canvas?e.canvas.parentElement.append(n):document.body.append(n),n.elt=n,n},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,n)=>{let i=e.createEl("a",r);return i.href=t,i.target=n?"_blank":"_self",i},e.createButton=t=>e.createEl("button",t),e.createCheckbox=(t="",r=!1)=>{let n=e.createEl("input");n.type="checkbox",n.checked=r;let i=e.createEl("label",t);return i.addEventListener("click",(()=>{n.checked=!n.checked,n.dispatchEvent(new Event("input",{bubbles:!0})),n.dispatchEvent(new Event("change",{bubbles:!0}))})),n.insertAdjacentElement("afterend",i),n.label=i,n},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 n=e.createEl("input");return n.value=t,n.type=r,n.style.boxSizing="border-box",n},e.createP=t=>e.createEl("p",t);let r=0;function n(t){t.width||=t.videoWidth,t.height||=t.videoHeight,t.defaultWidth=t.width*e._defaultImageScale,t.defaultHeight=t.height*e._defaultImageScale,t.ready=!0}e.createRadio=t=>{let n=e.createEl("div");return n.name=t||"radio"+r++,n.buttons=[],Object.defineProperty(n,"value",{get:()=>n.selected?.value,set:e=>{let t=n.buttons.find((t=>t.value==e));t&&(t.checked=!0,n.selected=t)}}),n.option=(t,r)=>{let i=e.createEl("input");i.type="radio",i.name=n.name,i.value=r||t,i.addEventListener("input",(()=>n.selected=i));let a=e.createEl("label",t);return a.addEventListener("click",(()=>{i.checked=!0,n.selected=i,i.dispatchEvent(new Event("input",{bubbles:!0})),i.dispatchEvent(new Event("change",{bubbles:!0}))})),i.label=a,n.append(i),n.append(a),n.buttons.push(i),n},n},e.createSelect=t=>{let r=e.createEl("select");if(t){let n=e.createEl("option",t);n.disabled=!0,n.selected=!0,r.append(n)}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 n=0;n<r.options.length;n++)if(r.options[n].value==e){t=r.options[n];break}t&&(t.selected=!0)}}}),r.option=(t,n)=>{let i=e.createEl("option",t);return i.value=n||t,r.append(i),r},r},e.createSlider=(t,r,n,i)=>{let a=e.createEl("input");return a.type="range",a.min=t,a.max=r,a.step=i,a.value=n,a.val=()=>parseFloat(a.value),a},e.createSpan=t=>e.createEl("span",t),e.createVideo=t=>{let r=e.createEl("video");return r.crossOrigin="anonymous",t&&(r.promise=new Promise((i=>{r.addEventListener("loadeddata",(()=>{delete r.then,r._usedAwait&&(r=e.createEl("video"),r.crossOrigin="anonymous",r.src=t),n(r),i(r)})),r.src=t})),e._loaders.push(r.promise),r.then=(e,t)=>(r._usedAwait=!0,r.promise.then(e,t))),r},e.createCapture=function(t,r=!0,i){let a="string"==typeof t?{[t]:!0}:t||{video:!0,audio:!0};!0===a.video&&(a.video={width:3840,height:2160}),a.video.facingMode??="user";let o=e.createVideo();return o.promise=(async()=>{let t;try{t=await navigator.mediaDevices.getUserMedia(a)}catch(e){throw e}return delete o.then,o._usedAwait&&(o=e.createVideo()),function(t){t.playsinline=t.autoplay=!0,r&&(t.flipped=!0,t.style.transform="scale(-1, 1)"),t.loadPixels=()=>{let r=e.createGraphics(t.videoWidth,t.videoHeight,{renderer:"c2d"});r.image(t,0,0),r.loadPixels(),t.pixels=r.pixels,r.remove()}}(o),o.srcObject=t,await new Promise((e=>o.addEventListener("loadeddata",e))),n(o),i&&i(o),o})(),e._loaders.push(o.promise),o.then=(e,t)=>(o._usedAwait=!0,o.promise.then(e,t)),o},e.findElement=e=>document.querySelector(e),e.findElements=e=>document.querySelectorAll(e)},Q5.modules.fes=e=>{if(e._fes=async t=>{if(Q5.disableFriendlyErrors)return;t._handledByFES=!0;let r=t.stack?.split("\n");if(!r?.length)return;let n=1,i="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(n=0,i="@");r[n].indexOf("q5")>=0;)n++;let a=r[n].split(i).at(-1);a.startsWith("blob:")&&(a=a.slice(5)),a=a.split(")")[0];let o=a.split(":"),s=parseInt(o.at(-2));o[o.length-1]=o.at(-1).split(")")[0];let l=t.file||o.slice(0,-2).join(":"),d=l.split("/").at(-1);try{let t=(await(await fetch(l)).text()).split("\n"),r=t[s-1]?.trim()??"",n=["🐛","🐞","🐜","🦗","🦋","🪲"][Math.floor(6*Math.random())],i=window.self!==window.top,a=`q5.js ${n}`,o=` Error in ${d} on line ${s}:\n\n${r}`;i?e.log(a+o):e.log(`%c${a}%c${o}`,"background: #b7ebff; color: #000;","")}catch(e){}},"undefined"!=typeof window&&window.addEventListener){let t=new Error,r=t.stack?.split("\n")||"";for(let t of r){let r=t.match(/(https?:\/\/[^\s)]+\.js|\b\/[^\s)]+\.js)/);if(r){let t=r[1];if(!/q5|p5play/i.test(t)){e._sketchFile=t;break}}}e._sketchFile&&(window.addEventListener("error",(t=>{let r=t.error;t.filename!==e._sketchFile||r?._handledByFES||(r.file=t.filename,e._fes(r))})),window.addEventListener("unhandledrejection",(t=>{let r=t.reason;r?.stack?.includes(e._sketchFile)&&!r?._handledByFES&&e._fes(r)})))}if(e._isGlobal&&0!=Q5.online&&null!=typeof navigator&&navigator.onLine){!async function(){try{let e=await fetch("https://data.jsdelivr.com/v1/package/npm/q5");if(!e.ok)return;let t=(await e.json()).tags.latest;t=t.slice(0,t.lastIndexOf(".")),t!=Q5.version&&console.warn(`q5.js v${t} is now available! Consider updating from v${Q5.version}.`)}catch(e){}}()}},Q5.modules.input=(e,t)=>{if(e._isGraphics)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.pointers={},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={},n=[Q5.LEFT,Q5.CENTER,Q5.RIGHT],i=e.canvas;e._startAudio=()=>{Q5.aud&&"running"==Q5.aud?.state||e.userStartAudio()},e._updatePointer=r=>{let n=r.pointerId;e.pointers[n]??={event:r};let a,o,s=e.pointers[n];if(s.event=r,i){let t=i.getBoundingClientRect(),n=i.scrollWidth/e.width||1,s=i.scrollHeight/e.height||1;a=(r.clientX-t.left)/n,o=(r.clientY-t.top)/s,e._webgpu&&(a-=i.hw,o-=i.hh)}else a=r.clientX,o=r.clientY;s.x=a,s.y=o,!r.isPrimary&&r.pointerId||(document.pointerLockElement?(t.mouseX+=r.movementX,t.mouseY+=r.movementY):(t.mouseX=a,t.mouseY=o),t.moveX=r.movementX,t.moveY=r.movementY)};let a=0;function o(t){const r=e.canvas.getBoundingClientRect(),n=e.canvas.scrollWidth/e.width||1,i=e.canvas.scrollHeight/e.height||1;let a=0,o=0;return e._webgpu&&(a=e.halfWidth,o=e.halfHeight),{x:(t.clientX-r.left)/n-a,y:(t.clientY-r.top)/i-o,id:t.identifier}}if(e._onpointerdown=r=>{a++,e._startAudio(),e._updatePointer(r),t.mouseIsPressed=!0,t.mouseButton=n[r.button],e.mousePressed(r)},e._onpointermove=t=>{i&&!i.visible||(e._updatePointer(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t))},e._onpointerup=r=>{t.mouseIsPressed=!1,a>0&&(a--,e._updatePointer(r),delete e.pointers[r.pointerId],e.mouseReleased(r))},e._onclick=r=>{e._updatePointer(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e._ondblclick=r=>{e._updatePointer(r),t.mouseIsPressed=!0,e.doubleClicked(r),t.mouseIsPressed=!1},e._onwheel=t=>{e._updatePointer(t),t.delta=t.deltaY;let r=e.mouseWheel(t);(e._isGlobal&&!r||0==r)&&t.preventDefault()},e.cursor=(t,r,n)=>{let i="";t.includes(".")&&(t=`url("${t}")`,i=", auto"),void 0!==r&&(t+=" "+r+" "+n),e.canvas.style.cursor=t+i},e.noCursor=()=>e.canvas.style.cursor="none",e.pointerLock=(e=!1)=>{document.body?.requestPointerLock({unadjustedMovement:e})},e._onkeydown=n=>{n.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=n.key,t.keyCode=n.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(n),1==n.key.length&&e.keyTyped(n))},e._onkeyup=n=>{t.keyIsPressed=!1,t.key=n.key,t.keyCode=n.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(n)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._updateTouches=t=>{if(i&&!i.visible)return;let r=[...t.changedTouches].map(o);for(let t of r){let r=e.touches.find((e=>e.id==t.id));r?(r.x=t.x,r.y=t.y):e.touches.push(t)}for(let r=e.touches.length-1;r>=0;r--){let n=e.touches[r],i=!1;for(let e=0;e<t.touches.length;e++)if(t.touches[e].identifier===n.id){i=!0;break}i||e.touches.splice(r,1)}},e._ontouchstart=t=>{e._startAudio(),e.touchStarted(t)||t.preventDefault()},e._ontouchmove=t=>{e.touchMoved(t)||t.preventDefault()},e._ontouchend=t=>{e.touchEnded(t)||t.preventDefault()},window){let t=window.addEventListener;t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1);let r=window.PointerEvent?"pointer":"mouse";t(r+"move",(t=>e._onpointermove(t)),!1),t(r+"up",(t=>e._onpointerup(t))),t(r+"cancel",(t=>e._onpointerup(t))),t("touchstart",(t=>e._updateTouches(t))),t("touchmove",(t=>e._updateTouches(t))),t("touchend",(t=>e._updateTouches(t))),t("touchcancel",(t=>e._updateTouches(t))),i&&i.addEventListener("wheel",(t=>e._onwheel(t))),!e._isGlobal&&i&&(t=i.addEventListener.bind(i)),t(r+"down",(t=>e._onpointerdown(t))),t("click",(t=>e._onclick(t))),t("dblclick",(t=>e._ondblclick(t))),i&&(t=i.addEventListener.bind(i)),t("touchstart",(t=>e._ontouchstart(t))),t("touchmove",(t=>e._ontouchmove(t))),t("touchend",(t=>e._ontouchend(t))),t("touchcancel",(t=>e._ontouchend(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 n=e._DEGTORAD=Math.PI/180,i=e._RADTODEG=180/Math.PI;function a(){let e,t,r=4294967295;return{setSeed(n){e=t=(n??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,n,i,a)=>{let o=n+1*(e-t)/(r-t)*(i-n);return a?n<i?Math.min(Math.max(o,n),i):Math.min(Math.max(o,i),n):o},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,n)=>e.map(t,r,n,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*n:e),e.cos=e=>Math.cos(r?e*n:e),e.tan=e=>Math.tan(r?e*n: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 n=Math.atan2(e,t);return r?n*i:n};let o=a();o.setSeed(),e.randomSeed=e=>o.setSeed(e),e.random=(e,t)=>void 0===e?o.rand():"number"==typeof e?void 0!==t?o.rand()*(t-e)+e:o.rand()*e:e[Math.trunc(e.length*o.rand())],e.jit=(t=1)=>e.random(-t,t),e.randomGenerator=t=>{t==e.LCG?o=function(){const e=4294967296;let t,r;return{setSeed(n){r=t=(n??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(o=a()),o.setSeed()};var s=new function(){var e,t,r,n=new Array(128),i=new Array(256),a=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*o.rand()-2147483648,u=()=>.5+2.328306e-10*(c()|0),h=()=>{for(var t,i,o,l,d=3.44262;;){if(t=r*a[e],0==e){do{o=u(),l=u(),t=.2904764*-Math.log(o),i=-Math.log(l)}while(i+i<t*t);return r>0?d+t:-d-t}if(s[e]+u()*(s[e-1]-s[e])<Math.exp(-.5*t*t))return t;if(r=c(),e=127&r,Math.abs(r)<n[e])return r*a[e]}},f=()=>{for(var r;;){if(0==e)return 7.69711-Math.log(u());if(r=t*l[e],d[e]+u()*(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=u,this.RNOR=()=>(r=c(),e=127&r,Math.abs(r)<n[e]?r*a[e]:h()),this.REXP=()=>(t=c()>>>0)<n[e=255&t]?t*l[e]:f(),this.zigset=()=>{var e,t,r=2147483648,o=4294967296,c=3.442619855899,u=c,h=.00991256303526217,f=7.697117470131487,p=f,g=.003949659822581572;for(e=h/Math.exp(-.5*c*c),n[0]=Math.floor(c/e*r),n[1]=0,a[0]=e/r,a[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(h/c+Math.exp(-.5*c*c))),n[t+1]=Math.floor(c/u*r),u=c,s[t]=Math.exp(-.5*c*c),a[t]=c/r;for(e=g/Math.exp(-f),i[0]=Math.floor(f/e*o),i[1]=0,l[0]=e/o,l[255]=f/o,d[0]=1,d[255]=Math.exp(-f),t=254;t>=1;t--)f=-Math.log(g/f+Math.exp(-f)),i[t+1]=Math.floor(f/p*o),p=f,d[t]=Math.exp(-f),l[t]=f/o}};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,n=0)=>(l??=new e.NoiseGenerator,l.noise(t,r,n)),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,n=[];for(let e=0;e<256;e++)n[e]=e;for(let i=255;i>0;i--)t=(e=16807*e%2147483647)%(i+1),r=n[i],n[i]=n[t],n[t]=r;return n}dot(e,t,r,n){return e[0]*t+e[1]*r+e[2]*n}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 n=this,i=0,a=1,o=1,s=0;for(let l=0;l<n.octaves;l++){const l=255&Math.floor(e*a),d=255&Math.floor(t*a),c=255&Math.floor(r*a),u=e*a-Math.floor(e*a),h=t*a-Math.floor(t*a),f=r*a-Math.floor(r*a),p=n.fade(u),g=n.fade(h),m=n.fade(f),_=n.p[l]+d,x=n.p[_]+c,v=n.p[_+1]+c,b=n.p[l+1]+d,y=n.p[b]+c,w=n.p[b+1]+c,S=n.mix(n.dot(n.grad3[n.p[x]%12],u,h,f),n.dot(n.grad3[n.p[y]%12],u-1,h,f),p),C=n.mix(n.dot(n.grad3[n.p[v]%12],u,h-1,f),n.dot(n.grad3[n.p[w]%12],u-1,h-1,f),p),Q=n.mix(n.dot(n.grad3[n.p[x+1]%12],u,h,f-1),n.dot(n.grad3[n.p[y+1]%12],u-1,h,f-1),p),M=n.mix(n.dot(n.grad3[n.p[v+1]%12],u,h-1,f-1),n.dot(n.grad3[n.p[w+1]%12],u-1,h-1,f-1),p),P=n.mix(S,C,g),E=n.mix(Q,M,g);i+=n.mix(P,E,m)*o,s+=o,o*=n.falloff,a*=2}return(i/s+1)/2}},Q5.modules.record=(e,t)=>{let r,n,i,a,o,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',[n,a,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 h=d+'"avc1.640034"';e.canvas.width*e.canvas.height>32e5&&MediaRecorder.isTypeSupported(h)&&(r.formats["H.264"]=h),Object.assign(r.formats,t.formats),o=e.createSelect("format");for(const e in r.formats)o.option(e,r.formats[e]);o.title="Video Format",r.append(o);let g=e.createEl("div");g.className="bitrate",g.style.display="flex",r.append(g),s=e.createInput();let m=document.createElement("span");function _(){r.encoderSettings.mimeType=o.value}function x(){r.encoderSettings.videoBitsPerSecond=1e6*s.value}m.textContent="mbps",s.title=m.title="Video Bitrate",g.append(s),g.append(m),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={},o.addEventListener("change",_),s.addEventListener("change",x),Object.defineProperty(r,"bitrate",{get:()=>s.value,set:e=>{s.value=e,x()}}),Object.defineProperty(r,"format",{get:()=>o.selected,set:e=>{e=e.toUpperCase(),r.formats[e]&&(o.selected=e,_())}}),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,n.addEventListener("click",(()=>{e.recording?r.paused?u():e.pauseRecording():c()})),i.addEventListener("click",(()=>{r.paused?e.saveRecording():e.deleteRecording()})),f(),e.registerMethod("post",p)}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(),n=t.createMediaStreamDestination();t.destination.input?t.destination.input.connect(n):Q5.soundOut.connect(n),r.audioTrack=n.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(),f(!0)}}function u(){e.recording&&r.paused&&(r.mediaRecorder.resume(),r.paused=!1,f(!0))}function h(){e.recording&&(r.resetTimer(),r.mediaRecorder.stop(),t.recording=!1,r.paused=!1,r.classList.remove("recording"))}function f(e){n.textContent=e?"⏸":"⏺",n.title=(e?"Pause":"Start")+" Recording",i.textContent=e?"🗑️":"💾",i.title=(e?"Delete":"Save")+" Recording",i.disabled=!e}function p(){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)))}a.textContent=function(){let{hours:e,minutes:t,seconds:n,frames:i}=r.time;return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}:${String(n).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&&u():c()},e.pauseRecording=()=>{e.recording&&!r.paused&&(r.mediaRecorder.pause(),r.paused=!0,f(),n.title="Resume Recording",i.disabled=!1)},e.deleteRecording=()=>{h(),f(),t.recording=!1},e.saveRecording=async n=>{if(!e.recording)return;await new Promise((e=>{r.mediaRecorder.onstop=e,h()}));let i=r.encoderSettings.mimeType,a=i.slice(6,i.indexOf(";")),o=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=o,n??=document.title+" "+(new Date).toLocaleString(void 0,{hour12:!1}).replace(","," at").replaceAll("/","-").replaceAll(":","_"),l.download=`${n}.${a}`,await new Promise((e=>{s.onload=()=>{document.body.removeChild(s),e()},l.click()})),setTimeout((()=>URL.revokeObjectURL(o)),1e3),f(),t.recording=!1}},Q5.modules.sound=(e,t)=>{e.Sound=Q5.Sound;let r=[];e.loadSound=(t,n)=>{let i=new Q5.Sound;return r.push(i),i.promise=(async()=>{let e;i._usedAwait&&(r.splice(r.indexOf(i),1),i=new Q5.Sound,r.push(i));try{await i.load(t)}catch(t){e=t}if(delete i.then,e)throw e;return n&&n(i),i})(),e._loaders.push(i.promise),i.then=(e,t)=>(i._usedAwait=!0,i.promise.then(e,t)),i},e.loadAudio=(t,r)=>{let n=new Audio(t);return n._isAudio=!0,n.crossOrigin="Anonymous",n.promise=new Promise(((e,i)=>{function a(){n.loaded||(delete n.then,n._usedAwait&&(n=new Audio(t),n._isAudio=!0,n.crossOrigin="Anonymous"),n.loaded=!0,r&&r(n),e(n))}n.addEventListener("canplay",a),n.addEventListener("suspend",a),n.addEventListener("error",i)})),e._loaders.push(n.promise),n.then=(e,t)=>(n._usedAwait=!0,n.promise.then(e,t)),n},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 Q5.instances)e._userAudioStarted()}return Q5.aud.resume()}},e._userAudioStarted=()=>{for(let e of r)e.init()},e.outputVolume=e=>{Q5.soundOut&&(Q5.soundOut.gain.value=e)}},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._isSound=!0,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),Q5.aud&&this.init()}init(){this.buffer.length&&(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();return 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.promise=new Promise((e=>{r.onended=()=>{this.paused||(this.ended=!0,this._onended&&this._onended(),this.sources.delete(r),e())}})),r}play(e=0,t){if(!this.loaded)return;let r;if(this.paused){let e=[];for(let t of this.sources)e.push({offset:t._offset,duration:t._duration}),this.sources.delete(t);e.sort(((e,t)=>(e.duration??this.buffer.duration-e.offset)-(t.duration??this.buffer.duration-t.offset)));for(let t of e)r=this._newSource(t.offset,t.duration)}else r=this._newSource(e,t);return this.paused=this.ended=!1,r.promise}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}onended(e){this._onended=e}},Q5.modules.util=(e,t)=>{e._loadFile=(t,r,n)=>{let i={};return i.promise=fetch(t).then((e=>e.ok?"json"==n?e.json():e.text():(reject("error loading file"),null))).then((e=>("csv"==n&&(e=Q5.CSV.parse(e)),"string"==typeof e?i.text=e:Object.assign(i,e),delete i.then,r&&r(e),e))),e._loaders.push(i.promise),i.then=(e,t)=>i.promise.then(e,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"),e.loadXML=(t,r)=>{let n={};return n.promise=fetch(t).then((e=>e.text())).then((e=>{let t=(new DOMParser).parseFromString(e,"application/xml");return n.DOM=t,delete n.then,r&&r(t),t})),e._loaders.push(n.promise),n.then=(e,t)=>n.promise.then(e,t),n};const r=/(jpe?g|png|gif|webp|avif|svg)/i,n=/(ttf|otf|woff2?|eot|json)/i,i=/(serif|sans-serif|monospace|cursive|fantasy)/i,a=/(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/i;async function o(e,t,n){let i;if(t=t||"untitled",n=n||"png",r.test(n)){let t=e.canvas||e;i=await t.convertToBlob({type:"image/"+n})}else{let t="text/plain";"json"==n&&("string"!=typeof e&&(e=JSON.stringify(e)),t="text/json"),i=new Blob([e],{type:t})}let a=document.createElement("a");a.href=URL.createObjectURL(i),a.download=t+"."+n,a.click(),setTimeout((()=>URL.revokeObjectURL(a.href)),1e3)}e.load=function(...t){Array.isArray(t[0])&&(t=t[0]);let o=[];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):n.test(l)||i.test(s)?e.loadFont(s):a.test(l)?e.loadSound(s):"xml"==l?e.loadXML(s):e.loadText(s):e.loadJSON(s),o.push(t)}return 1==t.length?o[0]:Promise.all(o)},e.save=(t,r,n)=>{if((!t||"string"==typeof t&&(!r||!n&&r.length<5))&&(n=r,r=t,t=e),n)o(t,r,n);else if(r){let e=r.lastIndexOf(".");o(t,r.slice(0,e),r.slice(e+1))}else o(t)},e.canvas&&!Q5._createServerCanvas&&(e.canvas.save=e.saveCanvas=e.save),"object"==typeof localStorage&&(e.storeItem=(e,t)=>localStorage.setItem(e,t),e.getItem=e=>localStorage.getItem(e),e.removeItem=e=>localStorage.removeItem(e),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 n=e<0,i=(e=Math.abs(e)).toFixed(r).split(".");i[0]=i[0].padStart(t,"0");let a=i.join(".");return n&&(a="-"+a),a},e.shuffle=(t,r)=>{r||(t=[...t]);for(let r=t.length-1;r>0;r--){let n=Math.floor(e.random()*(r+1));[t[r],t[n]]=[t[n],t[r]]}return t}},Q5.CSV={},Q5.CSV.parse=(e,t=",",r="\n")=>{if(!e.length)return[];let n=[],i=e.split(r),a=i[0].split(t).map((e=>e.replaceAll('"',"")));for(let e=1;e<i.length;e++){let r={},o=i[e].split(t);a.forEach(((e,t)=>r[e]=JSON.parse(o[t]))),n.push(r)}return n},Q5.modules.vector=e=>{e.Vector=Q5.Vector,e.createVector=(t,r,n)=>new e.Vector(t,r,n,e)},Q5.Vector=class{constructor(e,t,r,n){this.x=e||0,this.y=t||0,this.z=r||0,this._isVector=!0,this._$=n||window,this._useCache=!1,this._mag=0,this._magCached=!1,this._direction=0,this._directionCached=!1}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}}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}_calcMag(){const e=this.x,t=this.y,r=this.z;this._mag=Math.sqrt(e*e+t*t+r*r),this._magCached=this._useCache}mag(){return this._magCached||this._calcMag(),this._mag}magSq(){if(this._magCached)return this._mag*this._mag;const e=this.x,t=this.y,r=this.z;return e*e+t*t+r*r}setMag(e){this._magCached||this._calcMag();let t=this._mag;if(0==t){const t=this.direction();this.x=e*this._$.cos(t),this.y=e*this._$.sin(t)}else{let r=e/t;this.x*=r,this.y*=r,this.z*=r}return this._mag=e,this._magCached=this._useCache,this}direction(){if(!this._directionCached){const e=this.x,t=this.y;(e||t)&&(this._direction=this._$.atan2(this.y,this.x)),this._directionCached=this._useCache}return this._direction}setDirection(e){let t=this.mag();return t&&(this.x=t*this._$.cos(e),this.y=t*this._$.sin(e)),this._direction=e,this._directionCached=this._useCache,this}heading(){return this.direction()}setHeading(e){return this.setDirection(e)}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,n=this.z-e.z;return Math.sqrt(t*t+r*r+n*n)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,n=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=n,this}normalize(){this._magCached||this._calcMag();let e=this._mag;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._mag=1,this._magCached=this._useCache,this}limit(e){this._magCached||this._calcMag();let t=this._mag;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._mag=e,this._magCached=this._useCache}return this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),n=this.x*t-this.y*r,i=this.x*r+this.y*t;return this.x=n,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 n=this.mag(),i=r.mag();if(0==n||0==i)return this.mult(1-t).add(r.mult(t));let a=Q5.Vector.cross(this,r),o=a.mag(),s=Math.atan2(o,this.dot(r));if(o>0)a.div(o);else{if(s<this._$.HALF_PI)return this.mult(1-t).add(r.mult(t));0==this.z&&0==r.z?a.set(0,0,1):0!=this.x?a.set(this.y,-this.x,0).normalize():a.set(1,0,0)}let l=a.cross(this),d=1-t+t*i/n,c=d*Math.cos(t*s),u=d*Math.sin(t*s);return this.x=this.x*c+l.x*u,this.y=this.y*c+l.y*u,this.z=this.z*c+l.z*u,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._mag=t,this._magCached=this._useCache,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._mag=r,this._magCached=this._useCache;const n=this._$.cos(t),i=this._$.sin(t),a=this._$.cos(e),o=this._$.sin(e);return this.x=r*o*i,this.y=-r*a,this.z=r*o*n,this}random2D(){return this._mag=1,this._magCached=this._useCache,this.fromAngle(Math.random()*Math.PI*2)}random3D(){return this._mag=1,this._magCached=this._useCache,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.direction=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)=>{const 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 n,i,a,o,s,l,d,c,u,h,f=2,p=12,g=0,m=0;e._pipelineConfigs=[],e._pipelines=[],e._buffers=[];let _=[],x=new Float32Array(1e6);x.set([0,0,0,0,0,0,0,1,1,1,1,1]);let v=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=[v];let b=Q5.device.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),y=()=>{let t=[e.canvas.width,e.canvas.height],r="bgra8unorm";a=Q5.device.createTexture({size:t,sampleCount:4,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}).createView();let n=GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT;e._frameA=s=Q5.device.createTexture({label:"frameA",size:t,format:r,usage:n}),e._frameB=o=Q5.device.createTexture({label:"frameB",size:t,format:r,usage: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]),u=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:d},{binding:2,resource:o.createView()}]}),h=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:d},{binding:2,resource:s.createView()}]})};e._createCanvas=(n,i,a)=>(t.ctx=t.drawingContext=r.getContext("webgpu"),a.format??=navigator.gpu.getPreferredCanvasFormat(),a.device??=Q5.device,a.alpha&&(a.alphaMode="premultiplied"),e.ctx.configure(a),y(),r),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r),y()};let w=!0,S="rgb",C=1;if(e.colorMode){let t=e.colorMode;e.colorMode=function(){t(...arguments),S=e._colorMode,w="rgb"==S,C=e._colorFormat}}const Q=(t,r,n,i)=>{if(!1===w||void 0===r&&!t._isColor&&"number"!=typeof t?!1!==w&&"string"!=typeof t&&Array.isArray(t)?[t,r,n,i]=t:t=e.color(t,r,n,i):void 0===n&&(i=r??C,r=n=t),i??=C,t._isColor){let e=t;w?({r:t,g:r,b:n,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,n]=e)}255===C&&(t/=255,r/=255,n/=255,i/=255);let a=x,o=p;a[o++]=t,a[o++]=r,a[o++]=n,a[o++]=i,p=o,f++};let M=!0,P=!0,E=!1,I=!1,R=1,A=2,T=2,k=1,O=1,G=.5,D=.25,L=.5;e.fill=(e,t,r,n)=>{Q(e,t,r,n),M=E=!0,A=f},e.stroke=(e,t,r,n)=>{Q(e,t,r,n),P=I=!0,R=f},e.tint=(e,t,r,n)=>{Q(e,t,r,n),T=f},e.opacity=e=>k=e,e.noFill=()=>M=!1,e.noStroke=()=>P=!1,e.noTint=()=>T=2,e.strokeWeight=e=>{if(void 0===e)return O;e?(e=Math.abs(e),O=e,G=e/2,D=e/4,L=G*W):P=!1},e._getStrokeWeight=()=>[O,G,D,L],e._setStrokeWeight=e=>{[O,G,D,L]=e},e._getFillIdx=()=>A,e._setFillIdx=e=>A=e,e._doFill=()=>M=!0,e._getStrokeIdx=()=>R,e._setStrokeIdx=e=>R=e,e._doStroke=()=>P=!0;const F=e._isGraphics?1e3:Q5.MAX_TRANSFORMS,B=16*F*4,z=new Float32Array(16*F);let U,N=[],V=[],H=0,q=!1;N.push([1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1]),z.set(N[0]),e.translate=(e,t)=>{if(!e&&!t)return;let r=U;r[12]+=e*r[0]+t*r[4],r[13]+=e*r[1]+t*r[5],q=!0},e.rotate=e.rotateZ=(t,r)=>{if(!t)return;let n,i;void 0===r?(e._angleMode&&(t*=e._DEGTORAD),n=Math.cos(t),i=Math.sin(t)):(n=t,i=r);let a=U,o=a[0],s=a[1],l=a[4],d=a[5];1!=o||s||l||1!=d?(a[0]=o*n+s*i,a[1]=s*n-o*i,a[4]=l*n+d*i,a[5]=d*n-l*i):(a[0]=n,a[1]=-i,a[4]=i,a[5]=n),q=!0};let W=1;e.scale=(e=1,t,r=1)=>{t??=e,W=Math.max(Math.abs(e),Math.abs(t)),L=G*W;let n=U;n[0]*=e,n[1]*=e,n[2]*=e,n[3]*=e,n[4]*=t,n[5]*=t,n[6]*=t,n[7]*=t,n[8]*=r,n[9]*=r,n[10]*=r,n[11]*=r,q=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),n=U,i=n[0],a=n[1],o=n[4],s=n[5];n[4]=o+i*r,n[5]=s+a*r,q=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),n=U,i=n[0],a=n[1],o=n[4],s=n[5];n[0]=i+o*r,n[1]=a+s*r,q=!0},e.applyMatrix=(...e)=>{let t;if(t=1==e.length?e[0]:e,t.length<=6){t=[t[0],t[1],0,t[2],t[3],0,t[4]||0,t[5]||0,1]}if(t.length<=9)t=[t[0],t[1],0,t[2],t[3],t[4],0,t[5],0,0,1,0,t[6],t[7],0,t[8]];else if(16!=t.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");U=t.slice(),q=!0};const j=()=>{z.set(U,16*N.length),H=N.length,N.push(U.slice()),q=!1};let $=[];e.pushMatrix=()=>{q&&j(),V.push(H),$.push(W)},e.popMatrix=()=>{if(!V.length)return console.warn("Matrix index stack is empty!");let e=V.pop();U=N[e].slice(),H=e,q=!1,W=$.pop(),L=G*W},e.resetMatrix=()=>{U=N[0].slice(),H=0,W=1,L=G},e.resetMatrix();let X=[];e.pushStyles=()=>{X.push([A,R,O,G,W,L,M,P,E,I,k,T,Et,It,Rt,mt,Be,Ke,w,S,C,e.Color])},e.popStyles=()=>{let t=X.pop();[A,R,O,G,W,L,M,P,E,I,k,T,Et,It,Rt,mt,Be,Ke,w,S,C]=t,e._colorFormat=C,e._colorMode=S,e.Color=t.at(-1)},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()};let Y=[0,0,0,0];const J=(e,t,r,n,i)=>{let a,o,s,l;if(i&&"corner"!=i)if("center"==i){let i=r/2,d=n/2;a=e-i,o=e+i,s=t-d,l=t+d}else a=e,o=r,s=t,l=n;else a=e,o=e+r,s=t,l=t+n;return Y[0]=a,Y[1]=o,Y[2]=s,Y[3]=l,Y};let K=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],Z=["add","subtract","reverse-subtract","min","max"];const ee={"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]};let te=Object.keys(ee);e.blendConfigs={};for(const[t,r]of Object.entries(ee))e.blendConfigs[t]={color:{srcFactor:K[r[0]],dstFactor:K[r[1]],operation:Z[r[2]]},alpha:{srcFactor:K[r[3]],dstFactor:K[r[4]],operation:Z[r[5]]}};let re,ne,ie,ae,oe,se,le,de,ce,ue,he="source-over";e.blendMode=e=>{if(e==he)return;he=e;let t=te.indexOf(e);-1!=t?_.push(0,t):console.error(`Blend mode "${e}" not supported in q5.js WebGPU.`)},e.clear=()=>{re=!0},e.background=(t,n,i,a)=>{if(t.canvas){e.push(),e.resetMatrix();let n=t;mt="corner",e.image(n,-r.hw,-r.hh,r.w,r.h),e.pop()}else{Q(t,n,i,a);let e=-r.hw,o=r.hw,s=-r.hh,l=r.hh;Pe(e,s,o,s,o,l,e,l,f,0)}},e._beginRender=()=>{const t=o;o=s,s=t;const r=u;u=h,h=r,n=Q5.device.createCommandEncoder(),e._pass=i=n.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:a,resolveTarget:o.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=h,re||(i.setPipeline(e._pipelines[g]),i.setBindGroup(0,c),i.draw(4)),re=!1},e._render=()=>{let t=16*N.length*4;(!ne||ne.size<t)&&(ne&&ne.destroy(),ne=Q5.device.createBuffer({size:Math.min(2*t,B),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(ne,0,z.subarray(0,16*N.length));let r=4*p;(!ie||ie.size<r)&&(ie&&ie.destroy(),ie=Q5.device.createBuffer({size:2*r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(ie,0,x.subarray(0,p)),e._uniforms[0]=e.width,e._uniforms[1]=e.height,e._uniforms[2]=e.halfWidth,e._uniforms[3]=e.halfHeight,e._uniforms[4]=e._pixelDensity,e._uniforms[5]=e.frameCount,e._uniforms[6]=performance.now(),e._uniforms[7]=e.deltaTime,e._uniforms[8]=e.mouseX,e._uniforms[9]=e.mouseY,e._uniforms[10]=e.mouseIsPressed?1:0,e._uniforms[11]=e.keyCode,e._uniforms[12]=e.keyIsPressed?1:0,Q5.device.queue.writeBuffer(b,0,e._uniforms),de&&ce===ne&&ue===ie||(de=Q5.device.createBindGroup({layout:v,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:{buffer:ne}},{binding:2,resource:{buffer:ie}}]}),ce=ne,ue=ie),i.setBindGroup(0,de),e._pass.setPipeline(e._pipelines[1]);let n=4*me;if((!ae||ae.size<n)&&(ae&&ae.destroy(),ae=Q5.device.createBuffer({size:2*n,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(ae,0,ge.subarray(0,me)),e._pass.setVertexBuffer(0,ae),ot){e._pass.setPipeline(e._pipelines[2]);let t=4*ot;(!oe||oe.size<t)&&(oe&&oe.destroy(),oe=Q5.device.createBuffer({size:2*t,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(oe,0,at.subarray(0,ot)),e._pass.setVertexBuffer(1,oe),pt&&(e._pass.setPipeline(e._pipelines[3]),e._pass.setVertexBuffer(1,oe))}if(Ft.length){let t=0;for(let e of Ft)Ut.set(e,t),t+=e.length;let r=4*t;(!se||se.size<r)&&(se&&se.destroy(),se=Q5.device.createBuffer({size:2*r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(se,0,Ut.buffer,0,r);let n=0;for(let e of Bt)Nt.set(e,n),n+=e.length;let i=4*n;(!le||le.size<i)&&(le&&le.destroy(),le=Q5.device.createBuffer({label:"textBuffer",size:2*i,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(le,0,Nt.buffer,0,i),e._textBindGroup=Q5.device.createBindGroup({label:"textBindGroup",layout:bt,entries:[{binding:0,resource:{buffer:se}},{binding:1,resource:{buffer:le}}]})}Q5.device.queue.writeBuffer(De,0,Oe.buffer,Oe.byteOffset,4*Ge),Q5.device.queue.writeBuffer(Xe,0,je.buffer,je.byteOffset,4*$e);let a=0,o=0,s=0,l=0,d=0,c=-1;for(let t=0;t<_.length;t+=2){let r=_[t+1];if(_[t]!=c){if(0==_[t]){let t=te[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}c=_[t],i.setPipeline(e._pipelines[c]),5==c?(i.setIndexBuffer(Ae,"uint16"),i.setBindGroup(1,Le)):6==c&&(i.setIndexBuffer(He,"uint16"),i.setBindGroup(1,Ye))}if(6==c)i.drawIndexed(18,r,0,0,d),d+=r;else if(5==c)i.drawIndexed(6,r,0,0,l),l+=r;else if(4==c||c>=4e3){let n=_[t+2];i.setBindGroup(1,Mt[n].bindGroup),i.setBindGroup(2,e._textBindGroup),i.draw(4,r,0,s),s+=r,t++}else 2==c||3==c||c>=2e3?(i.setBindGroup(1,e._textureBindGroups[r]),i.draw(4,1,o),o+=4):(i.draw(r,1,a),a+=r)}},e._finishRender=()=>{i.end(),i=n.beginRenderPass({colorAttachments:[{view:a,resolveTarget:e.ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=u,i.setPipeline(e._pipelines[m]),i.setBindGroup(0,c),i.draw(4),i.end(),Q5.device.queue.submit([n.finish()]),e._pass=i=n=null,_.length=0,f=2,p=12,N.length=1,V.length=0,e._texture=o,me=0,ot=0,pt>0&&(e._textureBindGroups.length=ft),pt=0,Ft.length=0,Bt.length=0,Ge=0,$e=0,Q5.device.queue.onSubmittedWorkDone().then((()=>{for(let t of e._buffers)t.destroy();e._buffers=[]}))};let fe=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 pe=Q5.device.createShaderModule({label:"shapesShader",code:e._shapesShaderCode}),ge=new Float32Array(e._isGraphics?1e3:1e7),me=0;const _e=2*Math.PI;Math.PI;let xe=Q5.device.createPipelineLayout({label:"shapesPipelineLayout",bindGroupLayouts:e._bindGroupLayouts});e._pipelineConfigs[1]={label:"shapesPipeline",layout:xe,vertex:{module:pe,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:pe,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 ve=(e,t,r,n)=>{let i=ge,a=me;i[a++]=e,i[a++]=t,i[a++]=r,i[a++]=n,me=a};let be="round",ye="round";e.strokeCap=e=>be=e,e.strokeJoin=e=>ye=e,e.lineMode=()=>{be="square",ye="none"};let we=20;e.curveDetail=e=>we=e;let Se,Ce=20;e.bezierDetail=e=>Ce=e;let Qe=[],Me=[];function Pe(e,t,r,n,i,a,o,s,l,d){ve(e,t,l,d),ve(r,n,l,d),ve(o,s,l,d),ve(i,a,l,d),_.push(fe,4)}e.beginShape=()=>{Se=0,Qe=[],Me=[]},e.vertex=(e,t)=>{q&&j(),Qe.push(e,t,A,H),Se++},e.curveVertex=(e,t)=>{q&&j(),Me.push({x:e,y:t})},e.bezierVertex=function(e,t,r,n,i,a){if(0===Se)throw new Error("Shape needs a vertex()");q&&j();let o,s,l=4*(Se-1),d=Qe[l],c=Qe[l+1],u=1/Ce,h=4==arguments.length;h&&(i=r,a=n);let f=1+u;for(let l=u;l<=f;l+=u){let u=l*l,f=1-l,p=f*f;if(h)o=p*d+2*f*l*e+u*i,s=p*c+2*f*l*t+u*a;else{let h=u*l,g=p*f;o=g*d+3*p*l*e+3*f*u*r+h*i,s=g*c+3*p*l*t+3*f*u*n+h*a}Qe.push(o,s,A,H),Se++}},e.quadraticVertex=(t,r,n,i)=>e.bezierVertex(t,r,n,i),e.endShape=t=>{if(Me.length>0){let e=[...Me];if(e.length<4)for(;e.length<4;)e.unshift(e[0]),e.push(e[e.length-1]);let t=1/we;for(let r=0;r<e.length-3;r++){let n=e[r],i=e[r+1],a=e[r+2],o=e[r+3];for(let e=0;e<=1;e+=t){let t=e*e,r=t*e,s=.5*(2*i.x+(-n.x+a.x)*e+(2*n.x-5*i.x+4*a.x-o.x)*t+(-n.x+3*i.x-3*a.x+o.x)*r),l=.5*(2*i.y+(-n.y+a.y)*e+(2*n.y-5*i.y+4*a.y-o.y)*t+(-n.y+3*i.y-3*a.y+o.y)*r);Qe.push(s,l,A,H),Se++}}}if(Se){if(1==Se)return e.point(Qe[0],Qe[1]);if(2==Se)return e.line(Qe[0],Qe[1],Qe[4],Qe[5]);if(t){let e=0,t=4*(Se-1),r=Qe[e],n=Qe[e+1],i=Qe[t],a=Qe[t+1];r===i&&n===a||(Qe.push(r,n,Qe[e+2],Qe[e+3]),Se++)}if(M)if(5==Se)ve(Qe[0],Qe[1],Qe[2],Qe[3]),ve(Qe[4],Qe[5],Qe[6],Qe[7]),ve(Qe[12],Qe[13],Qe[14],Qe[15]),ve(Qe[8],Qe[9],Qe[10],Qe[11]),_.push(fe,4);else{for(let e=1;e<Se-1;e++){let t=0,r=4*e,n=4*(e+1);ve(Qe[t],Qe[t+1],Qe[t+2],Qe[t+3]),ve(Qe[r],Qe[r+1],Qe[r+2],Qe[r+3]),ve(Qe[n],Qe[n+1],Qe[n+2],Qe[n+3])}_.push(fe,3*(Se-2))}if(P){for(let t=0;t<Se-1;t++){let r=4*t,n=4*(t+1);e.line(Qe[r],Qe[r+1],Qe[n],Qe[n+1])}let r=4*(Se-1),n=0;t&&e.line(Qe[r],Qe[r+1],Qe[n],Qe[n+1])}Se=0,Qe=[],Me=[]}},e.curve=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(n,i),e.curveVertex(a,o),e.curveVertex(s,l),e.endShape()},e.bezier=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(n,i,a,o,s,l),e.endShape()},e.triangle=(t,r,n,i,a,o)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.endShape(!0)},e.quad=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.vertex(s,l),e.endShape(!0)},e.plane=(e,t,r,n)=>{n??=r;let[i,a,o,s]=J(e,t,r,n,"center");q&&j(),Pe(i,o,a,o,a,s,i,s,A,H)};let Ee=5;e._rectShaderCode=e._baseShaderCode+"\nstruct Rect {\n\tcenter: vec2f,\n\textents: vec2f,\n\troundedRadius: f32,\n\tstrokeWeight: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tmatrixIndex: f32,\n\tpadding0: f32, // can't use vec3f for alignment\n\tpadding1: vec2f,\n\tpadding2: vec4f\n};\n\nstruct VertexParams {\n\t@builtin(vertex_index) vertIndex: u32,\n\t@builtin(instance_index) instIndex: u32\n};\n\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) local: vec2f,\n\t@location(1) extents: vec2f,\n\t@location(2) roundedRadius: f32,\n\t@location(3) strokeWeight: f32,\n\t@location(4) fill: vec4f,\n\t@location(5) stroke: vec4f,\n\t@location(6) blend: 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\n@group(1) @binding(0) var<storage, read> rects: array<Rect>;\n\nconst quad = array(\n\tvec2f(-1.0, -1.0),\n\tvec2f( 1.0, -1.0),\n\tvec2f(-1.0, 1.0),\n\tvec2f( 1.0, 1.0)\n);\nconst transparent = vec4f(0.0);\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\tlet rect = rects[v.instIndex];\n\n\tlet halfStrokeSize = vec2f(rect.strokeWeight * 0.5);\n\tlet quadSize = rect.extents + halfStrokeSize;\n\tlet pos = (quad[v.vertIndex] * quadSize) + rect.center;\n\n\tlet local = pos - rect.center;\n\n\tvar f: FragParams;\n\tf.position = transformVertex(pos, rect.matrixIndex);\n\n\tf.local = local;\n\tf.extents = rect.extents;\n\tf.roundedRadius = rect.roundedRadius;\n\tf.strokeWeight = rect.strokeWeight;\n\n\tlet fill = colors[i32(rect.fillIndex)];\n\tlet stroke = colors[i32(rect.strokeIndex)];\n\tf.fill = fill;\n\tf.stroke = stroke;\n\n\t// Source-over blend: stroke over fill (pre-multiplied alpha)\n\tif (fill.a != 0.0 && stroke.a != 1.0) {\n\t\tlet outAlpha = stroke.a + fill.a * (1.0 - stroke.a);\n\t\tlet outColor = stroke.rgb * stroke.a + fill.rgb * fill.a * (1.0 - stroke.a);\n\t\tf.blend = vec4f(outColor / max(outAlpha, 1e-5), outAlpha);\n\t}\n\treturn f;\n}\n\nfn sdRoundRect(p: vec2f, extents: vec2f, radius: f32) -> f32 {\n\tlet q = abs(p) - extents + vec2f(radius);\n\treturn length(max(q, vec2f(0.0))) - radius + min(max(q.x, q.y), 0.0);\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tlet dist = select(\n\t\tmax(abs(f.local.x) - f.extents.x, abs(f.local.y) - f.extents.y), // sharp\n\t\tsdRoundRect(f.local, f.extents, f.roundedRadius), // rounded\n\t\tf.roundedRadius > 0.0\n\t);\n\n\t// fill only\n\tif (f.fill.a != 0.0 && f.strokeWeight == 0.0) {\n\t\tif (dist <= 0.0) {\n\t\t\treturn f.fill;\n\t\t}\n\t\treturn transparent;\n\t}\n\n\tlet halfStroke = f.strokeWeight * 0.5;\n\tlet inner = dist + halfStroke;\n\n\tif (f.fill.a != 0.0) {\n\t\tif (inner <= 0.0) {\n\t\t\treturn f.fill;\n\t\t}\n\t\tif (dist <= 0.0 && f.stroke.a != 1.0) {\n\t\t\treturn f.blend;\n\t\t}\n\t}\n\n\tlet outer = dist - halfStroke;\n\n\tif (outer <= 0.0 && inner >= 0.0) {\n\t\treturn f.stroke;\n\t}\n\n\treturn transparent;\n}\n\t";let Ie=Q5.device.createShaderModule({label:"rectShader",code:e._rectShaderCode}),Re=new Uint16Array([0,1,2,2,1,3]),Ae=Q5.device.createBuffer({size:Re.byteLength,usage:GPUBufferUsage.INDEX,mappedAtCreation:!0});new Uint16Array(Ae.getMappedRange()).set(Re),Ae.unmap();let Te=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),ke=Q5.device.createPipelineLayout({label:"rectPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,Te]});e._pipelineConfigs[5]={label:"rectPipeline",layout:ke,vertex:{module:Ie,entryPoint:"vertexMain",buffers:[]},fragment:{module:Ie,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-list"},multisample:{count:4}},e._pipelines[5]=Q5.device.createRenderPipeline(e._pipelineConfigs[5]);let Oe=new Float32Array(16*Q5.MAX_RECTS),Ge=0,De=Q5.device.createBuffer({size:Oe.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Le=Q5.device.createBindGroup({layout:Te,entries:[{binding:0,resource:{buffer:De}}]});function Fe(e,t,r,n,i,a,o){let s=Oe,l=Ge;s[l]=e,s[l+1]=t,s[l+2]=r,s[l+3]=n,s[l+4]=i,s[l+5]=a,s[l+6]=o,s[l+7]=R,s[l+8]=H,Ge+=16,_.push(Ee,1)}let Be="corner";e.rectMode=e=>Be=e,e._getRectMode=()=>Be;let ze=[0,0,0,0];function Ue(t,r,n,i,a,o,s){let l=n-t,d=i-r,c=Math.hypot(l,d);if(0===c)return;let u=Math.atan2(d,l),h=(t+n)/2,f=(r+i)/2;e._angleMode&&(u*=e._RADTODEG),e.pushMatrix(),e.translate(h,f),e.rotate(u),q&&j(),Fe(0,0,c/2+a,a,a,o,s),e.popMatrix()}e.rect=(e,t,r,n,i=0)=>{let a,o;q&&j(),[e,t,a,o]=function(e,t,r,n){let i=r/2,a=n/2;return"center"!=Be&&("corner"==Be?(e+=i,t+=a,i=Math.abs(i),a=Math.abs(a)):"radius"==Be?(i=r,a=n):"corners"==Be&&(i=Math.abs((r-e)/2),a=Math.abs((n-t)/2),e=(e+r)/2,t=(t+n)/2)),ze[0]=e,ze[1]=t,ze[2]=i,ze[3]=a,ze}(e,t,r,n),Fe(e,t,a,o,i,P?O:0,M?A:0)},e.square=(t,r,n,i)=>e.rect(t,r,n,n,i),e.capsule=(e,t,r,n,i)=>{Ue(e,t,r,n,i,P?O:0,M?A:0)},e.line=(e,t,r,n)=>{P&&Ue(e,t,r,n,D,G,0)};e._ellipseShaderCode=e._baseShaderCode+"\nstruct Ellipse {\n\tcenter: vec2f,\n\tsize: vec2f,\n\tstartAngle: f32,\n\tendAngle: f32,\n\tstrokeWeight: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tmatrixIndex: f32,\n\tpadding0: vec2f,\n\tpadding1: vec4f\n};\n\nstruct VertexParams {\n\t@builtin(vertex_index) vertIndex: u32,\n\t@builtin(instance_index) instIndex: u32\n};\n\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) outerEdge: vec2f,\n\t@location(1) fillEdge: vec2f,\n\t@location(2) innerEdge: vec2f,\n\t@location(3) strokeWeight: f32,\n\t@location(4) fill: vec4f,\n\t@location(5) stroke: vec4f,\n\t@location(6) blend: 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\n@group(1) @binding(0) var<storage, read> ellipses: array<Ellipse>;\n\nconst PI = 3.141592653589793;\nconst segments = 6.0;\nconst expansion = 1.0 / cos(PI / segments);\nconst antiAlias = 0.015625; // 1/64\nconst transparent = vec4f(0.0);\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\tlet ellipse = ellipses[v.instIndex];\n\tvar pos = ellipse.center;\n\tvar local = vec2f(0.0);\n\tlet start = ellipse.startAngle;\n\tlet end = ellipse.endAngle;\n\tlet arc = end - start;\n\tlet halfStrokeSize = vec2f(ellipse.strokeWeight * 0.5);\n\n\tlet fanSize = (ellipse.size + halfStrokeSize) * expansion;\n\n\tif (v.vertIndex != 0) {\n\t\tlet theta = start + (f32(v.vertIndex - 1) / segments) * arc;\n\t\tlocal = vec2f(cos(theta), sin(theta));\n\t\tpos = ellipse.center + local * fanSize;\n\t}\n\n\tlet dist = pos - ellipse.center;\n\n\tvar f: FragParams;\n\tf.position = transformVertex(pos, ellipse.matrixIndex);\n\tf.outerEdge = dist / (ellipse.size + halfStrokeSize);\n\tf.fillEdge = dist / ellipse.size;\n\tf.innerEdge = dist / (ellipse.size - halfStrokeSize);\n\tf.strokeWeight = ellipse.strokeWeight;\n\n\tlet fill = colors[i32(ellipse.fillIndex)];\n\tlet stroke = colors[i32(ellipse.strokeIndex)];\n\tf.fill = fill;\n\tf.stroke = stroke;\n\n\t// Source-over blend: stroke over fill (pre-multiplied alpha)\n\tif (fill.a != 0.0 && stroke.a != 1.0) {\n\t\tlet outAlpha = stroke.a + fill.a * (1.0 - stroke.a);\n\t\tlet outColor = stroke.rgb * stroke.a + fill.rgb * fill.a * (1.0 - stroke.a);\n\t\tf.blend = vec4f(outColor / max(outAlpha, 1e-5), outAlpha);\n\t}\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tlet fillEdge = length(f.fillEdge);\n\n\t// disable AA for very thin strokes\n\tlet aa = select(antiAlias, 0.0, f.strokeWeight <= 1.0);\n\n\tif (f.fill.a != 0.0 && f.strokeWeight == 0.0) {\n\t\tif (fillEdge > 1.0) {\n\t\t\treturn transparent;\n\t\t}\n\t\tlet fillAlpha = 1.0 - smoothstep(1.0 - aa, 1.0, fillEdge);\n\t\treturn vec4f(f.fill.rgb, f.fill.a * fillAlpha);\n\t}\n\n\tlet innerEdge = length(f.innerEdge);\n\t\n\tif (f.fill.a != 0.0 && fillEdge < 1.0) {\n\t\tif (innerEdge < 1.0) {\n\t\t\treturn f.fill;\n\t\t}\n\t\tlet tInner = smoothstep(1.0, 1.0 + aa, innerEdge);\n\t\tlet tOuter = smoothstep(1.0 - aa, 1.0, fillEdge);\n\t\tif (f.stroke.a != 1.0) {\n\t\t\tlet fillBlend = mix(f.fill, f.blend, tInner);\n\t\t\treturn mix(fillBlend, f.stroke, tOuter);\n\t\t} else {\n\t\t\tlet fillBlend = mix(f.fill, f.stroke, tInner);\n\t\t\treturn mix(fillBlend, f.stroke, tOuter);\n\t\t}\n\t}\n\t\n\tif (innerEdge < 1.0) {\n\t\treturn transparent;\n\t}\n\n\tlet outerEdge = length(f.outerEdge);\n\tlet outerAlpha = 1.0 - smoothstep(1.0 - aa, 1.0, outerEdge);\n\tlet innerAlpha = smoothstep(1.0, 1.0 + aa, innerEdge);\n\tlet strokeAlpha = innerAlpha * outerAlpha;\n\treturn vec4f(f.stroke.rgb, f.stroke.a * strokeAlpha);\n}\n\t\t";let Ne=Q5.device.createShaderModule({label:"ellipseShader",code:e._ellipseShaderCode}),Ve=new Uint16Array([0,1,2,0,2,3,0,3,4,0,4,5,0,5,6,0,6,7]),He=Q5.device.createBuffer({size:Ve.byteLength,usage:GPUBufferUsage.INDEX,mappedAtCreation:!0});new Uint16Array(He.getMappedRange()).set(Ve),He.unmap();let qe=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),We=Q5.device.createPipelineLayout({label:"ellipsePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,qe]});e._pipelineConfigs[6]={label:"ellipsePipeline",layout:We,vertex:{module:Ne,entryPoint:"vertexMain",buffers:[]},fragment:{module:Ne,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-list"},multisample:{count:4}},e._pipelines[6]=Q5.device.createRenderPipeline(e._pipelineConfigs[6]);let je=new Float32Array(16*Q5.MAX_ELLIPSES),$e=0,Xe=Q5.device.createBuffer({size:je.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Ye=Q5.device.createBindGroup({layout:qe,entries:[{binding:0,resource:{buffer:Xe}}]});function Je(e,t,r,n,i,a,o,s){let l=je,d=$e;l[d]=e,l[d+1]=t,l[d+2]=r,l[d+3]=n,l[d+4]=i,l[d+5]=a,l[d+6]=o,l[d+7]=s?A:0,l[d+8]=R,l[d+9]=H,$e+=16,_.push(6,1)}let Ke="center";e.ellipseMode=e=>Ke=e,e._getEllipseMode=()=>Ke;let Ze=[0,0,0,0];function et(e,t,r,n){let i,a;return n??=r,"center"==Ke?(i=r/2,a=n/2):"radius"==Ke?(i=r,a=n):"corner"==Ke?(e+=r/2,t+=n/2,i=r/2,a=n/2):"corners"==Ke&&(i=r-(e=(e+r)/2),a=n-(t=(t+n)/2)),Ze[0]=e,Ze[1]=t,Ze[2]=i,Ze[3]=a,Ze}e.ellipse=(e,t,r,n)=>{let i,a;[e,t,i,a]=et(e,t,r,n),q&&j(),Je(e,t,i,a,0,_e,P?O:0,M)},e.circle=(t,r,n)=>e.ellipse(t,r,n,n),e.arc=(t,r,n,i,a,o)=>{if(a===o)return e.ellipse(t,r,n,i);if(e._angleMode&&(a=e.radians(a),o=e.radians(o)),(a%=_e)<0&&(a+=_e),(o%=_e)<0&&(o+=_e),a>o&&(o+=_e),a==o)return e.ellipse(t,r,n,i);let s,l;[t,r,s,l]=et(t,r,n,i),q&&j(),Je(t,r,s,l,a,o,P?O:0,M)},e.point=(e,t)=>{q&&j(),L<=.5?Fe(e,t,G,G,0,O,0):Je(e,t,G,G,0,_e,O,0)};let tt=2,rt=3;e._imageShaderCode=e._baseShaderCode+"\n\tstruct VertexParams {\n\t\t@builtin(vertex_index) vertexIndex : u32,\n\t\t@location(0) pos: vec2f,\n\t\t@location(1) texCoord: vec2f,\n\t\t@location(2) tintIndex: f32,\n\t\t@location(3) matrixIndex: f32,\n\t\t@location(4) imageAlpha: f32\n\t}\n\tstruct FragParams {\n\t\t@builtin(position) position: vec4f,\n\t\t@location(0) texCoord: vec2f,\n\t\t@location(1) tintColor: vec4f,\n\t\t@location(2) imageAlpha: f32\n\t}\n\t\n\t@group(0) @binding(0) var<uniform> q: Q5;\n\t@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n\t@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\t\n\t@group(1) @binding(0) var samp: sampler;\n\t@group(1) @binding(1) var tex: texture_2d<f32>;\n\t\n\tfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\t\tvar vert = vec4f(pos, 0f, 1f);\n\t\tvert = transforms[i32(matrixIndex)] * vert;\n\t\tvert.x /= q.halfWidth;\n\t\tvert.y /= q.halfHeight;\n\t\treturn vert;\n\t}\n\t\n\tfn applyTint(texColor: vec4f, tintColor: vec4f) -> vec4f {\n\t\t// apply the tint color to the sampled texture color at full strength\n\t\tlet tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a);\n\t\t// mix in the tint using the tint alpha as the blend strength\n\t\treturn mix(texColor, tinted, tintColor.a);\n\t}\n\t\n\t@vertex\n\tfn vertexMain(v: VertexParams) -> FragParams {\n\t\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\t\n\t\tvar f: FragParams;\n\t\tf.position = vert;\n\t\tf.texCoord = v.texCoord;\n\t\tf.tintColor = colors[i32(v.tintIndex)];\n\t\tf.imageAlpha = v.imageAlpha;\n\t\treturn f;\n\t}\n\t\n\t@fragment\n\tfn fragMain(f: FragParams) -> @location(0) vec4f {\n\t\tvar texColor = textureSample(tex, samp, f.texCoord);\n\t\ttexColor.a *= f.imageAlpha;\n\t\treturn applyTint(texColor, f.tintColor);\n\t}\n\t";let nt=Q5.device.createShaderModule({label:"imageShader",code:e._imageShaderCode});e._videoShaderCode=e._imageShaderCode.replace("texture_2d<f32>","texture_external").replace("textureSample","textureSampleBaseClampToEdge");let it=Q5.device.createShaderModule({label:"videoShader",code:e._videoShaderCode}),at=new Float32Array(e._isGraphics?1e3:1e7),ot=0,st={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"}]},lt=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]}),dt=Q5.device.createBindGroupLayout({label:"videoTextureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,externalTexture:{}}]}),ct=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,lt]}),ut=Q5.device.createPipelineLayout({label:"videoPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,dt]});e._pipelineConfigs[2]={label:"imagePipeline",layout:ct,vertex:{module:nt,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},st]},fragment:{module:nt,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:ut,vertex:{module:it,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},st]},fragment:{module:it,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=[],r&&(r.convertToBlob=async t=>{let r=e._drawStack?.length;r&&(e._render(),e._finishRender());let n=e._texture;r&&e._beginRender();let i=n.width,a=n.height,o=256*Math.ceil(4*i/256),s=Q5.device.createBuffer({size:o*a,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),l=Q5.device.createCommandEncoder();l.copyTextureToBuffer({texture:n},{buffer:s,bytesPerRow:o,rowsPerImage:a},{width:i,height:a}),Q5.device.queue.submit([l.finish()]),await s.mapAsync(GPUMapMode.READ);let d=new Uint8Array(s.getMappedRange()),c=new Uint8Array(i*a*4);for(let e=0;e<a;e++){const t=e*o,r=e*i*4;for(let e=0;e<i;e++){const n=t+4*e,i=r+4*e;c[i+0]=d[n+2],c[i+1]=d[n+1],c[i+2]=d[n+0],c[i+3]=d[n+3]}}s.unmap();let u=e.canvas.colorSpace;c=new Uint8ClampedArray(c.buffer),c=new ImageData(c,i,a,{colorSpace:u});let h=new OffscreenCanvas(i,a);return h.getContext("2d",{colorSpace:u}).putImageData(c,0,0),e._buffers.push(s),await h.convertToBlob(t)});let ht=t=>{e._imageSampler=Q5.device.createSampler({magFilter:t,minFilter:t})};e.smooth=()=>ht("linear"),e.noSmooth=()=>ht("nearest"),e.smooth();let ft=0,pt=0;e._addTexture=(t,r)=>{let n=t.canvas||t;if(!r){if(t._texture)return;let i=[n.width,n.height,1];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:n},{texture:r,colorSpace:e.canvas.colorSpace},i)}r.index=ft+pt,t._texture=r,e._textureBindGroups[r.index]=Q5.device.createBindGroup({label:t.src||r.label||"canvas",layout:lt,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r.createView()}]}),ft++},e.loadImage=(t,r)=>e._g.loadImage(t,(t=>{e._makeDrawable(t),r&&r(t)})),e._makeDrawable=t=>{e._addTexture(t),t._owner=e},e.createImage=(t,r,n)=>{let i=e._g.createImage(t,r,n);return e._makeDrawable(i),i.modified=!0,i};let gt=e.createGraphics;e.createGraphics=(t,r,n={})=>{if(!Q5.experimental)throw new Error("createGraphics is disabled by default in q5 WebGPU. See issue https://github.com/q5js/q5.js/issues/104 for details.");"string"==typeof n&&(n={renderer:n}),n.renderer??="c2d";let i=gt(t,r,n);return i.canvas.webgpu?(e._addTexture(i,i._frameA),e._addTexture(i,i._frameB),i._beginRender()):(e._makeDrawable(i),i.modified=!0),i};let mt="corner";e.imageMode=e=>mt=e,e._getImageMode=()=>mt,e._uniforms=new Float32Array(13);const _t=(e,t,r,n,i,a,o)=>{let s=at,l=ot;s[l++]=e,s[l++]=t,s[l++]=r,s[l++]=n,s[l++]=i,s[l++]=a,s[l++]=o,ot=l};e.image=(t,r=0,n=0,i,a,o=0,s=0,l,d)=>{if(!t)return;let c;if(null==t._texture){if(c="VIDEO"==t.tagName,!t.width||c&&!t.currentTime)return;t.flipped&&e.scale(-1,1)}q&&j();let u=t.canvas||t,h=u.width,f=u.height,p=t._pixelDensity||1,g=t._isGraphics&&t._drawStack?.length;g&&(t._render(),t._finishRender()),t.modified&&(Q5.device.queue.copyExternalImageToTexture({source:u},{texture:t._texture,colorSpace:e.canvas.colorSpace},[h,f,1]),t.frameCount++,t.modified=!1),i??=t.defaultWidth||t.videoWidth,a??=t.defaultHeight||t.videoHeight,l??=h,d??=f,o*=p,s*=p;let[m,x,v,b]=J(r,n,i,a,mt),y=o/h,w=s/f,S=(o+l)/h,C=(s+d)/f,Q=H,M=T,P=k;if(_t(m,v,y,w,M,Q,P),_t(x,v,S,w,M,Q,P),_t(m,b,y,C,M,Q,P),_t(x,b,S,C,M,Q,P),c){let r=Q5.device.importExternalTexture({source:t});e._textureBindGroups.push(Q5.device.createBindGroup({layout:dt,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r}]})),_.push(rt,e._textureBindGroups.length-1),t.flipped&&e.scale(-1,1)}else _.push(tt,t._texture.index),g&&(t.resetMatrix(),t._beginRender(),t.frameCount++)};let xt=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 vt=Q5.device.createShaderModule({label:"textShader",code:e._textShaderCode}),bt=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"}}]}),yt=Q5.device.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:16}),wt=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"}}]}),St=Q5.device.createPipelineLayout({bindGroupLayouts:[...e._bindGroupLayouts,wt,bt]});e._pipelineConfigs[4]={label:"textPipeline",layout:St,vertex:{module:vt,entryPoint:"vertexMain"},fragment:{module:vt,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 Ct{constructor(e,t,r,n){this.bindGroup=e,this.lineHeight=t,this.chars=r,this.kernings=n;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 n=this.kernings.get(e);if(n)return r.xadvance+(n.get(t)??0)}return r.xadvance}}let Qt,Mt=[],Pt={};e.loadFont=(t="sans-serif",r)=>{if(Qt=!0,t.startsWith("https://fonts.googleapis.com/css"))return e._g.loadFont(t,r);let n=t.slice(t.lastIndexOf(".")+1);if(t==n){let e=t;Pt[e]=null,t=`https://q5js.org/fonts/${e}-msdf.json`,0!=Q5.online&&navigator.onLine||(t=`/node_modules/q5/builtinFonts/${e}-msdf.json`),n="json"}if("json"!=n)return e._g.loadFont(t,r);let i=t.slice(t.lastIndexOf("/")+1,t.lastIndexOf("-")),a={family:i};return a.promise=async function(t,r,n){let i,a,o=t.substring(0,t.lastIndexOf("-"));try{[i,a]=await Promise.all([fetch(t).then((e=>{if(404==e.status)throw new Error("404");return e.json()})),fetch(o+".png").then((e=>e.blob())).then((e=>createImageBitmap(e)))])}catch(e){return console.error("Error loading font:",e),""}let s=[a.width,a.height,1],l=Q5.device.createTexture({label:`MSDF ${r}`,size:s,format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:a},{texture:l},s),"string"==typeof i.chars&&(i.chars=Q5.CSV.parse(i.chars," "),i.kernings=Q5.CSV.parse(i.kernings," "));let d=i.chars.length,c=Q5.device.createBuffer({size:32*d,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),u=new Float32Array(c.getMappedRange()),h=1/i.common.scaleW,f=1/i.common.scaleH,p={},g=0;for(let[e,t]of i.chars.entries())p[t.id]=t,p[t.id].charIndex=e,u[g]=t.x*h,u[g+1]=t.y*f,u[g+2]=t.width*h,u[g+3]=t.height*f,u[g+4]=t.width,u[g+5]=t.height,u[g+6]=t.xoffset,u[g+7]=t.yoffset,g+=8;c.unmap();let m=Q5.device.createBindGroup({label:"fontBindGroup",layout:wt,entries:[{binding:0,resource:l.createView()},{binding:1,resource:yt},{binding:2,resource:{buffer:c}}]}),_=new Map;if(i.kernings)for(let e of i.kernings){let t=_.get(e.first);t||(t=new Map,_.set(e.first,t)),t.set(e.second,e.amount)}let x=new Ct(m,i.common.lineHeight,p,_);return x.index=Mt.length,Mt.push(x),Pt[r]=x,e._font=x,n&&n(r),{family:r}}(t,i,(()=>{delete a.then,a._usedAwait&&(a={family:i}),r&&r(a)})),e._loaders.push(a.promise),a.then=(e,t)=>(a._usedAwait=!0,a.promise.then(e,t)),a};let Et=18,It="left",Rt="alphabetic",At=!1,Tt=22.5,kt=4.5,Ot=1.25,Gt=["serif","sans-serif","monospace","cursive","fantasy","system-ui"];e.textFont=t=>{if(!t)return e._font;Qt=!0,"string"!=typeof t&&(t=t.family);let r=Pt[t];r?e._font=r:(Gt[t]||void 0===r)&&e._g.textFont(t)},e.textSize=t=>{if(e._font||e._g.textSize(t),null==t)return Et;Et=t,At||(Tt=t*Ot,kt=Tt-t)};let Dt={thin:100,extralight:200,light:300,normal:400,regular:400,medium:500,semibold:600,bold:700,bolder:800,extrabold:800,black:900,heavy:900},Lt=.5;e.textWeight=t=>{if(!t)return e._textWeight;if("string"==typeof t&&!(t=Dt[t.toLowerCase().replace(/[ _-]/g,"")]))throw new Error(`Invalid font weight: ${t}`);Lt=.6875-375e-6*t},e.textLeading=t=>e._font?t?(e._font.lineHeight=Tt=t,kt=Tt-Et,Ot=Tt/Et,void(At=!0)):Tt:e._g.textLeading(t),e.textAlign=(e,t)=>{It=e,t&&(Rt=t)},e.textStyle=e=>{};let Ft=[],Bt=[],zt=new Array(100),Ut=new Float32Array(4*Q5.MAX_CHARS),Nt=new Float32Array(8*Q5.MAX_TEXTS),Vt=(e,t,r)=>{let n=0,i=0,a=0,o=0,s=0,l=zt,d=t.charCodeAt(0);for(let c=0;c<t.length;++c){let u=d;switch(d=c<t.length-1?t.charCodeAt(c+1):-1,u){case 10:l.push(i),o++,n=Math.max(n,i),i=0,a-=e.lineHeight*Ot;break;case 13:break;case 32:i+=e.getXAdvance(u);break;case 9:i+=2*e.getXAdvance(u);break;default:r&&r(i,a,o,e.getChar(u)),i+=e.getXAdvance(u,d),s++}}l[o]=i,n=Math.max(n,i);let c=o+1;return{width:n,height:c*e.lineHeight*Ot,lineWidths:l,lineCount:c,printedCharCount:s}};e.text=(t,r,n,i,a)=>{if(Et<1)return;let o,s=typeof t;if("string"!=s)"object"==s?t=t.toString():t+="";else if(!t.length)return;if(!e._font){Qt||e.loadFont();let o=e.createTextImage(t,i,a);return e.textImage(o,r,n)}if(t.length>i){let e=[],r=0;for(;r<t.length&&e.length<a;){let n=r+i;if(n>=t.length){e.push(t.slice(r));break}let a=t.lastIndexOf(" ",n);(-1==a||a<r)&&(a=n),e.push(t.slice(r,a)),r=a+1}t=e.join("\n"),o=!0}o??=t.includes("\n");let l,d=[],c=It,u=Rt,h=Bt.length,f=0;if("left"!=c||o){l=Vt(e._font,t);let r=0;"alphabetic"==u?n-=Et:"center"==u?r=.5*l.height:"bottom"==u&&(r=l.height),Vt(e._font,t,((e,t,n,i)=>{let a=0;"center"==c?a=-.5*l.width- -.5*(l.width-l.lineWidths[n]):"right"==c&&(a=-l.lineWidths[n]),d[f]=e+a,d[f+1]=-(t+r),d[f+2]=i.charIndex,d[f+3]=h,f+=4}))}else l=Vt(e._font,t,((e,t,r,n)=>{d[f]=e,d[f+1]=-t,d[f+2]=n.charIndex,d[f+3]=h,f+=4})),"alphabetic"==u?n-=Et:"center"==u?n-=.5*Et:"bottom"==u&&(n-=Tt);Ft.push(d);let p=[];q&&j(),p[0]=r,p[1]=n,p[2]=Et/42,p[3]=H,p[4]=M&&E?A:1,p[5]=R,p[6]=P&&I?O:0,p[7]=Lt,Bt.push(p),_.push(xt,l.printedCharCount,e._font.index)},e.textWidth=t=>e._font?Vt(e._font,t).width*Et/42:(e._g.textSize(Et),e._g.textWidth(t)),e.textAscent=t=>e._font?Tt-kt:(e._g.textSize(Et),e._g.textAscent(t)),e.textDescent=t=>e._font?kt:(e._g.textSize(Et),e._g.textDescent(t)),e.createTextImage=(t,r,n)=>{if(e._g.textSize(Et),M&&E){let t=4*A;e._g.fill(x.slice(t,t+4))}if(P&&I){let t=4*R;e._g.stroke(x.slice(t,t+4))}let i=e._g.createTextImage(t,r,n);return e._makeDrawable(i),i},e.textImage=(t,r,n)=>{"string"==typeof t&&(t=e.createTextImage(t));let i=mt;mt="corner";let a=It;"center"==a?r-=t.canvas.hw:"right"==a&&(r-=t.width);let o=Rt;"alphabetic"==o?n-=t._leading:"center"==o?n-=t._middle:"bottom"==o?n-=t._bottom:"top"==o&&(n-=t._top),e.image(t,r,n),mt=i};let Ht=["frame","shapes","image","video","text"],qt={frame:10,shapes:1e3,image:2e3,video:3e3,text:4e3};e._createShader=(t,r="shapes")=>{t=t.trim();let n=e["_"+r+"ShaderCode"],i=n.indexOf("@vertex"),a=n.indexOf("@fragment");t=t.includes("@fragment")?t.includes("@vertex")?n.slice(0,i)+t:n.slice(0,a)+t:n.slice(0,i)+t+"\n\n"+n.slice(a);let o=Q5.device.createShaderModule({label:r+"Shader",code:t});o.type=r;let s=Ht.indexOf(r),l=Object.assign({},e._pipelineConfigs[s]);l.vertex.module=l.fragment.module=o;let d=qt[r];return e._pipelines[d]=Q5.device.createRenderPipeline(l),e._pipelines[d].shader=o,o.pipelineIndex=d,qt[r]++,o},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=e=>{let t=e.type,r=e.pipelineIndex;"frame"==t?e.applyBeforeDraw?g=r:m=r:"shapes"==t?fe=r:"image"==t?tt=r:"video"==t?rt=r:"text"==t&&(xt=r)},e.resetShader=e.resetShapesShader=()=>fe=1,e.resetFrameShader=()=>g=m=0,e.resetImageShader=()=>tt=2,e.resetVideoShader=()=>rt=3,e.resetTextShader=()=>xt=4,e.resetShaders=()=>{g=m=0,fe=1,tt=2,rt=3,xt=4}},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.MAX_TRANSFORMS=1e7,Q5.MAX_RECTS=200200,Q5.MAX_ELLIPSES=200200,Q5.MAX_CHARS=1e5,Q5.MAX_TEXTS=1e4,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){Q5.requestedGPU=!0;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){let r;return e&&"global"!=e||(Q5._hasGlobal=!0),await Q5.initWebGPU()||(r=new Q5(e,t,"webgpu-fallback")),r=new Q5(e,t,"webgpu"),await r.ready,r},Q5.addHook("presetup",(e=>{let t;if("es"==Q5.lang){t={createCanvas:"crearLienzo",background:"fondo",windowWidth:"anchoVentana",windowHeight:"altoVentana",frameCount:"cuadroActual",noLoop:"pausar",redraw:"redibujar",loop:"reanudar",frameRate:"frecuenciaRefresco",getTargetFrameRate:"frecuenciaIdeal",getFPS:"frecuenciaMaxima",deltaTime:"ultimoTiempo",circle:"círculo"};for(let r in t){e[t[r]]=e[r]}}})),Object.defineProperty(Q5,"lang",{get:()=>Q5._lang||"en",set:e=>{let t;if(Q5._lang=e,"es"==e){"object"==typeof window&&(window.crearLienzo=createCanvas),t={update:"actualizar",draw:"dibujar",postProcess:"retocarDibujo"};for(let e in t){const r=t[e];Object.defineProperty(Q5,r,{get:()=>Q5[e],set:t=>Q5[e]=t})}Q5._userFnsMap=t,Q5._userFns.push(...Object.values(t))}}}),Q5.modules.lang=e=>{let t=Q5._userFnsMap;for(let r in t){const n=t[r];Object.defineProperty(e,n,{get:()=>e[r],set:t=>e[r]=t})}};
|
|
9
|
+
function Q5(e,t,r){let n,i=this;i._isQ5=i._q5=!0,i._parent=t,i.ready=new Promise((e=>{n=e})),"webgpu-fallback"==r?(i._renderer="c2d",i._webgpu=i._webgpuFallback=!0):(i._renderer=r||"c2d",i["_"+i._renderer]=!0);let a,o="auto"==e;if(e??="global","auto"==e){if(!(window.setup||window.update||Q5.update||window.draw||Q5.draw))return;e="global"}"global"==e&&(Q5._hasGlobal=i._isGlobal=!0,a=Q5._esm?globalThis:Q5._server?global:window),"graphics"==e&&(i._isGraphics=!0),"image"==e&&(i._isImage=!0);let s=new Proxy(i,{set:(e,t,r)=>(i[t]=r,i._isGlobal&&(a[t]=r),!0)});i.canvas=i.ctx=i.drawingContext=null,i.pixels=[];let l=null,d=!0;async function c(e){for(let t of Q5.hooks[e])await t.call(i,s)}i.frameCount=0,i.deltaTime=16,i._targetFrameRate=0,i._targetFrameDuration=16.666666666666668,i._frameRate=i._fps=60,i._loop=!0;let u=0;i.millis=()=>performance.now()-u,i.noCanvas=()=>{i.canvas?.remove&&i.canvas.remove(),i.canvas=0,s.ctx=s.drawingContext=0},window&&(i.windowWidth=window.innerWidth,i.windowHeight=window.innerHeight,i.deviceOrientation=window.screen?.orientation?.type),i._loaders=[],i.loadAll=()=>{let e=[...i._loaders];return i._loaders=[],i._g&&(e=e.concat(i._g._loaders),i._g._loaders=[]),Promise.all(e)},i.isPreloadSupported=()=>!0,i.disablePreload=()=>i._disablePreload=!0;const h=[];async function f(e){let t=e||performance.now();if(i._didResize&&(i.windowResized(),i._didResize=!1),i._loop)if(d)l=g(f);else{let e=t+i._targetFrameDuration,r=e-performance.now();for(;r<0;)r+=i._targetFrameDuration;l=setTimeout((()=>f(e)),r)}else if(i.frameCount&&!i._redraw)return;if(i.frameCount&&d&&!i._redraw){if(t-i._lastFrameTime<i._targetFrameDuration-4)return}s.deltaTime=t-i._lastFrameTime,i._frameRate=1e3/i.deltaTime,s.frameCount++;let r=performance.now();i.resetMatrix(),i._beginRender&&i._beginRender(),await c("predraw");try{await i.draw()}catch(e){throw Q5.errorTolerant||i.noLoop(),i._fes&&i._fes(e),e}await c("postdraw"),await i.postProcess(),i._render&&i._render(),i._finishRender&&i._finishRender(),s.pmouseX=i.mouseX,s.pmouseY=i.mouseY,s.moveX=s.moveY=0,i._lastFrameTime=t;let n=performance.now();i._fps=Math.round(1e3/(n-r))}i._incrementPreload=()=>{i._loaders.push(new Promise((e=>h.push(e))))},i._decrementPreload=()=>{h.length&&h.pop()()},i.noLoop=()=>{i._loop=!1,null!=l&&(d&&window.cancelAnimationFrame?cancelAnimationFrame(l):clearTimeout(l)),l=null},i.loop=()=>{i._loop=!0,i._setupDone&&null==l&&f()},i.isLooping=()=>i._loop,i.redraw=async(e=1)=>{i._redraw=!0;for(let t=0;t<e;t++)await f();i._redraw=!1},i.remove=async()=>{i.noLoop(),i.canvas.remove(),await c("remove")},i.frameRate=e=>(e&&e!=i._targetFrameRate&&(i._targetFrameRate=e,i._targetFrameDuration=1e3/e,i._loop&&null!=l&&(d&&window.cancelAnimationFrame?cancelAnimationFrame(l):clearTimeout(l),l=null),d=e<=60,i._setupDone&&(l=d?g(f):setTimeout((()=>f()),i._targetFrameDuration))),i._frameRate),i.getTargetFrameRate=()=>i._targetFrameRate||60,i.getFPS=()=>i._fps,i.Element=function(e){this.elt=e},i._elements=[],i.describe=()=>{},i.log=i.print=console.log;for(let e in Q5.modules)Q5.modules[e](i,s);let p=Q5.renderers[i._renderer];for(let e in p)p[e](i,s);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(i[e]=Q5[e]);if(i._isGraphics)return;if(i._isGlobal){let e=Object.assign({},i);delete e.Color,Object.assign(Q5,e),delete Q5.Q5}for(let e of Q5.hooks.init)e.call(i,s);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof i[e]&&(i[e]=t.bind(i));for(let[e,t]of Object.entries(Q5.preloadMethods))i[e]=function(){return i._incrementPreload(),t.apply(i,arguments)};if(i._isGlobal){let e=Object.getOwnPropertyNames(i);for(let t of e)"_"!=t[0]&&(a[t]=i[t]);for(let e of["_incrementPreload","_decrementPreload"])a[e]=i[e]}"function"==typeof e&&e(i),Q5._instanceCount++;let g=window.requestAnimationFrame||function(e){const t=i._lastFrameTime+i._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},m=a||i,_=Q5._userFns.slice(0,15);for(let e of _)i[e]??=()=>{};if(i._isGlobal){let e=Q5._userFns.slice(0,17);for(let t of e)Q5[t]?i[t]=Q5[t]:Object.defineProperty(Q5,t,{get:()=>i[t],set:e=>i[t]=e})}function x(e){const t=m[e]||i[e];i[e]=e=>{try{return t(e)}catch(e){throw i._fes&&i._fes(e),e}}}async function v(){await c("presetup"),n(),(m.preload||i.preload)&&(x("preload"),i.preload()),await Promise.race([new Promise((e=>{!function t(){i.setup||i.update||i.draw||m.setup||m.update||m.draw?e():i._setupDone||(i.canvas?.ready&&i._render&&(i._beginRender(),i._render(),i._finishRender()),g(t))}()})),new Promise((e=>{setTimeout((()=>{i._loaders.length||e()}),500)}))]),i._disablePreload||await i.loadAll(),i.setup??=m.setup||(()=>{}),x("setup");for(let e of _)x(e);i.draw??=m.draw||(()=>{}),u=performance.now(),await i.setup(),i._setupDone=!0,null===i.ctx&&i.createCanvas(200,200),await c("postsetup"),i.frameCount||(i._lastFrameTime=performance.now()-15,g(f))}Q5.instances.push(i),o||Q5._esm?v():setTimeout(v,32)}function createCanvas(e,t,r){if(Q5._hasGlobal)return;if("c2d"==e||"c2d"==t||"c2d"==r||"c2d"==r?.renderer||!Q5._esm){let n=new Q5,i=n.createCanvas(e,t,r);return n.ready.then((()=>i))}return Q5.WebGPU().then((n=>n.createCanvas(e,t,r)))}Q5.renderers={},Q5.modules={},Q5._server="object"==typeof process,Q5._esm=void 0===this,Q5._instanceCount=0,Q5.instances=[],Q5._friendlyError=(e,t)=>{Q5.disableFriendlyErrors||console.error(t+": "+e)},Q5._validateParameters=()=>!0,Q5._userFns=["postProcess","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","doubleClicked","mouseWheel","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized","update","draw"],Q5.hooks={init:[],presetup:[],postsetup:[],predraw:[],postdraw:[],remove:[]},Q5.addHook=(e,t)=>Q5.hooks[e].push(t),Q5.registerAddon=e=>{let t={};e(Q5,Q5.prototype,t);for(let e in t)Q5.hooks[e].push(t[e])},Q5.prototype.registerMethod=(e,t)=>{("beforeSetup"==e||e.includes("Preload"))&&(e="presetup"),"afterSetup"==e&&(e="postsetup"),"pre"==e&&(e="predraw"),"post"==e&&(e="postdraw"),Q5.hooks[e].push(t)},Q5.preloadMethods={},Q5.prototype.registerPreloadMethod=(e,t)=>Q5.preloadMethods[e]=t[e],Q5._server&&(global.q5=global.Q5=Q5,global.p5??=Q5),"object"==typeof window?(window.q5=window.Q5=Q5,window.p5??=Q5,window.createCanvas=createCanvas,window.C2D="c2d",window.WEBGPU="webgpu"):global.window=0,Q5.version=Q5.VERSION="3.7","object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||(Q5.update||Q5.draw?Q5.WebGPU():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(200,200)):(e._isImage||e._isGraphics)&&(t.canvas=new e._Canvas(200,200)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas()),e.displayDensity=()=>window.devicePixelRatio||1,e.width=200,e.height=200,e._pixelDensity=1;let r=e.canvas;if(r&&(r.width=200,r.height=200,r.colorSpace=Q5.canvasOptions.colorSpace,e._isImage||(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity()))),e._adjustDisplay=e=>{let t=r.style;t&&e&&(t.width=r.w+"px",t.height=r.h+"px")},e.createCanvas=function(t,i,a){(isNaN(t)||"string"==typeof t&&!t.includes(":"))&&(a=t,t=null),"number"!=typeof i&&(a=i,i=null),a??=arguments[3],"string"==typeof a&&(a={renderer:a});let o=Object.assign({},Q5.canvasOptions);if("object"==typeof a&&Object.assign(o,a),!e._isImage)if(e._isGraphics)e._pixelDensity=this._pixelDensity;else if(Q5._server)r.visible=!0;else{let t=r,i=document.body||document.documentElement;for(;t&&t.parentElement!=i;)t=t.parentElement;if(t||(document.getElementById(r.id)?.remove(),n()),window.IntersectionObserver){let t=!1;new IntersectionObserver((n=>{if(n[0].isIntersecting)r.visible=!0;else{let e=r.getBoundingClientRect();r.visible=e.top<window.innerHeight&&e.bottom>0&&e.left<window.innerWidth&&e.right>0}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,i),Object.assign(r,o);let s=e._createCanvas(r.w,r.h,o);return e._addEventMethods&&e._addEventMethods(r),e.canvas.ready=!0,s},e.createGraphics=function(t,r,n={}){"string"==typeof n&&(n={renderer:n});let i=new Q5("graphics",void 0,n.renderer||(e._webgpuFallback?"webgpu-fallback":e._renderer));n.alpha??=!0,n.colorSpace??=e.canvas.colorSpace,n.pixelDensity??=e._pixelDensity,i._defaultImageScale=e._defaultImageScale,i.createCanvas.call(e,t,r,n);let a=i._pixelDensity*e._defaultImageScale;return i.defaultWidth=t*a,i.defaultHeight=r*a,i},e._setCanvasSize=(n,i)=>{i??=n??window.innerHeight,n??=window.innerWidth,r.w=n=Math.ceil(n),r.h=i=Math.ceil(i),t.halfWidth=r.hw=n/2,t.halfHeight=r.hh=i/2,r.width=Math.ceil(n*e._pixelDensity),r.height=Math.ceil(i*e._pixelDensity),t.width=n,t.height=i,e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay(!0)},e._setImageSize=(n,i)=>{t.width=r.w=n,t.height=r.h=i,t.halfWidth=r.hw=n/2,t.halfHeight=r.hh=i/2,r.width=Math.ceil(n*e._pixelDensity),r.height=Math.ceil(i*e._pixelDensity)},e.defaultImageScale=t=>t?(e._g&&(e._g._defaultImageScale=t),e._defaultImageScale=t):e._defaultImageScale,e.defaultImageScale(.5),!e._isImage){if(r&&!e._isGraphics){function n(){let t=e._parent;if(t??=document.getElementsByTagName("main")[0],!t){t=document.createElement("main"),(document.body||document.documentElement).appendChild(t)}r.parent(t),document.body||document.addEventListener("DOMContentLoaded",(()=>{document.body&&document.body.appendChild(t)}))}r.parent=t=>{function n(){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(n),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",n)},n()}e.resizeCanvas=(t,n)=>{if(!e.ctx)return e.createCanvas(t,n);t==r.w&&n==r.h||e._resizeCanvas(t,n)},r&&!Q5._createServerCanvas&&(r.resize=e.resizeCanvas),e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._resizeCanvas(r.w,r.h),e._g&&e._g.pixelDensity(t),t):e._pixelDensity,window&&!e._isGraphics&&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.GPU=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;function n(){let t=e._styles.pop();for(let r of e._styleNames)e[r]=t[r]}e.colorMode&&e.colorMode("rgb",e._webgpu?1:255),e._createCanvas=function(n,i,a){if(r)return t.ctx=t.drawingContext=r.getContext("2d",a),e._isImage||(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()},e._isImage||(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._isColor&&(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,n)=>{let i,a={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(a[t]=e.ctx[t]);if(delete a.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,n);for(let t in a)e.ctx[t]=a[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._isColor||"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._isColor||"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.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._getFillIdx=()=>e._fill,e._setFillIdx=t=>e._fill=t,e._getStrokeIdx=()=>e._stroke,e._setStrokeIdx=t=>e._stroke=t,e._doShadow=!1,e._shadowOffsetX=e._shadowOffsetY=e._shadowBlur=10,e.shadow=function(t){if(Q5.Color&&(t._isColor||"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,n)=>{e.ctx.shadowOffsetX=e._shadowOffsetX=t,e.ctx.shadowOffsetY=e._shadowOffsetY=r||t,e.ctx.shadowBlur=e._shadowBlur=n||0},e.noShadow=()=>{e._doShadow=!1,e.ctx.shadowOffsetX=e.ctx.shadowOffsetY=e.ctx.shadowBlur=0},e.translate=(t,r)=>{t.x&&(r=t.y,t=t.x),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,n,i,a,o)=>e.ctx.transform(t,r,n,i,a,o),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._styleNames=["_fill","_stroke","_strokeWeight","_doFill","_doStroke","_fillSet","_strokeSet","_shadow","_doShadow","_shadowOffsetX","_shadowOffsetY","_shadowBlur","_tint","_textSize","_textAlign","_textBaseline","_imageMode","_rectMode","_ellipseMode","_colorMode","_colorFormat","Color"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t),e._fontMod&&e._updateFont()},e.popStyles=()=>{n(),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.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore(),e.push=()=>{e.pushStyles(),e.ctx.save()},e.pop=()=>{e.ctx.restore(),n()})},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 n(){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,n,i)=>{e._doStroke&&(e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(n,i),e.ctx.stroke())};const i=2*Math.PI;function a(t,r,n,a,o,s,l){if(e._angleMode&&(o=e.radians(o),s=e.radians(s)),(o%=i)<0&&(o+=i),(s%=i)<0&&(s+=i),o>s&&(s+=i),o==s)return e.ellipse(t,r,n,a);if(n/=2,a/=2,n=Math.abs(n),a=Math.abs(a),e._doFill||l!=e.PIE_OPEN||(l=e.CHORD_OPEN),e.ctx.beginPath(),e.ctx.ellipse(t,r,n,a,0,o,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,n,a,0,o,s),e.ctx.stroke()}}function o(t,r,a,o){e.ctx.beginPath(),e.ctx.ellipse(t,r,Math.abs(a/2),Math.abs(o/2),0,0,i),n()}function s(t,r,i,a,o,l,d,c){return void 0===o?function(t,r,i,a){e.ctx.beginPath(),e.ctx.rect(t,r,i,a),n()}(t,r,i,a):void 0===l?s(t,r,i,a,o,o,o,o):(e.ctx.beginPath(),e.ctx.roundRect(t,r,i,a,[o,l,d,c]),void n())}e.arc=(t,r,n,i,o,s,l)=>{if(o==s)return e.ellipse(t,r,n,i);l??=e.PIE_OPEN,e._ellipseMode==e.CENTER?a(t,r,n,i,o,s,l):e._ellipseMode==e.RADIUS?a(t,r,2*n,2*i,o,s,l):e._ellipseMode==e.CORNER?a(t+n/2,r+i/2,n,i,o,s,l):e._ellipseMode==e.CORNERS&&a((t+n)/2,(r+i)/2,n-t,i-r,o,s,l)},e.ellipse=(t,r,n,i)=>{i??=n,e._ellipseMode==e.CENTER?o(t,r,n,i):e._ellipseMode==e.RADIUS?o(t,r,2*n,2*i):e._ellipseMode==e.CORNER?o(t+n/2,r+i/2,n,i):e._ellipseMode==e.CORNERS&&o((t+n)/2,(r+i)/2,n-t,i-r)},e.circle=(t,r,a)=>{e._ellipseMode==e.CENTER?(e.ctx.beginPath(),e.ctx.arc(t,r,Math.abs(a/2),0,i),n()):e.ellipse(t,r,a,a)},e.point=(t,r)=>{e._doStroke&&(t.x&&(r=t.y,t=t.x),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(t,r),e.ctx.stroke())},e.rect=(t,r,n,i=n,a,o,l,d)=>{e._rectMode==e.CENTER?s(t-n/2,r-i/2,n,i,a,o,l,d):e._rectMode==e.RADIUS?s(t-n,r-i,2*n,2*i,a,o,l,d):e._rectMode==e.CORNER?s(t,r,n,i,a,o,l,d):e._rectMode==e.CORNERS&&s(t,r,n-t,i-r,a,o,l,d)},e.square=(t,r,n,i,a,o,s)=>e.rect(t,r,n,n,i,a,o,s),e.capsule=(t,r,i,a,o)=>{const s=i-t,l=a-r,d=Math.hypot(s,l);if(0===d)return e.circle(t,r,2*o);const c=Math.atan2(l,s),u=-l/d*o,h=s/d*o;e.ctx.beginPath(),e.ctx.moveTo(t-u,r-h),e.ctx.arc(t,r,o,c-e.HALF_PI,c+e.HALF_PI,!0),e.ctx.lineTo(i+u,a+h),e.ctx.arc(i,a,o,c+e.HALF_PI,c-e.HALF_PI,!0),e.ctx.closePath(),n()},e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(n,i)=>{r=[],t?e.ctx.moveTo(n,i):e.ctx.lineTo(n,i),t=!1},e.bezierVertex=(t,n,i,a,o,s)=>{r=[],e.ctx.bezierCurveTo(t,n,i,a,o,s)},e.quadraticVertex=(t,n,i,a)=>{r=[],e.ctx.quadraticCurveTo(t,n,i,a)},e.bezier=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(n,i,a,o,s,l),e.endShape()},e.triangle=(t,r,n,i,a,o)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.endShape(e.CLOSE)},e.quad=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),n()},e.curveVertex=(n,i)=>{if(r.push([n,i]),r.length<4)return;let a=r.at(-4),o=r.at(-3),s=r.at(-2),l=r.at(-1),d=o[0]+(s[0]-a[0])/6,c=o[1]+(s[1]-a[1])/6,u=s[0]-(l[0]-o[0])/6,h=s[1]-(l[1]-o[1])/6;t&&(e.ctx.moveTo(o[0],o[1]),t=!1),e.ctx.bezierCurveTo(d,c,u,h,s[0],s[1])},e.curve=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(n,i),e.curveVertex(a,o),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,n,i)=>{const a=i*i*i,o=i*i;return e*(-.5*a+o-.5*i)+t*(1.5*a-2.5*o+1)+r*(-1.5*a+2*o+.5*i)+n*(.5*a-.5*o)},e.bezierPoint=(e,t,r,n,i)=>{const a=1-i;return Math.pow(a,3)*e+3*Math.pow(a,2)*i*t+3*a*Math.pow(i,2)*r+Math.pow(i,3)*n},e.curveTangent=(e,t,r,n,i)=>{const a=i*i;return e*(-3*a/2+2*i-.5)+t*(9*a/2-5*i)+r*(-9*a/2+4*i+.5)+n*(3*a/2-i)},e.bezierTangent=(e,t,r,n,i)=>{const a=1-i;return 3*n*Math.pow(i,2)-3*r*Math.pow(i,2)+6*r*a*i-6*t*a*i+3*t*Math.pow(a,2)-3*e*Math.pow(a,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 n=e._pixelDensity;return e.ctx.isPointInPath(t*n,r*n)},e.inStroke=(t,r)=>{const n=e._pixelDensity;return e.ctx.isPointInStroke(t*n,r*n)}},Q5.renderers.c2d.image=(e,t)=>{const r=e.canvas;r&&(r.convertToBlob??=e=>new Promise((t=>{r.toBlob((e=>t(e)),e.type,e.quality)}))),e._tint=null;let n=null,i=null;e.createImage=(t,r,n={})=>(n.colorSpace??=e.canvas.colorSpace,n.defaultImageScale??=e._defaultImageScale,new Q5.Image(t,r,n)),e.loadImage=function(t,r,n){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?(n=i,r=null):n=void 0;let a=e.createImage(1,1,n),o=a._pixelDensity,s=new window.Image;return s.crossOrigin="Anonymous",a.promise=new Promise(((t,i)=>{s.onload=()=>{delete a.then,a._usedAwait&&(a=e.createImage(1,1,n)),s._pixelDensity=o,a.defaultWidth=s.width*e._defaultImageScale,a.defaultHeight=s.height*e._defaultImageScale,a.naturalWidth=s.naturalWidth||s.width,a.naturalHeight=s.naturalHeight||s.height,a._setImageSize(Math.ceil(a.naturalWidth/o),Math.ceil(a.naturalHeight/o)),a.ctx.drawImage(s,0,0),r&&r(a),t(a)},s.onerror=i})),e._loaders.push(a.promise),a.then=(e,t)=>(a._usedAwait=!0,a.promise.then(e,t)),a.src=s.src=t,a},e._imageMode=Q5.CORNER,e.imageMode=t=>e._imageMode=t,e.image=(t,r,n,i,a,o=0,s=0,l,d)=>{if(!t)return;let c=t.canvas||t;i??=t.defaultWidth||c.width||t.videoWidth,a??=t.defaultHeight||c.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*i,n-=.5*a);let u=t._pixelDensity||1;if(l?l*=u:l=c.width||c.videoWidth,d?d*=u:d=c.height||c.videoHeight,e._tint){if(t._retint||t._tint!=e._tint){t._tintImg??=e.createImage(t.w,t.h,{pixelDensity:u}),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,o*u,s*u,l,d,r,n,i,a),t.flipped&&e.ctx.restore()},e.filter=(t,n)=>{e.ctx.save();let i="";if(e.ctx.filter){if("string"==typeof t)i=t;else if(t==Q5.GRAY)i="saturate(0%)";else if(t==Q5.INVERT)i="invert(100%)";else if(t==Q5.BLUR){i=`blur(${Math.ceil(n*e._pixelDensity)||1}px)`}else if(t==Q5.THRESHOLD){n??=.5,i=`saturate(0%) brightness(${Math.floor(.5/Math.max(n,1e-5)*100)}%) contrast(1000000%)`}else if(t==Q5.SEPIA)i=`sepia(${n??1})`;else if(t==Q5.BRIGHTNESS)i=`brightness(${n??1})`;else if(t==Q5.SATURATION)i=`saturate(${n??1})`;else if(t==Q5.CONTRAST)i=`contrast(${n??1})`;else if(t==Q5.HUE_ROTATE){i=`hue-rotate(${n}${0==e._angleMode?"rad":"deg"})`}if(i&&(e.ctx.filter=i,"none"==e.ctx.filter))throw new Error(`Invalid filter format: ${t}`)}i||e._softFilter(t,n),e.ctx.globalCompositeOperation="source-over",e.ctx.drawImage(r,0,0,r.w,r.h),e.ctx.restore(),e.modified=e._retint=!0},e._isImage&&(e.resize=(t,n)=>{let i=new e._Canvas(r.width,r.height);i.getContext("2d",{colorSpace:r.colorSpace}).drawImage(r,0,0),e._setImageSize(t,n),e.defaultWidth=r.width*e._defaultImageScale,e.defaultHeight=r.height*e._defaultImageScale,e.ctx.clearRect(0,0,r.width,r.height),e.ctx.drawImage(i,0,0,r.width,r.height),e.modified=e._retint=!0}),e._getImageData=(t,n,i,a)=>e.ctx.getImageData(t,n,i,a,{colorSpace:r.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,n=r.width,i=r.height,a=e._getImageData(0,0,n,i).data,o=n,s=0,l=i,d=0,c=3;for(let e=0;e<i;e++)for(let t=0;t<n;t++)0!==a[c]&&(t<o&&(o=t),t>s&&(s=t),e<l&&(l=e),e>d&&(d=e)),c+=4;return l=Math.floor(l/t),d=Math.floor(d/t),o=Math.floor(o/t),s=Math.floor(s/t),e.get(o,l,s-o+1,d-l+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,n,i,a,o,s,l,d)=>{let c=e._pixelDensity||1;e.ctx.drawImage(r,t*c,n*c,i*c,a*c,o,s,l,d),e.modified=e._retint=!0},e.copy=()=>{let t=e.get();for(let r in e)"function"==typeof e[r]||/(canvas|ctx|texture)/.test(r)||(t[r]=e[r]);return t},e.get=(t,n,a,o)=>{let s=e._pixelDensity||1;if(void 0!==t&&void 0===a){i||e.loadPixels();let a=Math.floor(t*s),o=4*(Math.floor(n*s)*r.width+a);return[i[o],i[o+1],i[o+2],i[o+3]]}t=Math.floor(t||0)*s,n=Math.floor(n||0)*s,a??=e.width,o??=e.height;let l=e.createImage(a,o,{pixelDensity:s});return l.ctx.drawImage(r,t,n,a*s,o*s,0,0,a,o),l.width=a,l.height=o,e._owner?._makeDrawable&&e._owner._makeDrawable(l),l},e.set=(t,n,a)=>{if(t=Math.floor(t),n=Math.floor(n),e.modified=e._retint=!0,a.canvas){let r=e._tint;return e._tint=null,e.image(a,t,n),void(e._tint=r)}i||e.loadPixels();let o=e._pixelDensity||1,s=a.r,l=a.g,d=a.b,c=a.a;1==(e._colorFormat||e._owner?._colorFormat)&&(s*=255,l*=255,d*=255,c*=255);for(let e=0;e<o;e++)for(let a=0;a<o;a++){let u=4*((n*o+e)*r.width+t*o+a);i[u]=s,i[u+1]=l,i[u+2]=d,i[u+3]=c}},e.loadPixels=()=>{n=e._getImageData(0,0,r.width,r.height),t.pixels=i=n.data},e.updatePixels=()=>{null!=n&&(e.ctx.putImageData(n,0,0),e.modified=e._retint=!0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,e._isImage||(e.tint=function(t){e._tint=(t._isColor?t:e.color(...arguments)).toString()},e.noTint=()=>e._tint=null)},Q5.Image=class{constructor(e,t,r={}){r.alpha??=!0,r.colorSpace??=Q5.canvasOptions.colorSpace;let n=this;n._isImage=!0,n.canvas=n.ctx=n.drawingContext=null,n.pixels=[],Q5.modules.canvas(n,n);let i=Q5.renderers.c2d;for(let e of["canvas","image","softFilters"])i[e]&&i[e](n,n);n._pixelDensity=r.pixelDensity||1,n._defaultImageScale=r.defaultImageScale||2,n.createCanvas(e,t,r);let a=n._pixelDensity*n._defaultImageScale;n.defaultWidth=e*a,n.defaultHeight=t*a,delete n.createCanvas,n._loop=!1}get w(){return this.width}get h(){return this.height}},Q5.renderers.c2d.softFilters=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=(n,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 n=.2126*e[r]+.7152*e[r+1]+.0722*e[r+2];e[r]=e[r+1]=e[r+2]=n>=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 n=0;n<e.length;n+=4)e[n]=255*(e[n]*t>>8)/r,e[n+1]=255*(e[n+1]*t>>8)/r,e[n+2]=255*(e[n+2]*t>>8)/r},e._filters[Q5.DILATE]=(n,i)=>{i??=Math.max,r(),t.set(n);let[a,o]=[e.canvas.width,e.canvas.height];for(let e=0;e<o;e++)for(let r=0;r<a;r++){let s=4*Math.max(r-1,0),l=4*Math.min(r+1,a-1),d=4*Math.max(e-1,0)*a,c=4*Math.min(e+1,o-1)*a,u=4*e*a,h=4*r;for(let e=0;e<4;e++){let r=e+d,a=e+c,o=e+u;n[u+h+e]=i(t[r+h],t[o+s],t[o+h],t[o+l],t[a+h])}}},e._filters[Q5.ERODE]=t=>{e._filters[Q5.DILATE](t,Math.min)},e._filters[Q5.BLUR]=(n,i)=>{i=i||1,i=Math.floor(i*e._pixelDensity),r(),t.set(n);let a=2*i+1,o=function(e){let t=new Float32Array(e),r=.3*i+.8,n=r*r*2;for(let i=0;i<e;i++){let a=i-e/2,o=Math.exp(-a*a/n)/(2.5066282746*r);t[i]=o}return t}(a),[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,u=0;for(let n=0;n<a;n++){let a=4*(e*s+Math.min(Math.max(r-i+n,0),s-1));l+=t[a]*o[n],d+=t[a+1]*o[n],c+=t[a+2]*o[n],u+=t[a+3]*o[n]}let h=4*(e*s+r);n[h]=l,n[h+1]=d,n[h+2]=c,n[h+3]=u}t.set(n);for(let e=0;e<l;e++)for(let r=0;r<s;r++){let d=0,c=0,u=0,h=0;for(let n=0;n<a;n++){let a=4*(Math.min(Math.max(e-i+n,0),l-1)*s+r);d+=t[a]*o[n],c+=t[a+1]*o[n],u+=t[a+2]*o[n],h+=t[a+3]*o[n]}let f=4*(e*s+r);n[f]=d,n[f+1]=c,n[f+2]=u,n[f+3]=h}});let a=e._getImageData(0,0,e.canvas.width,e.canvas.height);e._filters[n](a.data,i),e.ctx.putImageData(a,0,0)}},Q5.renderers.c2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic",e._textSize=12;let r="sans-serif",n=!1,i=15,a=3,o="normal",s="normal",l=0,d=!1,c=0;e._fontMod=!1;let u=e._textCache={};e.loadFont=(t,r)=>{let n;if(t.includes("fonts.googleapis.com/css"))n=function(e,t){e.startsWith("http")||(e="https://"+e);const r=new URL(e).searchParams,n=r.get("family");if(!n)return console.error("Invalid Google Fonts URL: missing family parameter"),null;const i=n.split(":")[0];let a={family:i};return a.promise=(async()=>{try{const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch Google Font: ${r.status} ${r.statusText}`);let n,o=await r.text(),s=/@font-face\s*{([^}]*)}/g,l=/src:\s*url\(([^)]+)\)[^;]*;/,d=/font-family:\s*['"]([^'"]+)['"]/,c=/font-weight:\s*([^;]+);/,u=/font-style:\s*([^;]+);/,h=[];for(;null!==(n=s.exec(o));){let e=n[1],t=l.exec(e);if(!t)continue;let r=t[1],i=d.exec(e);if(!i)continue;let a=i[1],o=c.exec(e),s=o?o[1]:"400",f=u.exec(e),p=f?f[1]:"normal",g=`${a}-${s}-${p}`.replace(/\s+/g,"-"),m=new FontFace(a,`url(${r})`,{weight:s,style:p});document.fonts.add(m);try{await m.load(),h.push(m)}catch(e){console.error(`Failed to load font face: ${g}`,e)}}return a._usedAwait&&(a={family:i}),a.faces=h,delete a.then,t&&t(a),a}catch(e){throw console.error("Error loading Google Font:",e),e}})(),a}(t,r);else{let e=t.split("/").pop().split(".")[0].replace(" ","");n={family:e};let i=new FontFace(e,`url(${encodeURI(t)})`);document.fonts.add(i),n.promise=new Promise(((e,t)=>{i.load().then((()=>{delete n.then,r&&r(i),e(i)})).catch((e=>{t(e)}))}))}return e._loaders.push(n.promise),e.textFont(n.family),n.then=(e,t)=>(n._usedAwait=!0,n.promise.then(e,t)),n},e.textFont=t=>{if(t&&"string"!=typeof t&&(t=t.family),!t||t==r)return r;r=t,e._fontMod=!0,l=-1},e.textSize=t=>{if(null==t)return e._textSize;e._textSize=t,e._fontMod=!0,l=-1,n||(i=1.25*t,a=i-t)},e.textStyle=t=>{if(!t)return o;o=t,e._fontMod=!0,l=-1},e.textWeight=t=>{if(!t)return s;s=t,e._fontMod=!0,l=-1},e.textLeading=t=>null==t?i||1.25*e._textSize:(n=!0,t==i?i:(i=t,a=t-e._textSize,void(l=-1))),e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r)},e._updateFont=()=>{e.ctx.font=`${o} ${s} ${e._textSize}px ${r}`,e._fontMod=!1},e.textWidth=t=>(e._fontMod&&e._updateFont(),e.ctx.measureText(t).width),e.textAscent=t=>(e._fontMod&&e._updateFont(),e.ctx.measureText(t).actualBoundingBoxAscent),e.textDescent=t=>(e._fontMod&&e._updateFont(),e.ctx.measureText(t).actualBoundingBoxDescent),e.textFill=e.fill,e.textStroke=e.stroke;e.createTextImage=(t,r,n)=>{d=!0;let i=e.text(t,0,0,r,n);return d=!1,i};let h=[];e.text=(t,n,s,f,p)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString();let g,m,_,x,v,b,y,w,S=e.ctx;if(e._fontMod&&e._updateFont(),d)if(-1==l&&(()=>{let t=r+e._textSize+o+i,n=5381;for(let e=0;e<t.length;e++)n=33*n^t.charCodeAt(e);l=n>>>0})(),m=e._fill+e._stroke+e._strokeWeight,_=u[t],_?x=_[l]:_=u[t]={},x){if(g=x[m],g)return g;if(x.size>=4){for(let e in x){g=x[e],delete x[e];break}v=!0}}else x=_[l]={};if(-1==t.indexOf("\n")?h[0]=t:h=t.split("\n"),t.length>f){let e=[];for(let t of h){let r=0;for(;r<t.length;){let n=r+f;if(n>=t.length){e.push(t.slice(r));break}let i=t.lastIndexOf(" ",n);(-1===i||i<r)&&(i=n),e.push(t.slice(r,i)),r=i+1}}h=e}if(d){if(b=0,y=i,g){let e=g.canvas;g.ctx.clearRect(0,0,e.width,e.height),g.modified=!0}else{let t=e.ctx.textBaseline;e.ctx.textBaseline="alphabetic";let r=S.measureText(" "),n=r.fontBoundingBoxAscent,o=r.fontBoundingBoxDescent;e.ctx.textBaseline=t;let s=0;for(let e of h){let t=S.measureText(e).width;t>s&&(s=t)}let l=Math.ceil(s),d=Math.ceil(i*h.length+o);g=e.createImage.call(e,l,d,{pixelDensity:e._pixelDensity,defaultImageScale:1/e._pixelDensity}),g._ascent=n,g._descent=o,g._top=o+a,g._middle=g._top+.5*n+i*(h.length-1)*.5,g._bottom=g._top+n+i*(h.length-1),g._leading=i}S=g.ctx,S.font=e.ctx.font,S.fillStyle=e._fill,S.strokeStyle=e._stroke,S.lineWidth=e.ctx.lineWidth}else b=n,y=s,"middle"==e._textBaseline?y-=i*(h.length-1)*.5:"bottom"==e._textBaseline&&(y-=i*(h.length-1));e._fillSet||(w=S.fillStyle,S.fillStyle="black");let Q=0;for(let t of h)if(e._doStroke&&e._strokeSet&&S.strokeText(t,b,y),e._doFill&&S.fillText(t,b,y),y+=i,Q++,Q>=p)break;if(h=[],e._fillSet||(S.fillStyle=w),d){if(x[m]=g,v||(x.size||(Object.defineProperty(x,"size",{writable:!0,enumerable:!1}),x.size=0),x.size++,c++),c>Q5.MAX_TEXT_IMAGES){for(const e in u){_=u[e];for(const e in _){x=_[e];for(let e in x){let t=x[e];t._texture&&t._texture.destroy(),delete x[e]}}}c=0}return g}},e.textImage=(t,r,n)=>{"string"==typeof t&&(t=e.createTextImage(t));let i=e._imageMode;e._imageMode="corner";let a=e._textAlign;"center"==a?r-=t.canvas.hw:"right"==a&&(r-=t.width);let o=e._textBaseline;"alphabetic"==o?n-=t._leading:"middle"==o?n-=t._middle:"bottom"==o?n-=t._bottom:"top"==o&&(n-=t._top),e.image(t,r,n),e._imageMode=i}},Q5.fonts=[],Q5.MAX_TEXT_IMAGES=5e3,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,n,i)=>{e._colorMode=r;let a="srgb"==e.canvas.colorSpace||"srgb"==i;e._srgb=a,n??="rgb"==r&&(e._c2d||a)?255:1,e._colorFormat="integer"==n||255==n?255:1,"oklch"==r?t.Color=Q5.ColorOKLCH:"hsl"==r?t.Color=a?Q5.ColorHSL:Q5.ColorHSL_P3:"hsb"==r?t.Color=a?Q5.ColorHSB:Q5.ColorHSB_P3:(255==e._colorFormat?t.Color=a?Q5.ColorRGB_8:Q5.ColorRGB_P3_8:t.Color=a?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],coral:[255,127,80],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],silver:[192,192,192],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,n,i)=>{let a=e.Color;if(t._isColor)return new a(...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)),n=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)),n=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 a(0,0,0);return e._css=t,e.toString=function(){return this._css},e}if([t,r,n,i]=e._namedColors[t],"rgb"!=e._colorMode)return a=e._srgb?Q5.ColorRGB_8:Q5.ColorRGB_P3_8,new a(t,r,n,i)}1==e._colorFormat&&(t/=255,r&&(r/=255),n&&(n/=255),i&&(i/=255))}(Array.isArray(t)||t.constructor==Float32Array)&&([t,r,n,i]=t)}return null==n?e._colorMode==Q5.OKLCH?new a(t,0,0,r):new a(t,t,t,r):new a(t,r,n,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,n=t.g,i=t.b;255==e._colorFormat&&(r/=255,n/=255,i/=255);let a,o=Math.max(r,n,i),s=Math.min(r,n,i);return a=o==s?0:o==r?60*(n-i)/(o-s):o==n?60*(i-r)/(o-s)+120:60*(r-n)/(o-s)+240,a<0&&(a+=360),a},e.lerpColor=(t,r,n)=>{if(n=Math.max(0,Math.min(1,n)),"rgb"==e._colorMode)return new e.Color(e.lerp(t.r,r.r,n),e.lerp(t.g,r.g,n),e.lerp(t.b,r.b,n),e.lerp(t.a,r.a,n));{let i=r.h-t.h;i>180&&(i-=360),i<-180&&(i+=360);let a=t.h+n*i;return a<0&&(a+=360),a>360&&(a-=360),new e.Color(e.lerp(t.l,r.l,n),e.lerp(t.c,r.c,n),a,e.lerp(t.a,r.a,n))}}},Q5.Color=class{constructor(){this._isColor=!0,this._q5Color=!0}get alpha(){return this.a}set alpha(e){this.a=e}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,n){super(),this.l=e,this.c=t,this.h=r,this.a=n??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,n){super(),this.r=e,this.g=t,this.b=r,this.a=n??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,n){super(e,t,r,n??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,n){super(e,t,r,n??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),n=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${n})`,this._edited=!1}return this._css}},Q5.ColorHSL=class extends Q5.Color{constructor(e,t,r,n){super(),this.h=e,this.s=t,this.l=r,this.a=n??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,n){super(e,t,r,n),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 n=t/100*Math.min(r,1-r),i=(t,i=(t+e/30)%12)=>r-n*Math.max(Math.min(i-3,9-i,1),-1);return[i(0),i(8),i(4)]},Q5.HSBtoHSL=(e,t,r,n=r*(1-t/200))=>[e,n&&100!=n?(r-n)/Math.min(n,100-n)*100:0,n];{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)))),n=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,a,o)=>r(i(n(t(e,a,o))))}Q5.modules.display=e=>{if(!e.canvas||e._isGraphics)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=e=>{let r=t.style;if(r)if("normal"==t.displayMode){if(!e)return;r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"}else{let e=t.parentElement.getBoundingClientRect();t.w/t.h>e.width/e.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",n="smooth",i=1)=>{Q5._server||("string"==typeof i&&(i=parseFloat(i.slice(1))),"fullscreen"==r&&(r="maxed"),"center"==r&&(r="centered"),t.displayMode&&(t.parentElement.classList.remove("q5-"+t.displayMode),t.classList.remove("q5-pixelated")),t.parentElement.classList.add("q5-"+r),"pixelated"==n&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.defaultImageScale(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),Object.assign(t,{displayMode:r,renderQuality:n,displayScale:i}),e.ctx&&e.pushStyles(),e._adjustDisplay(!0),e.ctx&&e.popStyles())},e.fullscreen=e=>{if(null==e)return document.fullscreenElement;e?document.body.requestFullscreen():document.exitFullscreen()}},Q5.modules.dom=(e,t)=>{e.elementMode=t=>e._elementMode=t,e.createElement=(t,r)=>{let n=document.createElement(t);return"center"==e._elementMode&&(n.style.transform="translate(-50%, -50%)"),r&&(n.innerHTML=r),Object.defineProperty(n,"x",{get:()=>n._x,set:t=>{let r=n.style.position;r&&"relative"!=r||(n.style.position="absolute");let i=e.canvas.offsetLeft+t;n.style.left=i+"px",n._x=i}}),Object.defineProperty(n,"y",{get:()=>n._y,set:t=>{let r=n.style.position;r&&"relative"!=r||(n.style.position="absolute");let i=e.canvas.offsetTop+t;n.style.top=i+"px",n._y=i}}),Object.defineProperty(n,"width",{get:()=>parseFloat(n.style.width||0),set:e=>n.style.width=e+"px"}),Object.defineProperty(n,"height",{get:()=>parseFloat(n.style.height||0),set:e=>n.style.height=e+"px"}),n.position=(e,t,r)=>(r&&(n.style.position=r),n.x=e,n.y=t,n),Object.defineProperty(n,"size",{writable:!0}),n.size=(e,t)=>(n.width=e,n.height=t,n),n.center=()=>(n.style.position="absolute",n.x=e.canvas.hw,n.y=e.canvas.hh,n),n.show=()=>(n.style.display="",n),n.hide=()=>(n.style.display="none",n),n.parent=e=>(e.append(n),n),e._addEventMethods(n),e._elements.push(n),e.canvas?e.canvas.parentElement.append(n):document.body.append(n),n.elt=n,n},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,n)=>{let i=e.createEl("a",r);return i.href=t,i.target=n?"_blank":"_self",i},e.createButton=t=>e.createEl("button",t),e.createCheckbox=(t="",r=!1)=>{let n=e.createEl("input");n.type="checkbox",n.checked=r;let i=e.createEl("label",t);return i.addEventListener("click",(()=>{n.checked=!n.checked,n.dispatchEvent(new Event("input",{bubbles:!0})),n.dispatchEvent(new Event("change",{bubbles:!0}))})),n.insertAdjacentElement("afterend",i),n.label=i,n},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 n=e.createEl("input");return n.value=t,n.type=r,n.style.boxSizing="border-box",n},e.createP=t=>e.createEl("p",t);let r=0;function n(t){t.width||=t.videoWidth,t.height||=t.videoHeight,t.defaultWidth=t.width*e._defaultImageScale,t.defaultHeight=t.height*e._defaultImageScale,t.ready=!0}e.createRadio=t=>{let n=e.createEl("div");return n.name=t||"radio"+r++,n.buttons=[],Object.defineProperty(n,"value",{get:()=>n.selected?.value,set:e=>{let t=n.buttons.find((t=>t.value==e));t&&(t.checked=!0,n.selected=t)}}),n.option=(t,r)=>{let i=e.createEl("input");i.type="radio",i.name=n.name,i.value=r||t,i.addEventListener("input",(()=>n.selected=i));let a=e.createEl("label",t);return a.addEventListener("click",(()=>{i.checked=!0,n.selected=i,i.dispatchEvent(new Event("input",{bubbles:!0})),i.dispatchEvent(new Event("change",{bubbles:!0}))})),i.label=a,n.append(i),n.append(a),n.buttons.push(i),n},n},e.createSelect=t=>{let r=e.createEl("select");if(t){let n=e.createEl("option",t);n.disabled=!0,n.selected=!0,r.append(n)}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 n=0;n<r.options.length;n++)if(r.options[n].value==e){t=r.options[n];break}t&&(t.selected=!0)}}}),r.option=(t,n)=>{let i=e.createEl("option",t);return i.value=n||t,r.append(i),r},r},e.createSlider=(t,r,n,i)=>{let a=e.createEl("input");return a.type="range",a.min=t,a.max=r,a.step=i,a.value=n,a.val=()=>parseFloat(a.value),a},e.createSpan=t=>e.createEl("span",t),e.createVideo=t=>{let r=e.createEl("video");return r.crossOrigin="anonymous",t&&(r.promise=new Promise((i=>{r.addEventListener("loadeddata",(()=>{delete r.then,r._usedAwait&&(r=e.createEl("video"),r.crossOrigin="anonymous",r.src=t),n(r),i(r)})),r.src=t})),e._loaders.push(r.promise),r.then=(e,t)=>(r._usedAwait=!0,r.promise.then(e,t))),r},e.createCapture=function(t,r=!0,i){let a="string"==typeof t?{[t]:!0}:t||{video:!0,audio:!0};!0===a.video&&(a.video={width:3840,height:2160}),a.video.facingMode??="user";let o=e.createVideo();return o.promise=(async()=>{let t;try{t=await navigator.mediaDevices.getUserMedia(a)}catch(e){throw e}return delete o.then,o._usedAwait&&(o=e.createVideo()),function(t){t.playsinline=t.autoplay=!0,r&&(t.flipped=!0,t.style.transform="scale(-1, 1)"),t.loadPixels=()=>{let r=e.createGraphics(t.videoWidth,t.videoHeight,{renderer:"c2d"});r.image(t,0,0),r.loadPixels(),t.pixels=r.pixels,r.remove()}}(o),o.srcObject=t,await new Promise((e=>o.addEventListener("loadeddata",e))),n(o),i&&i(o),o})(),e._loaders.push(o.promise),o.then=(e,t)=>(o._usedAwait=!0,o.promise.then(e,t)),o},e.findElement=e=>document.querySelector(e),e.findElements=e=>document.querySelectorAll(e)},Q5.modules.fes=e=>{if(e._fes=async t=>{if(Q5.disableFriendlyErrors)return;t._handledByFES=!0;let r=t.stack?.split("\n");if(!r?.length)return;let n=1,i="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(n=0,i="@");r[n].indexOf("q5")>=0;)n++;let a=r[n].split(i).at(-1);a.startsWith("blob:")&&(a=a.slice(5)),a=a.split(")")[0];let o=a.split(":"),s=parseInt(o.at(-2));o[o.length-1]=o.at(-1).split(")")[0];let l=t.file||o.slice(0,-2).join(":"),d=l.split("/").at(-1);try{let t=(await(await fetch(l)).text()).split("\n"),r=t[s-1]?.trim()??"",n=["🐛","🐞","🐜","🦗","🦋","🪲"][Math.floor(6*Math.random())],i=window.self!==window.top,a=`q5.js ${n}`,o=` Error in ${d} on line ${s}:\n\n${r}`;i?e.log(a+o):e.log(`%c${a}%c${o}`,"background: #b7ebff; color: #000;","")}catch(e){}},"undefined"!=typeof window&&window.addEventListener){let t=new Error,r=t.stack?.split("\n")||"";for(let t of r){let r=t.match(/(https?:\/\/[^\s)]+\.js|\b\/[^\s)]+\.js)/);if(r){let t=r[1];if(!/q5|p5play/i.test(t)){e._sketchFile=t;break}}}e._sketchFile&&(window.addEventListener("error",(t=>{let r=t.error;t.filename!==e._sketchFile||r?._handledByFES||(r.file=t.filename,e._fes(r))})),window.addEventListener("unhandledrejection",(t=>{let r=t.reason;r?.stack?.includes(e._sketchFile)&&!r?._handledByFES&&e._fes(r)})))}if(e._isGlobal&&0!=Q5.online&&null!=typeof navigator&&navigator.onLine){!async function(){try{let e=await fetch("https://data.jsdelivr.com/v1/package/npm/q5");if(!e.ok)return;let t=(await e.json()).tags.latest;t=t.slice(0,t.lastIndexOf(".")),t!=Q5.version&&console.warn(`q5.js v${t} is now available! Consider updating from v${Q5.version}.`)}catch(e){}}()}},Q5.modules.input=(e,t)=>{if(e._isGraphics)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.pointers={},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={},n=[Q5.LEFT,Q5.CENTER,Q5.RIGHT],i=e.canvas;e._startAudio=()=>{Q5.aud&&"running"==Q5.aud?.state||e.userStartAudio()},e._updatePointer=r=>{let n=r.pointerId;e.pointers[n]??={event:r};let a,o,s=e.pointers[n];if(s.event=r,i){let t=i.getBoundingClientRect(),n=i.scrollWidth/e.width||1,s=i.scrollHeight/e.height||1;a=(r.clientX-t.left)/n,o=(r.clientY-t.top)/s,e._webgpu&&(a-=i.hw,o-=i.hh)}else a=r.clientX,o=r.clientY;s.x=a,s.y=o,!r.isPrimary&&r.pointerId||(document.pointerLockElement?(t.mouseX+=r.movementX,t.mouseY+=r.movementY):(t.mouseX=a,t.mouseY=o),t.moveX=r.movementX,t.moveY=r.movementY)};let a=0;function o(t){const r=e.canvas.getBoundingClientRect(),n=e.canvas.scrollWidth/e.width||1,i=e.canvas.scrollHeight/e.height||1;let a=0,o=0;return e._webgpu&&(a=e.halfWidth,o=e.halfHeight),{x:(t.clientX-r.left)/n-a,y:(t.clientY-r.top)/i-o,id:t.identifier}}if(e._onpointerdown=r=>{a++,e._startAudio(),e._updatePointer(r),t.mouseIsPressed=!0,t.mouseButton=n[r.button],e.mousePressed(r)},e._onpointermove=t=>{i&&!i.visible||(e._updatePointer(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t))},e._onpointerup=r=>{t.mouseIsPressed=!1,a>0&&(a--,e._updatePointer(r),delete e.pointers[r.pointerId],e.mouseReleased(r))},e._onclick=r=>{e._updatePointer(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e._ondblclick=r=>{e._updatePointer(r),t.mouseIsPressed=!0,e.doubleClicked(r),t.mouseIsPressed=!1},e._onwheel=t=>{e._updatePointer(t),t.delta=t.deltaY;let r=e.mouseWheel(t);(e._isGlobal&&!r||0==r)&&t.preventDefault()},e.cursor=(t,r,n)=>{let i="";t.includes(".")&&(t=`url("${t}")`,i=", auto"),void 0!==r&&(t+=" "+r+" "+n),e.canvas.style.cursor=t+i},e.noCursor=()=>e.canvas.style.cursor="none",e.pointerLock=(e=!1)=>{document.body?.requestPointerLock({unadjustedMovement:e})},e._onkeydown=n=>{n.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=n.key,t.keyCode=n.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(n),1==n.key.length&&e.keyTyped(n))},e._onkeyup=n=>{t.keyIsPressed=!1,t.key=n.key,t.keyCode=n.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(n)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._updateTouches=t=>{if(i&&!i.visible)return;let r=[...t.changedTouches].map(o);for(let t of r){let r=e.touches.find((e=>e.id==t.id));r?(r.x=t.x,r.y=t.y):e.touches.push(t)}for(let r=e.touches.length-1;r>=0;r--){let n=e.touches[r],i=!1;for(let e=0;e<t.touches.length;e++)if(t.touches[e].identifier===n.id){i=!0;break}i||e.touches.splice(r,1)}},e._ontouchstart=t=>{e._startAudio(),e.touchStarted(t)||t.preventDefault()},e._ontouchmove=t=>{e.touchMoved(t)||t.preventDefault()},e._ontouchend=t=>{e.touchEnded(t)||t.preventDefault()},window){let t=window.addEventListener;t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1);let r=window.PointerEvent?"pointer":"mouse";t(r+"move",(t=>e._onpointermove(t)),!1),t(r+"up",(t=>e._onpointerup(t))),t(r+"cancel",(t=>e._onpointerup(t))),t("touchstart",(t=>e._updateTouches(t))),t("touchmove",(t=>e._updateTouches(t))),t("touchend",(t=>e._updateTouches(t))),t("touchcancel",(t=>e._updateTouches(t))),i&&i.addEventListener("wheel",(t=>e._onwheel(t))),!e._isGlobal&&i&&(t=i.addEventListener.bind(i)),t(r+"down",(t=>e._onpointerdown(t))),t("click",(t=>e._onclick(t))),t("dblclick",(t=>e._ondblclick(t))),i&&(t=i.addEventListener.bind(i)),t("touchstart",(t=>e._ontouchstart(t))),t("touchmove",(t=>e._ontouchmove(t))),t("touchend",(t=>e._ontouchend(t))),t("touchcancel",(t=>e._ontouchend(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 n=e._DEGTORAD=Math.PI/180,i=e._RADTODEG=180/Math.PI;function a(){let e,t,r=4294967295;return{setSeed(n){e=t=(n??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,n,i,a)=>{let o=n+1*(e-t)/(r-t)*(i-n);return a?n<i?Math.min(Math.max(o,n),i):Math.min(Math.max(o,i),n):o},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,n)=>e.map(t,r,n,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*n:e),e.cos=e=>Math.cos(r?e*n:e),e.tan=e=>Math.tan(r?e*n: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 n=Math.atan2(e,t);return r?n*i:n};let o=a();o.setSeed(),e.randomSeed=e=>o.setSeed(e),e.random=(e,t)=>void 0===e?o.rand():"number"==typeof e?void 0!==t?o.rand()*(t-e)+e:o.rand()*e:e[Math.trunc(e.length*o.rand())],e.jit=(t=1)=>e.random(-t,t),e.randomGenerator=t=>{t==e.LCG?o=function(){const e=4294967296;let t,r;return{setSeed(n){r=t=(n??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(o=a()),o.setSeed()};var s=new function(){var e,t,r,n=new Array(128),i=new Array(256),a=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*o.rand()-2147483648,u=()=>.5+2.328306e-10*(c()|0),h=()=>{for(var t,i,o,l,d=3.44262;;){if(t=r*a[e],0==e){do{o=u(),l=u(),t=.2904764*-Math.log(o),i=-Math.log(l)}while(i+i<t*t);return r>0?d+t:-d-t}if(s[e]+u()*(s[e-1]-s[e])<Math.exp(-.5*t*t))return t;if(r=c(),e=127&r,Math.abs(r)<n[e])return r*a[e]}},f=()=>{for(var r;;){if(0==e)return 7.69711-Math.log(u());if(r=t*l[e],d[e]+u()*(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=u,this.RNOR=()=>(r=c(),e=127&r,Math.abs(r)<n[e]?r*a[e]:h()),this.REXP=()=>(t=c()>>>0)<n[e=255&t]?t*l[e]:f(),this.zigset=()=>{var e,t,r=2147483648,o=4294967296,c=3.442619855899,u=c,h=.00991256303526217,f=7.697117470131487,p=f,g=.003949659822581572;for(e=h/Math.exp(-.5*c*c),n[0]=Math.floor(c/e*r),n[1]=0,a[0]=e/r,a[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(h/c+Math.exp(-.5*c*c))),n[t+1]=Math.floor(c/u*r),u=c,s[t]=Math.exp(-.5*c*c),a[t]=c/r;for(e=g/Math.exp(-f),i[0]=Math.floor(f/e*o),i[1]=0,l[0]=e/o,l[255]=f/o,d[0]=1,d[255]=Math.exp(-f),t=254;t>=1;t--)f=-Math.log(g/f+Math.exp(-f)),i[t+1]=Math.floor(f/p*o),p=f,d[t]=Math.exp(-f),l[t]=f/o}};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,n=0)=>(l??=new e.NoiseGenerator,l.noise(t,r,n)),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,n=[];for(let e=0;e<256;e++)n[e]=e;for(let i=255;i>0;i--)t=(e=16807*e%2147483647)%(i+1),r=n[i],n[i]=n[t],n[t]=r;return n}dot(e,t,r,n){return e[0]*t+e[1]*r+e[2]*n}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 n=this,i=0,a=1,o=1,s=0;for(let l=0;l<n.octaves;l++){const l=255&Math.floor(e*a),d=255&Math.floor(t*a),c=255&Math.floor(r*a),u=e*a-Math.floor(e*a),h=t*a-Math.floor(t*a),f=r*a-Math.floor(r*a),p=n.fade(u),g=n.fade(h),m=n.fade(f),_=n.p[l]+d,x=n.p[_]+c,v=n.p[_+1]+c,b=n.p[l+1]+d,y=n.p[b]+c,w=n.p[b+1]+c,S=n.mix(n.dot(n.grad3[n.p[x]%12],u,h,f),n.dot(n.grad3[n.p[y]%12],u-1,h,f),p),Q=n.mix(n.dot(n.grad3[n.p[v]%12],u,h-1,f),n.dot(n.grad3[n.p[w]%12],u-1,h-1,f),p),C=n.mix(n.dot(n.grad3[n.p[x+1]%12],u,h,f-1),n.dot(n.grad3[n.p[y+1]%12],u-1,h,f-1),p),M=n.mix(n.dot(n.grad3[n.p[v+1]%12],u,h-1,f-1),n.dot(n.grad3[n.p[w+1]%12],u-1,h-1,f-1),p),P=n.mix(S,Q,g),E=n.mix(C,M,g);i+=n.mix(P,E,m)*o,s+=o,o*=n.falloff,a*=2}return(i/s+1)/2}},Q5.modules.record=(e,t)=>{let r,n,i,a,o,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',[n,a,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 h=d+'"avc1.640034"';e.canvas.width*e.canvas.height>32e5&&MediaRecorder.isTypeSupported(h)&&(r.formats["H.264"]=h),Object.assign(r.formats,t.formats),o=e.createSelect("format");for(const e in r.formats)o.option(e,r.formats[e]);o.title="Video Format",r.append(o);let g=e.createEl("div");g.className="bitrate",g.style.display="flex",r.append(g),s=e.createInput();let m=document.createElement("span");function _(){r.encoderSettings.mimeType=o.value}function x(){r.encoderSettings.videoBitsPerSecond=1e6*s.value}m.textContent="mbps",s.title=m.title="Video Bitrate",g.append(s),g.append(m),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={},o.addEventListener("change",_),s.addEventListener("change",x),Object.defineProperty(r,"bitrate",{get:()=>s.value,set:e=>{s.value=e,x()}}),Object.defineProperty(r,"format",{get:()=>o.selected,set:e=>{e=e.toUpperCase(),r.formats[e]&&(o.selected=e,_())}}),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,n.addEventListener("click",(()=>{e.recording?r.paused?u():e.pauseRecording():c()})),i.addEventListener("click",(()=>{r.paused?e.saveRecording():e.deleteRecording()})),f(),e.registerMethod("post",p)}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(),n=t.createMediaStreamDestination();t.destination.input?t.destination.input.connect(n):Q5.soundOut.connect(n),r.audioTrack=n.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(),f(!0)}}function u(){e.recording&&r.paused&&(r.mediaRecorder.resume(),r.paused=!1,f(!0))}function h(){e.recording&&(r.resetTimer(),r.mediaRecorder.stop(),t.recording=!1,r.paused=!1,r.classList.remove("recording"))}function f(e){n.textContent=e?"⏸":"⏺",n.title=(e?"Pause":"Start")+" Recording",i.textContent=e?"🗑️":"💾",i.title=(e?"Delete":"Save")+" Recording",i.disabled=!e}function p(){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)))}a.textContent=function(){let{hours:e,minutes:t,seconds:n,frames:i}=r.time;return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}:${String(n).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&&u():c()},e.pauseRecording=()=>{e.recording&&!r.paused&&(r.mediaRecorder.pause(),r.paused=!0,f(),n.title="Resume Recording",i.disabled=!1)},e.deleteRecording=()=>{h(),f(),t.recording=!1},e.saveRecording=async n=>{if(!e.recording)return;await new Promise((e=>{r.mediaRecorder.onstop=e,h()}));let i=r.encoderSettings.mimeType,a=i.slice(6,i.indexOf(";")),o=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=o,n??=document.title+" "+(new Date).toLocaleString(void 0,{hour12:!1}).replace(","," at").replaceAll("/","-").replaceAll(":","_"),l.download=`${n}.${a}`,await new Promise((e=>{s.onload=()=>{document.body.removeChild(s),e()},l.click()})),setTimeout((()=>URL.revokeObjectURL(o)),1e3),f(),t.recording=!1}},Q5.modules.sound=(e,t)=>{e.Sound=Q5.Sound;let r=[];e.loadSound=(t,n)=>{let i=new Q5.Sound;return r.push(i),i.promise=(async()=>{let e;i._usedAwait&&(r.splice(r.indexOf(i),1),i=new Q5.Sound,r.push(i));try{await i.load(t)}catch(t){e=t}if(delete i.then,e)throw e;return n&&n(i),i})(),e._loaders.push(i.promise),i.then=(e,t)=>(i._usedAwait=!0,i.promise.then(e,t)),i},e.loadAudio=(t,r)=>{let n=new Audio(t);return n._isAudio=!0,n.crossOrigin="Anonymous",n.promise=new Promise(((e,i)=>{function a(){n.loaded||(delete n.then,n._usedAwait&&(n=new Audio(t),n._isAudio=!0,n.crossOrigin="Anonymous"),n.loaded=!0,r&&r(n),e(n))}n.addEventListener("canplay",a),n.addEventListener("suspend",a),n.addEventListener("error",i)})),e._loaders.push(n.promise),n.then=(e,t)=>(n._usedAwait=!0,n.promise.then(e,t)),n},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 Q5.instances)e._userAudioStarted()}return Q5.aud.resume()}},e._userAudioStarted=()=>{for(let e of r)e.init()},e.outputVolume=e=>{Q5.soundOut&&(Q5.soundOut.gain.value=e)}},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._isSound=!0,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),Q5.aud&&this.init()}init(){this.buffer.length&&(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();return 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.promise=new Promise((e=>{r.onended=()=>{this.paused||(this.ended=!0,this._onended&&this._onended(),this.sources.delete(r),e())}})),r}play(e=0,t){if(!this.loaded)return;let r;if(this.paused){let e=[];for(let t of this.sources)e.push({offset:t._offset,duration:t._duration}),this.sources.delete(t);e.sort(((e,t)=>(e.duration??this.buffer.duration-e.offset)-(t.duration??this.buffer.duration-t.offset)));for(let t of e)r=this._newSource(t.offset,t.duration)}else r=this._newSource(e,t);return this.paused=this.ended=!1,r.promise}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}onended(e){this._onended=e}},Q5.modules.util=(e,t)=>{e._loadFile=(t,r,n)=>{let i={};return i.promise=fetch(t).then((e=>e.ok?"json"==n?e.json():e.text():(reject("error loading file"),null))).then((e=>("csv"==n&&(e=Q5.CSV.parse(e)),"string"==typeof e?i.text=e:Object.assign(i,e),delete i.then,r&&r(e),e))),e._loaders.push(i.promise),i.then=(e,t)=>i.promise.then(e,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"),e.loadXML=(t,r)=>{let n={};return n.promise=fetch(t).then((e=>e.text())).then((e=>{let t=(new DOMParser).parseFromString(e,"application/xml");return n.DOM=t,delete n.then,r&&r(t),t})),e._loaders.push(n.promise),n.then=(e,t)=>n.promise.then(e,t),n};const r=/(jpe?g|png|gif|webp|avif|svg)/i,n=/(ttf|otf|woff2?|eot|json)/i,i=/(serif|sans-serif|monospace|cursive|fantasy)/i,a=/(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/i;async function o(e,t,n){let i;if(t=t||"untitled",n=n||"png",r.test(n)){let t=e.canvas||e;i=await t.convertToBlob({type:"image/"+n})}else{let t="text/plain";"json"==n&&("string"!=typeof e&&(e=JSON.stringify(e)),t="text/json"),i=new Blob([e],{type:t})}let a=document.createElement("a");a.href=URL.createObjectURL(i),a.download=t+"."+n,a.click(),setTimeout((()=>URL.revokeObjectURL(a.href)),1e3)}e.load=function(...t){Array.isArray(t[0])&&(t=t[0]);let o=[];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):n.test(l)||i.test(s)?e.loadFont(s):a.test(l)?e.loadSound(s):"xml"==l?e.loadXML(s):e.loadText(s):e.loadJSON(s),o.push(t)}return 1==t.length?o[0]:Promise.all(o)},e.save=(t,r,n)=>{if((!t||"string"==typeof t&&(!r||!n&&r.length<5))&&(n=r,r=t,t=e),n)o(t,r,n);else if(r){let e=r.lastIndexOf(".");o(t,r.slice(0,e),r.slice(e+1))}else o(t)},e.canvas&&!Q5._createServerCanvas&&(e.canvas.save=e.saveCanvas=e.save),"object"==typeof localStorage&&(e.storeItem=(e,t)=>localStorage.setItem(e,t),e.getItem=e=>localStorage.getItem(e),e.removeItem=e=>localStorage.removeItem(e),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 n=e<0,i=(e=Math.abs(e)).toFixed(r).split(".");i[0]=i[0].padStart(t,"0");let a=i.join(".");return n&&(a="-"+a),a},e.shuffle=(t,r)=>{r||(t=[...t]);for(let r=t.length-1;r>0;r--){let n=Math.floor(e.random()*(r+1));[t[r],t[n]]=[t[n],t[r]]}return t}},Q5.CSV={},Q5.CSV.parse=(e,t=",",r="\n")=>{if(!e.length)return[];let n=[],i=e.split(r),a=i[0].split(t).map((e=>e.replaceAll('"',"")));for(let e=1;e<i.length;e++){let r={},o=i[e].split(t);a.forEach(((e,t)=>r[e]=JSON.parse(o[t]))),n.push(r)}return n},Q5.modules.vector=e=>{e.Vector=Q5.Vector,e.createVector=(t,r,n)=>new e.Vector(t,r,n,e)},Q5.Vector=class{constructor(e,t,r,n){this.x=e||0,this.y=t||0,this.z=r||0,this._isVector=!0,this._$=n||window,this._useCache=!1,this._mag=0,this._magCached=!1,this._direction=0,this._directionCached=!1}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}}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}_calcMag(){const e=this.x,t=this.y,r=this.z;this._mag=Math.sqrt(e*e+t*t+r*r),this._magCached=this._useCache}mag(){return this._magCached||this._calcMag(),this._mag}magSq(){if(this._magCached)return this._mag*this._mag;const e=this.x,t=this.y,r=this.z;return e*e+t*t+r*r}setMag(e){this._magCached||this._calcMag();let t=this._mag;if(0==t){const t=this.direction();this.x=e*this._$.cos(t),this.y=e*this._$.sin(t)}else{let r=e/t;this.x*=r,this.y*=r,this.z*=r}return this._mag=e,this._magCached=this._useCache,this}direction(){if(!this._directionCached){const e=this.x,t=this.y;(e||t)&&(this._direction=this._$.atan2(this.y,this.x)),this._directionCached=this._useCache}return this._direction}setDirection(e){let t=this.mag();return t&&(this.x=t*this._$.cos(e),this.y=t*this._$.sin(e)),this._direction=e,this._directionCached=this._useCache,this}heading(){return this.direction()}setHeading(e){return this.setDirection(e)}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,n=this.z-e.z;return Math.sqrt(t*t+r*r+n*n)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,n=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=n,this}normalize(){this._magCached||this._calcMag();let e=this._mag;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._mag=1,this._magCached=this._useCache,this}limit(e){this._magCached||this._calcMag();let t=this._mag;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._mag=e,this._magCached=this._useCache}return this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),n=this.x*t-this.y*r,i=this.x*r+this.y*t;return this.x=n,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 n=this.mag(),i=r.mag();if(0==n||0==i)return this.mult(1-t).add(r.mult(t));let a=Q5.Vector.cross(this,r),o=a.mag(),s=Math.atan2(o,this.dot(r));if(o>0)a.div(o);else{if(s<this._$.HALF_PI)return this.mult(1-t).add(r.mult(t));0==this.z&&0==r.z?a.set(0,0,1):0!=this.x?a.set(this.y,-this.x,0).normalize():a.set(1,0,0)}let l=a.cross(this),d=1-t+t*i/n,c=d*Math.cos(t*s),u=d*Math.sin(t*s);return this.x=this.x*c+l.x*u,this.y=this.y*c+l.y*u,this.z=this.z*c+l.z*u,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._mag=t,this._magCached=this._useCache,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._mag=r,this._magCached=this._useCache;const n=this._$.cos(t),i=this._$.sin(t),a=this._$.cos(e),o=this._$.sin(e);return this.x=r*o*i,this.y=-r*a,this.z=r*o*n,this}random2D(){return this._mag=1,this._magCached=this._useCache,this.fromAngle(Math.random()*Math.PI*2)}random3D(){return this._mag=1,this._magCached=this._useCache,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.direction=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)=>{const 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 n,i,a,o,s,l,d,c,u,h,f=2,p=12,g=0,m=0;e._pipelineConfigs=[],e._pipelines=[],e._buffers=[];let _=[],x=new Float32Array(1e6);x.set([0,0,0,0,0,0,0,1,1,1,1,1]);let v=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=[v];let b=Q5.device.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),y=()=>{let t=[e.canvas.width,e.canvas.height],r="bgra8unorm";a=Q5.device.createTexture({size:t,sampleCount:4,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}).createView();let n=GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT;e._frameA=s=Q5.device.createTexture({label:"frameA",size:t,format:r,usage:n}),e._frameB=o=Q5.device.createTexture({label:"frameB",size:t,format:r,usage: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]),u=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:d},{binding:2,resource:o.createView()}]}),h=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:d},{binding:2,resource:s.createView()}]})};e._createCanvas=(n,i,a)=>(t.ctx=t.drawingContext=r.getContext("webgpu"),a.format??=navigator.gpu.getPreferredCanvasFormat(),a.device??=Q5.device,a.alpha&&(a.alphaMode="premultiplied"),e.ctx.configure(a),y(),r),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r),y()};let w=!0,S="rgb",Q=1;if(e.colorMode){let t=e.colorMode;e.colorMode=function(){t(...arguments),S=e._colorMode,w="rgb"==S,Q=e._colorFormat}}const C=(t,r,n,i)=>{if(!1===w||void 0===r&&!t._isColor&&"number"!=typeof t?!1!==w&&"string"!=typeof t&&Array.isArray(t)?[t,r,n,i]=t:t=e.color(t,r,n,i):void 0===n&&(i=r??Q,r=n=t),i??=Q,t._isColor){let e=t;w?({r:t,g:r,b:n,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,n]=e)}255===Q&&(t/=255,r/=255,n/=255,i/=255);let a=x,o=p;a[o++]=t,a[o++]=r,a[o++]=n,a[o++]=i,p=o,f++};let M=!0,P=!0,E=!1,I=!1,R=1,A=2,T=2,k=1,O=1,G=.5,D=.25,L=.5;e.fill=(e,t,r,n)=>{C(e,t,r,n),M=E=!0,A=f},e.stroke=(e,t,r,n)=>{C(e,t,r,n),P=I=!0,R=f},e.tint=(e,t,r,n)=>{C(e,t,r,n),T=f},e.opacity=e=>k=e,e.noFill=()=>M=!1,e.noStroke=()=>P=!1,e.noTint=()=>T=2,e.strokeWeight=e=>{if(void 0===e)return O;e?(e=Math.abs(e),O=e,G=e/2,D=e/4,L=G*W):P=!1},e._getStrokeWeight=()=>[O,G,D,L],e._setStrokeWeight=e=>{[O,G,D,L]=e},e._getFillIdx=()=>A,e._setFillIdx=e=>A=e,e._doFill=()=>M=!0,e._getStrokeIdx=()=>R,e._setStrokeIdx=e=>R=e,e._doStroke=()=>P=!0;const F=e._isGraphics?1e3:Q5.MAX_TRANSFORMS,B=16*F*4,z=new Float32Array(16*F);let U,N=[],V=[],H=0,q=!1;N.push([1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1]),z.set(N[0]),e.translate=(e,t)=>{if(!e&&!t)return;let r=U;r[12]+=e*r[0]+t*r[4],r[13]+=e*r[1]+t*r[5],q=!0},e.rotate=e.rotateZ=(t,r)=>{if(!t)return;let n,i;void 0===r?(e._angleMode&&(t*=e._DEGTORAD),n=Math.cos(t),i=Math.sin(t)):(n=t,i=r);let a=U,o=a[0],s=a[1],l=a[4],d=a[5];1!=o||s||l||1!=d?(a[0]=o*n+s*i,a[1]=s*n-o*i,a[4]=l*n+d*i,a[5]=d*n-l*i):(a[0]=n,a[1]=-i,a[4]=i,a[5]=n),q=!0};let W=1;e.scale=(e=1,t,r=1)=>{t??=e,W=Math.max(Math.abs(e),Math.abs(t)),L=G*W;let n=U;n[0]*=e,n[1]*=e,n[2]*=e,n[3]*=e,n[4]*=t,n[5]*=t,n[6]*=t,n[7]*=t,n[8]*=r,n[9]*=r,n[10]*=r,n[11]*=r,q=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),n=U,i=n[0],a=n[1],o=n[4],s=n[5];n[4]=o+i*r,n[5]=s+a*r,q=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),n=U,i=n[0],a=n[1],o=n[4],s=n[5];n[0]=i+o*r,n[1]=a+s*r,q=!0},e.applyMatrix=(...e)=>{let t;if(t=1==e.length?e[0]:e,t.length<=6){t=[t[0],t[1],0,t[2],t[3],0,t[4]||0,t[5]||0,1]}if(t.length<=9)t=[t[0],t[1],0,t[2],t[3],t[4],0,t[5],0,0,1,0,t[6],t[7],0,t[8]];else if(16!=t.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");U=t.slice(),q=!0};const j=()=>{z.set(U,16*N.length),H=N.length,N.push(U.slice()),q=!1};let $=[];e.pushMatrix=()=>{q&&j(),V.push(H),$.push(W)},e.popMatrix=()=>{if(!V.length)return console.warn("Matrix index stack is empty!");let e=V.pop();U=N[e].slice(),H=e,q=!1,W=$.pop(),L=G*W},e.resetMatrix=()=>{U=N[0].slice(),H=0,W=1,L=G},e.resetMatrix();let X=[];e.pushStyles=()=>{X.push([A,R,O,G,W,L,M,P,E,I,k,T,Et,It,Rt,mt,Be,Ke,w,S,Q,e.Color])},e.popStyles=()=>{let t=X.pop();[A,R,O,G,W,L,M,P,E,I,k,T,Et,It,Rt,mt,Be,Ke,w,S,Q]=t,e._colorFormat=Q,e._colorMode=S,e.Color=t.at(-1)},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()};let Y=[0,0,0,0];const J=(e,t,r,n,i)=>{let a,o,s,l;if(i&&"corner"!=i)if("center"==i){let i=r/2,d=n/2;a=e-i,o=e+i,s=t-d,l=t+d}else a=e,o=r,s=t,l=n;else a=e,o=e+r,s=t,l=t+n;return Y[0]=a,Y[1]=o,Y[2]=s,Y[3]=l,Y};let K=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],Z=["add","subtract","reverse-subtract","min","max"];const ee={"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]};let te=Object.keys(ee);e.blendConfigs={};for(const[t,r]of Object.entries(ee))e.blendConfigs[t]={color:{srcFactor:K[r[0]],dstFactor:K[r[1]],operation:Z[r[2]]},alpha:{srcFactor:K[r[3]],dstFactor:K[r[4]],operation:Z[r[5]]}};let re,ne,ie,ae,oe,se,le,de,ce,ue,he="source-over";e.blendMode=e=>{if(e==he)return;he=e;let t=te.indexOf(e);-1!=t?_.push(0,t):console.error(`Blend mode "${e}" not supported in q5.js WebGPU.`)},e.clear=()=>{re=!0},e.background=(t,n,i,a)=>{if(t.canvas){e.push(),e.resetMatrix();let n=t;mt="corner",e.image(n,-r.hw,-r.hh,r.w,r.h),e.pop()}else{C(t,n,i,a);let e=-r.hw,o=r.hw,s=-r.hh,l=r.hh;Pe(e,s,o,s,o,l,e,l,f,0)}},e._beginRender=()=>{const t=o;o=s,s=t;const r=u;u=h,h=r,n=Q5.device.createCommandEncoder(),e._pass=i=n.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:a,resolveTarget:o.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=h,re||(i.setPipeline(e._pipelines[g]),i.setBindGroup(0,c),i.draw(4)),re=!1},e._render=()=>{let t=16*N.length*4;(!ne||ne.size<t)&&(ne&&ne.destroy(),ne=Q5.device.createBuffer({size:Math.min(2*t,B),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(ne,0,z.subarray(0,16*N.length));let r=4*p;(!ie||ie.size<r)&&(ie&&ie.destroy(),ie=Q5.device.createBuffer({size:2*r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(ie,0,x.subarray(0,p)),e._uniforms[0]=e.width,e._uniforms[1]=e.height,e._uniforms[2]=e.halfWidth,e._uniforms[3]=e.halfHeight,e._uniforms[4]=e._pixelDensity,e._uniforms[5]=e.frameCount,e._uniforms[6]=performance.now(),e._uniforms[7]=e.deltaTime,e._uniforms[8]=e.mouseX,e._uniforms[9]=e.mouseY,e._uniforms[10]=e.mouseIsPressed?1:0,e._uniforms[11]=e.keyCode,e._uniforms[12]=e.keyIsPressed?1:0,Q5.device.queue.writeBuffer(b,0,e._uniforms),de&&ce===ne&&ue===ie||(de=Q5.device.createBindGroup({layout:v,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:{buffer:ne}},{binding:2,resource:{buffer:ie}}]}),ce=ne,ue=ie),i.setBindGroup(0,de),e._pass.setPipeline(e._pipelines[1]);let n=4*me;if((!ae||ae.size<n)&&(ae&&ae.destroy(),ae=Q5.device.createBuffer({size:2*n,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(ae,0,ge.subarray(0,me)),e._pass.setVertexBuffer(0,ae),ot){e._pass.setPipeline(e._pipelines[2]);let t=4*ot;(!oe||oe.size<t)&&(oe&&oe.destroy(),oe=Q5.device.createBuffer({size:2*t,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(oe,0,at.subarray(0,ot)),e._pass.setVertexBuffer(1,oe),pt&&(e._pass.setPipeline(e._pipelines[3]),e._pass.setVertexBuffer(1,oe))}if(Ft.length){let t=0;for(let e of Ft)Ut.set(e,t),t+=e.length;let r=4*t;(!se||se.size<r)&&(se&&se.destroy(),se=Q5.device.createBuffer({size:2*r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(se,0,Ut.buffer,0,r);let n=0;for(let e of Bt)Nt.set(e,n),n+=e.length;let i=4*n;(!le||le.size<i)&&(le&&le.destroy(),le=Q5.device.createBuffer({label:"textBuffer",size:2*i,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})),Q5.device.queue.writeBuffer(le,0,Nt.buffer,0,i),e._textBindGroup=Q5.device.createBindGroup({label:"textBindGroup",layout:bt,entries:[{binding:0,resource:{buffer:se}},{binding:1,resource:{buffer:le}}]})}Q5.device.queue.writeBuffer(De,0,Oe.buffer,Oe.byteOffset,4*Ge),Q5.device.queue.writeBuffer(Xe,0,je.buffer,je.byteOffset,4*$e);let a=0,o=0,s=0,l=0,d=0,c=-1;for(let t=0;t<_.length;t+=2){let r=_[t+1];if(_[t]!=c){if(0==_[t]){let t=te[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}c=_[t],i.setPipeline(e._pipelines[c]),5==c?(i.setIndexBuffer(Ae,"uint16"),i.setBindGroup(1,Le)):6==c&&(i.setIndexBuffer(He,"uint16"),i.setBindGroup(1,Ye))}if(6==c)i.drawIndexed(18,r,0,0,d),d+=r;else if(5==c)i.drawIndexed(6,r,0,0,l),l+=r;else if(4==c||c>=4e3){let n=_[t+2];i.setBindGroup(1,Mt[n].bindGroup),i.setBindGroup(2,e._textBindGroup),i.draw(4,r,0,s),s+=r,t++}else 2==c||3==c||c>=2e3?(i.setBindGroup(1,e._textureBindGroups[r]),i.draw(4,1,o),o+=4):(i.draw(r,1,a),a+=r)}},e._finishRender=()=>{i.end(),i=n.beginRenderPass({colorAttachments:[{view:a,resolveTarget:e.ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=u,i.setPipeline(e._pipelines[m]),i.setBindGroup(0,c),i.draw(4),i.end(),Q5.device.queue.submit([n.finish()]),e._pass=i=n=null,_.length=0,f=2,p=12,N.length=1,V.length=0,e._texture=o,me=0,ot=0,pt>0&&(e._textureBindGroups.length=ft),pt=0,Ft.length=0,Bt.length=0,Ge=0,$e=0,Q5.device.queue.onSubmittedWorkDone().then((()=>{for(let t of e._buffers)t.destroy();e._buffers=[]}))};let fe=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 pe=Q5.device.createShaderModule({label:"shapesShader",code:e._shapesShaderCode}),ge=new Float32Array(e._isGraphics?1e3:1e7),me=0;const _e=2*Math.PI;Math.PI;let xe=Q5.device.createPipelineLayout({label:"shapesPipelineLayout",bindGroupLayouts:e._bindGroupLayouts});e._pipelineConfigs[1]={label:"shapesPipeline",layout:xe,vertex:{module:pe,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:pe,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 ve=(e,t,r,n)=>{let i=ge,a=me;i[a++]=e,i[a++]=t,i[a++]=r,i[a++]=n,me=a};let be="round",ye="round";e.strokeCap=e=>be=e,e.strokeJoin=e=>ye=e,e.lineMode=()=>{be="square",ye="none"};let we=20;e.curveDetail=e=>we=e;let Se,Qe=20;e.bezierDetail=e=>Qe=e;let Ce=[],Me=[];function Pe(e,t,r,n,i,a,o,s,l,d){ve(e,t,l,d),ve(r,n,l,d),ve(o,s,l,d),ve(i,a,l,d),_.push(fe,4)}e.beginShape=()=>{Se=0,Ce=[],Me=[]},e.vertex=(e,t)=>{q&&j(),Ce.push(e,t,A,H),Se++},e.curveVertex=(e,t)=>{q&&j(),Me.push({x:e,y:t})},e.bezierVertex=function(e,t,r,n,i,a){if(0===Se)throw new Error("Shape needs a vertex()");q&&j();let o,s,l=4*(Se-1),d=Ce[l],c=Ce[l+1],u=1/Qe,h=4==arguments.length;h&&(i=r,a=n);let f=1+u;for(let l=u;l<=f;l+=u){let u=l*l,f=1-l,p=f*f;if(h)o=p*d+2*f*l*e+u*i,s=p*c+2*f*l*t+u*a;else{let h=u*l,g=p*f;o=g*d+3*p*l*e+3*f*u*r+h*i,s=g*c+3*p*l*t+3*f*u*n+h*a}Ce.push(o,s,A,H),Se++}},e.quadraticVertex=(t,r,n,i)=>e.bezierVertex(t,r,n,i),e.endShape=t=>{if(Me.length>0){let e=[...Me];if(e.length<4)for(;e.length<4;)e.unshift(e[0]),e.push(e[e.length-1]);let t=1/we;for(let r=0;r<e.length-3;r++){let n=e[r],i=e[r+1],a=e[r+2],o=e[r+3];for(let e=0;e<=1;e+=t){let t=e*e,r=t*e,s=.5*(2*i.x+(-n.x+a.x)*e+(2*n.x-5*i.x+4*a.x-o.x)*t+(-n.x+3*i.x-3*a.x+o.x)*r),l=.5*(2*i.y+(-n.y+a.y)*e+(2*n.y-5*i.y+4*a.y-o.y)*t+(-n.y+3*i.y-3*a.y+o.y)*r);Ce.push(s,l,A,H),Se++}}}if(Se){if(1==Se)return e.point(Ce[0],Ce[1]);if(2==Se)return e.line(Ce[0],Ce[1],Ce[4],Ce[5]);if(t){let e=0,t=4*(Se-1),r=Ce[e],n=Ce[e+1],i=Ce[t],a=Ce[t+1];r===i&&n===a||(Ce.push(r,n,Ce[e+2],Ce[e+3]),Se++)}if(M)if(5==Se)ve(Ce[0],Ce[1],Ce[2],Ce[3]),ve(Ce[4],Ce[5],Ce[6],Ce[7]),ve(Ce[12],Ce[13],Ce[14],Ce[15]),ve(Ce[8],Ce[9],Ce[10],Ce[11]),_.push(fe,4);else{for(let e=1;e<Se-1;e++){let t=0,r=4*e,n=4*(e+1);ve(Ce[t],Ce[t+1],Ce[t+2],Ce[t+3]),ve(Ce[r],Ce[r+1],Ce[r+2],Ce[r+3]),ve(Ce[n],Ce[n+1],Ce[n+2],Ce[n+3])}_.push(fe,3*(Se-2))}if(P){for(let t=0;t<Se-1;t++){let r=4*t,n=4*(t+1);e.line(Ce[r],Ce[r+1],Ce[n],Ce[n+1])}let r=4*(Se-1),n=0;t&&e.line(Ce[r],Ce[r+1],Ce[n],Ce[n+1])}Se=0,Ce=[],Me=[]}},e.curve=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(n,i),e.curveVertex(a,o),e.curveVertex(s,l),e.endShape()},e.bezier=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(n,i,a,o,s,l),e.endShape()},e.triangle=(t,r,n,i,a,o)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.endShape(!0)},e.quad=(t,r,n,i,a,o,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(n,i),e.vertex(a,o),e.vertex(s,l),e.endShape(!0)},e.plane=(e,t,r,n)=>{n??=r;let[i,a,o,s]=J(e,t,r,n,"center");q&&j(),Pe(i,o,a,o,a,s,i,s,A,H)};let Ee=5;e._rectShaderCode=e._baseShaderCode+"\nstruct Rect {\n\tcenter: vec2f,\n\textents: vec2f,\n\troundedRadius: f32,\n\tstrokeWeight: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tmatrixIndex: f32,\n\tpadding0: f32, // can't use vec3f for alignment\n\tpadding1: vec2f,\n\tpadding2: vec4f\n};\n\nstruct VertexParams {\n\t@builtin(vertex_index) vertIndex: u32,\n\t@builtin(instance_index) instIndex: u32\n};\n\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) local: vec2f,\n\t@location(1) extents: vec2f,\n\t@location(2) roundedRadius: f32,\n\t@location(3) strokeWeight: f32,\n\t@location(4) fill: vec4f,\n\t@location(5) stroke: vec4f,\n\t@location(6) blend: 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\n@group(1) @binding(0) var<storage, read> rects: array<Rect>;\n\nconst quad = array(\n\tvec2f(-1.0, -1.0),\n\tvec2f( 1.0, -1.0),\n\tvec2f(-1.0, 1.0),\n\tvec2f( 1.0, 1.0)\n);\nconst transparent = vec4f(0.0);\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\tlet rect = rects[v.instIndex];\n\n\tlet halfStrokeSize = vec2f(rect.strokeWeight * 0.5);\n\tlet quadSize = rect.extents + halfStrokeSize;\n\tlet pos = (quad[v.vertIndex] * quadSize) + rect.center;\n\n\tlet local = pos - rect.center;\n\n\tvar f: FragParams;\n\tf.position = transformVertex(pos, rect.matrixIndex);\n\n\tf.local = local;\n\tf.extents = rect.extents;\n\tf.roundedRadius = rect.roundedRadius;\n\tf.strokeWeight = rect.strokeWeight;\n\n\tlet fill = colors[i32(rect.fillIndex)];\n\tlet stroke = colors[i32(rect.strokeIndex)];\n\tf.fill = fill;\n\tf.stroke = stroke;\n\n\t// Source-over blend: stroke over fill (pre-multiplied alpha)\n\tif (fill.a != 0.0 && stroke.a != 1.0) {\n\t\tlet outAlpha = stroke.a + fill.a * (1.0 - stroke.a);\n\t\tlet outColor = stroke.rgb * stroke.a + fill.rgb * fill.a * (1.0 - stroke.a);\n\t\tf.blend = vec4f(outColor / max(outAlpha, 1e-5), outAlpha);\n\t}\n\treturn f;\n}\n\nfn sdRoundRect(p: vec2f, extents: vec2f, radius: f32) -> f32 {\n\tlet q = abs(p) - extents + vec2f(radius);\n\treturn length(max(q, vec2f(0.0))) - radius + min(max(q.x, q.y), 0.0);\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tlet dist = select(\n\t\tmax(abs(f.local.x) - f.extents.x, abs(f.local.y) - f.extents.y), // sharp\n\t\tsdRoundRect(f.local, f.extents, f.roundedRadius), // rounded\n\t\tf.roundedRadius > 0.0\n\t);\n\n\t// fill only\n\tif (f.fill.a != 0.0 && f.strokeWeight == 0.0) {\n\t\tif (dist <= 0.0) {\n\t\t\treturn f.fill;\n\t\t}\n\t\treturn transparent;\n\t}\n\n\tlet halfStroke = f.strokeWeight * 0.5;\n\tlet inner = dist + halfStroke;\n\n\tif (f.fill.a != 0.0) {\n\t\tif (inner <= 0.0) {\n\t\t\treturn f.fill;\n\t\t}\n\t\tif (dist <= 0.0 && f.stroke.a != 1.0) {\n\t\t\treturn f.blend;\n\t\t}\n\t}\n\n\tlet outer = dist - halfStroke;\n\n\tif (outer <= 0.0 && inner >= 0.0) {\n\t\treturn f.stroke;\n\t}\n\n\treturn transparent;\n}\n\t";let Ie=Q5.device.createShaderModule({label:"rectShader",code:e._rectShaderCode}),Re=new Uint16Array([0,1,2,2,1,3]),Ae=Q5.device.createBuffer({size:Re.byteLength,usage:GPUBufferUsage.INDEX,mappedAtCreation:!0});new Uint16Array(Ae.getMappedRange()).set(Re),Ae.unmap();let Te=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),ke=Q5.device.createPipelineLayout({label:"rectPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,Te]});e._pipelineConfigs[5]={label:"rectPipeline",layout:ke,vertex:{module:Ie,entryPoint:"vertexMain",buffers:[]},fragment:{module:Ie,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-list"},multisample:{count:4}},e._pipelines[5]=Q5.device.createRenderPipeline(e._pipelineConfigs[5]);let Oe=new Float32Array(16*Q5.MAX_RECTS),Ge=0,De=Q5.device.createBuffer({size:Oe.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Le=Q5.device.createBindGroup({layout:Te,entries:[{binding:0,resource:{buffer:De}}]});function Fe(e,t,r,n,i,a,o){let s=Oe,l=Ge;s[l]=e,s[l+1]=t,s[l+2]=r,s[l+3]=n,s[l+4]=i,s[l+5]=a,s[l+6]=o,s[l+7]=R,s[l+8]=H,Ge+=16,_.push(Ee,1)}let Be="corner";e.rectMode=e=>Be=e,e._getRectMode=()=>Be;let ze=[0,0,0,0];function Ue(t,r,n,i,a,o,s){let l=n-t,d=i-r,c=Math.hypot(l,d);if(0===c)return;let u=Math.atan2(d,l),h=(t+n)/2,f=(r+i)/2;e._angleMode&&(u*=e._RADTODEG),e.pushMatrix(),e.translate(h,f),e.rotate(u),q&&j(),Fe(0,0,c/2+a,a,a,o,s),e.popMatrix()}e.rect=(e,t,r,n,i=0)=>{let a,o;q&&j(),[e,t,a,o]=function(e,t,r,n){let i=r/2,a=n/2;return"center"!=Be&&("corner"==Be?(e+=i,t+=a,i=Math.abs(i),a=Math.abs(a)):"radius"==Be?(i=r,a=n):"corners"==Be&&(i=Math.abs((r-e)/2),a=Math.abs((n-t)/2),e=(e+r)/2,t=(t+n)/2)),ze[0]=e,ze[1]=t,ze[2]=i,ze[3]=a,ze}(e,t,r,n),Fe(e,t,a,o,i,P?O:0,M?A:0)},e.square=(t,r,n,i)=>e.rect(t,r,n,n,i),e.capsule=(e,t,r,n,i)=>{Ue(e,t,r,n,i,P?O:0,M?A:0)},e.line=(e,t,r,n)=>{P&&Ue(e,t,r,n,D,G,0)};e._ellipseShaderCode=e._baseShaderCode+"\nstruct Ellipse {\n\tcenter: vec2f,\n\tsize: vec2f,\n\tstartAngle: f32,\n\tendAngle: f32,\n\tstrokeWeight: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tmatrixIndex: f32,\n\tpadding0: vec2f,\n\tpadding1: vec4f\n};\n\nstruct VertexParams {\n\t@builtin(vertex_index) vertIndex: u32,\n\t@builtin(instance_index) instIndex: u32\n};\n\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) outerEdge: vec2f,\n\t@location(1) fillEdge: vec2f,\n\t@location(2) innerEdge: vec2f,\n\t@location(3) strokeWeight: f32,\n\t@location(4) fill: vec4f,\n\t@location(5) stroke: vec4f,\n\t@location(6) blend: 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\n@group(1) @binding(0) var<storage, read> ellipses: array<Ellipse>;\n\nconst PI = 3.141592653589793;\nconst segments = 6.0;\nconst expansion = 1.0 / cos(PI / segments);\nconst antiAlias = 0.015625; // 1/64\nconst transparent = vec4f(0.0);\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\tlet ellipse = ellipses[v.instIndex];\n\tvar pos = ellipse.center;\n\tvar local = vec2f(0.0);\n\tlet start = ellipse.startAngle;\n\tlet end = ellipse.endAngle;\n\tlet arc = end - start;\n\tlet halfStrokeSize = vec2f(ellipse.strokeWeight * 0.5);\n\n\tlet fanSize = (ellipse.size + halfStrokeSize) * expansion;\n\n\tif (v.vertIndex != 0) {\n\t\tlet theta = start + (f32(v.vertIndex - 1) / segments) * arc;\n\t\tlocal = vec2f(cos(theta), sin(theta));\n\t\tpos = ellipse.center + local * fanSize;\n\t}\n\n\tlet dist = pos - ellipse.center;\n\n\tvar f: FragParams;\n\tf.position = transformVertex(pos, ellipse.matrixIndex);\n\tf.outerEdge = dist / (ellipse.size + halfStrokeSize);\n\tf.fillEdge = dist / ellipse.size;\n\tf.innerEdge = dist / (ellipse.size - halfStrokeSize);\n\tf.strokeWeight = ellipse.strokeWeight;\n\n\tlet fill = colors[i32(ellipse.fillIndex)];\n\tlet stroke = colors[i32(ellipse.strokeIndex)];\n\tf.fill = fill;\n\tf.stroke = stroke;\n\n\t// Source-over blend: stroke over fill (pre-multiplied alpha)\n\tif (fill.a != 0.0 && stroke.a != 1.0) {\n\t\tlet outAlpha = stroke.a + fill.a * (1.0 - stroke.a);\n\t\tlet outColor = stroke.rgb * stroke.a + fill.rgb * fill.a * (1.0 - stroke.a);\n\t\tf.blend = vec4f(outColor / max(outAlpha, 1e-5), outAlpha);\n\t}\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tlet fillEdge = length(f.fillEdge);\n\n\t// disable AA for very thin strokes\n\tlet aa = select(antiAlias, 0.0, f.strokeWeight <= 1.0);\n\n\tif (f.fill.a != 0.0 && f.strokeWeight == 0.0) {\n\t\tif (fillEdge > 1.0) {\n\t\t\treturn transparent;\n\t\t}\n\t\tlet fillAlpha = 1.0 - smoothstep(1.0 - aa, 1.0, fillEdge);\n\t\treturn vec4f(f.fill.rgb, f.fill.a * fillAlpha);\n\t}\n\n\tlet innerEdge = length(f.innerEdge);\n\t\n\tif (f.fill.a != 0.0 && fillEdge < 1.0) {\n\t\tif (innerEdge < 1.0) {\n\t\t\treturn f.fill;\n\t\t}\n\t\tlet tInner = smoothstep(1.0, 1.0 + aa, innerEdge);\n\t\tlet tOuter = smoothstep(1.0 - aa, 1.0, fillEdge);\n\t\tif (f.stroke.a != 1.0) {\n\t\t\tlet fillBlend = mix(f.fill, f.blend, tInner);\n\t\t\treturn mix(fillBlend, f.stroke, tOuter);\n\t\t} else {\n\t\t\tlet fillBlend = mix(f.fill, f.stroke, tInner);\n\t\t\treturn mix(fillBlend, f.stroke, tOuter);\n\t\t}\n\t}\n\t\n\tif (innerEdge < 1.0) {\n\t\treturn transparent;\n\t}\n\n\tlet outerEdge = length(f.outerEdge);\n\tlet outerAlpha = 1.0 - smoothstep(1.0 - aa, 1.0, outerEdge);\n\tlet innerAlpha = smoothstep(1.0, 1.0 + aa, innerEdge);\n\tlet strokeAlpha = innerAlpha * outerAlpha;\n\treturn vec4f(f.stroke.rgb, f.stroke.a * strokeAlpha);\n}\n\t\t";let Ne=Q5.device.createShaderModule({label:"ellipseShader",code:e._ellipseShaderCode}),Ve=new Uint16Array([0,1,2,0,2,3,0,3,4,0,4,5,0,5,6,0,6,7]),He=Q5.device.createBuffer({size:Ve.byteLength,usage:GPUBufferUsage.INDEX,mappedAtCreation:!0});new Uint16Array(He.getMappedRange()).set(Ve),He.unmap();let qe=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),We=Q5.device.createPipelineLayout({label:"ellipsePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,qe]});e._pipelineConfigs[6]={label:"ellipsePipeline",layout:We,vertex:{module:Ne,entryPoint:"vertexMain",buffers:[]},fragment:{module:Ne,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs["source-over"]}]},primitive:{topology:"triangle-list"},multisample:{count:4}},e._pipelines[6]=Q5.device.createRenderPipeline(e._pipelineConfigs[6]);let je=new Float32Array(16*Q5.MAX_ELLIPSES),$e=0,Xe=Q5.device.createBuffer({size:je.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Ye=Q5.device.createBindGroup({layout:qe,entries:[{binding:0,resource:{buffer:Xe}}]});function Je(e,t,r,n,i,a,o,s){let l=je,d=$e;l[d]=e,l[d+1]=t,l[d+2]=r,l[d+3]=n,l[d+4]=i,l[d+5]=a,l[d+6]=o,l[d+7]=s?A:0,l[d+8]=R,l[d+9]=H,$e+=16,_.push(6,1)}let Ke="center";e.ellipseMode=e=>Ke=e,e._getEllipseMode=()=>Ke;let Ze=[0,0,0,0];function et(e,t,r,n){let i,a;return n??=r,"center"==Ke?(i=r/2,a=n/2):"radius"==Ke?(i=r,a=n):"corner"==Ke?(e+=r/2,t+=n/2,i=r/2,a=n/2):"corners"==Ke&&(i=r-(e=(e+r)/2),a=n-(t=(t+n)/2)),Ze[0]=e,Ze[1]=t,Ze[2]=i,Ze[3]=a,Ze}e.ellipse=(e,t,r,n)=>{let i,a;[e,t,i,a]=et(e,t,r,n),q&&j(),Je(e,t,i,a,0,_e,P?O:0,M)},e.circle=(t,r,n)=>e.ellipse(t,r,n,n),e.arc=(t,r,n,i,a,o)=>{if(a===o)return e.ellipse(t,r,n,i);if(e._angleMode&&(a=e.radians(a),o=e.radians(o)),(a%=_e)<0&&(a+=_e),(o%=_e)<0&&(o+=_e),a>o&&(o+=_e),a==o)return e.ellipse(t,r,n,i);let s,l;[t,r,s,l]=et(t,r,n,i),q&&j(),Je(t,r,s,l,a,o,P?O:0,M)},e.point=(e,t)=>{q&&j(),L<=.5?Fe(e,t,G,G,0,O,0):Je(e,t,G,G,0,_e,O,0)};let tt=2,rt=3;e._imageShaderCode=e._baseShaderCode+"\n\tstruct VertexParams {\n\t\t@builtin(vertex_index) vertexIndex : u32,\n\t\t@location(0) pos: vec2f,\n\t\t@location(1) texCoord: vec2f,\n\t\t@location(2) tintIndex: f32,\n\t\t@location(3) matrixIndex: f32,\n\t\t@location(4) imageAlpha: f32\n\t}\n\tstruct FragParams {\n\t\t@builtin(position) position: vec4f,\n\t\t@location(0) texCoord: vec2f,\n\t\t@location(1) tintColor: vec4f,\n\t\t@location(2) imageAlpha: f32\n\t}\n\t\n\t@group(0) @binding(0) var<uniform> q: Q5;\n\t@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n\t@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\t\n\t@group(1) @binding(0) var samp: sampler;\n\t@group(1) @binding(1) var tex: texture_2d<f32>;\n\t\n\tfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\t\tvar vert = vec4f(pos, 0f, 1f);\n\t\tvert = transforms[i32(matrixIndex)] * vert;\n\t\tvert.x /= q.halfWidth;\n\t\tvert.y /= q.halfHeight;\n\t\treturn vert;\n\t}\n\t\n\tfn applyTint(texColor: vec4f, tintColor: vec4f) -> vec4f {\n\t\t// apply the tint color to the sampled texture color at full strength\n\t\tlet tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a);\n\t\t// mix in the tint using the tint alpha as the blend strength\n\t\treturn mix(texColor, tinted, tintColor.a);\n\t}\n\t\n\t@vertex\n\tfn vertexMain(v: VertexParams) -> FragParams {\n\t\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\t\n\t\tvar f: FragParams;\n\t\tf.position = vert;\n\t\tf.texCoord = v.texCoord;\n\t\tf.tintColor = colors[i32(v.tintIndex)];\n\t\tf.imageAlpha = v.imageAlpha;\n\t\treturn f;\n\t}\n\t\n\t@fragment\n\tfn fragMain(f: FragParams) -> @location(0) vec4f {\n\t\tvar texColor = textureSample(tex, samp, f.texCoord);\n\t\ttexColor.a *= f.imageAlpha;\n\t\treturn applyTint(texColor, f.tintColor);\n\t}\n\t";let nt=Q5.device.createShaderModule({label:"imageShader",code:e._imageShaderCode});e._videoShaderCode=e._imageShaderCode.replace("texture_2d<f32>","texture_external").replace("textureSample","textureSampleBaseClampToEdge");let it=Q5.device.createShaderModule({label:"videoShader",code:e._videoShaderCode}),at=new Float32Array(e._isGraphics?1e3:1e7),ot=0,st={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"}]},lt=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]}),dt=Q5.device.createBindGroupLayout({label:"videoTextureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,externalTexture:{}}]}),ct=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,lt]}),ut=Q5.device.createPipelineLayout({label:"videoPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,dt]});e._pipelineConfigs[2]={label:"imagePipeline",layout:ct,vertex:{module:nt,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},st]},fragment:{module:nt,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:ut,vertex:{module:it,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},st]},fragment:{module:it,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=[],r&&(r.convertToBlob=async t=>{let r=e._drawStack?.length;r&&(e._render(),e._finishRender());let n=e._texture;r&&e._beginRender();let i=n.width,a=n.height,o=256*Math.ceil(4*i/256),s=Q5.device.createBuffer({size:o*a,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),l=Q5.device.createCommandEncoder();l.copyTextureToBuffer({texture:n},{buffer:s,bytesPerRow:o,rowsPerImage:a},{width:i,height:a}),Q5.device.queue.submit([l.finish()]),await s.mapAsync(GPUMapMode.READ);let d=new Uint8Array(s.getMappedRange()),c=new Uint8Array(i*a*4);for(let e=0;e<a;e++){const t=e*o,r=e*i*4;for(let e=0;e<i;e++){const n=t+4*e,i=r+4*e;c[i+0]=d[n+2],c[i+1]=d[n+1],c[i+2]=d[n+0],c[i+3]=d[n+3]}}s.unmap();let u=e.canvas.colorSpace;c=new Uint8ClampedArray(c.buffer),c=new ImageData(c,i,a,{colorSpace:u});let h=new OffscreenCanvas(i,a);return h.getContext("2d",{colorSpace:u}).putImageData(c,0,0),e._buffers.push(s),await h.convertToBlob(t)});let ht=t=>{e._imageSampler=Q5.device.createSampler({magFilter:t,minFilter:t})};e.smooth=()=>ht("linear"),e.noSmooth=()=>ht("nearest"),e.smooth();let ft=0,pt=0;e._addTexture=(t,r)=>{let n=t.canvas||t;if(!r){if(t._texture)return;let i=[n.width,n.height,1];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:n},{texture:r,colorSpace:e.canvas.colorSpace},i)}r.index=ft+pt,t._texture=r,e._textureBindGroups[r.index]=Q5.device.createBindGroup({label:t.src||r.label||"canvas",layout:lt,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r.createView()}]}),ft++},e.loadImage=(t,r)=>e._g.loadImage(t,(t=>{e._makeDrawable(t),r&&r(t)})),e._makeDrawable=t=>{e._addTexture(t),t._owner=e},e.createImage=(t,r,n)=>{let i=e._g.createImage(t,r,n);return e._makeDrawable(i),i.modified=!0,i};let gt=e.createGraphics;e.createGraphics=(t,r,n={})=>{if(!Q5.experimental)throw new Error("createGraphics is disabled by default in q5 WebGPU. See issue https://github.com/q5js/q5.js/issues/104 for details.");"string"==typeof n&&(n={renderer:n}),n.renderer??="c2d";let i=gt(t,r,n);return i.canvas.webgpu?(e._addTexture(i,i._frameA),e._addTexture(i,i._frameB),i._beginRender()):(e._makeDrawable(i),i.modified=!0),i};let mt="corner";e.imageMode=e=>mt=e,e._getImageMode=()=>mt,e._uniforms=new Float32Array(13);const _t=(e,t,r,n,i,a,o)=>{let s=at,l=ot;s[l++]=e,s[l++]=t,s[l++]=r,s[l++]=n,s[l++]=i,s[l++]=a,s[l++]=o,ot=l};e.image=(t,r=0,n=0,i,a,o=0,s=0,l,d)=>{if(!t)return;let c;if(null==t._texture){if(c="VIDEO"==t.tagName,!t.width||c&&!t.currentTime)return;t.flipped&&e.scale(-1,1)}q&&j();let u=t.canvas||t,h=u.width,f=u.height,p=t._pixelDensity||1,g=t._isGraphics&&t._drawStack?.length;g&&(t._render(),t._finishRender()),t.modified&&(Q5.device.queue.copyExternalImageToTexture({source:u},{texture:t._texture,colorSpace:e.canvas.colorSpace},[h,f,1]),t.frameCount++,t.modified=!1),i??=t.defaultWidth||t.videoWidth,a??=t.defaultHeight||t.videoHeight,l??=h,d??=f,o*=p,s*=p;let[m,x,v,b]=J(r,n,i,a,mt),y=o/h,w=s/f,S=(o+l)/h,Q=(s+d)/f,C=H,M=T,P=k;if(_t(m,v,y,w,M,C,P),_t(x,v,S,w,M,C,P),_t(m,b,y,Q,M,C,P),_t(x,b,S,Q,M,C,P),c){let r=Q5.device.importExternalTexture({source:t});e._textureBindGroups.push(Q5.device.createBindGroup({layout:dt,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r}]})),_.push(rt,e._textureBindGroups.length-1),t.flipped&&e.scale(-1,1)}else _.push(tt,t._texture.index),g&&(t.resetMatrix(),t._beginRender(),t.frameCount++)};let xt=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 vt=Q5.device.createShaderModule({label:"textShader",code:e._textShaderCode}),bt=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"}}]}),yt=Q5.device.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:16}),wt=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"}}]}),St=Q5.device.createPipelineLayout({bindGroupLayouts:[...e._bindGroupLayouts,wt,bt]});e._pipelineConfigs[4]={label:"textPipeline",layout:St,vertex:{module:vt,entryPoint:"vertexMain"},fragment:{module:vt,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 Qt{constructor(e,t,r,n){this.bindGroup=e,this.lineHeight=t,this.chars=r,this.kernings=n;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 n=this.kernings.get(e);if(n)return r.xadvance+(n.get(t)??0)}return r.xadvance}}let Ct,Mt=[],Pt={};e.loadFont=(t="sans-serif",r)=>{if(Ct=!0,t.startsWith("https://fonts.googleapis.com/css"))return e._g.loadFont(t,r);let n=t.slice(t.lastIndexOf(".")+1);if(t==n){let e=t;Pt[e]=null,t=`https://q5js.org/fonts/${e}-msdf.json`,0!=Q5.online&&navigator.onLine||(t=`/node_modules/q5/builtinFonts/${e}-msdf.json`),n="json"}if("json"!=n)return e._g.loadFont(t,r);let i=t.slice(t.lastIndexOf("/")+1,t.lastIndexOf("-")),a={family:i};return a.promise=async function(t,r,n){let i,a,o=t.substring(0,t.lastIndexOf("-"));try{[i,a]=await Promise.all([fetch(t).then((e=>{if(404==e.status)throw new Error("404");return e.json()})),fetch(o+".png").then((e=>e.blob())).then((e=>createImageBitmap(e)))])}catch(e){return console.error("Error loading font:",e),""}let s=[a.width,a.height,1],l=Q5.device.createTexture({label:`MSDF ${r}`,size:s,format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:a},{texture:l},s),"string"==typeof i.chars&&(i.chars=Q5.CSV.parse(i.chars," "),i.kernings=Q5.CSV.parse(i.kernings," "));let d=i.chars.length,c=Q5.device.createBuffer({size:32*d,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),u=new Float32Array(c.getMappedRange()),h=1/i.common.scaleW,f=1/i.common.scaleH,p={},g=0;for(let[e,t]of i.chars.entries())p[t.id]=t,p[t.id].charIndex=e,u[g]=t.x*h,u[g+1]=t.y*f,u[g+2]=t.width*h,u[g+3]=t.height*f,u[g+4]=t.width,u[g+5]=t.height,u[g+6]=t.xoffset,u[g+7]=t.yoffset,g+=8;c.unmap();let m=Q5.device.createBindGroup({label:"fontBindGroup",layout:wt,entries:[{binding:0,resource:l.createView()},{binding:1,resource:yt},{binding:2,resource:{buffer:c}}]}),_=new Map;if(i.kernings)for(let e of i.kernings){let t=_.get(e.first);t||(t=new Map,_.set(e.first,t)),t.set(e.second,e.amount)}let x=new Qt(m,i.common.lineHeight,p,_);return x.index=Mt.length,Mt.push(x),Pt[r]=x,e._font=x,n&&n(r),{family:r}}(t,i,(()=>{delete a.then,a._usedAwait&&(a={family:i}),r&&r(a)})),e._loaders.push(a.promise),a.then=(e,t)=>(a._usedAwait=!0,a.promise.then(e,t)),a};let Et=18,It="left",Rt="alphabetic",At=!1,Tt=22.5,kt=4.5,Ot=1.25,Gt=["serif","sans-serif","monospace","cursive","fantasy","system-ui"];e.textFont=t=>{if(!t)return e._font;Ct=!0,"string"!=typeof t&&(t=t.family);let r=Pt[t];r?e._font=r:(Gt[t]||void 0===r)&&e._g.textFont(t)},e.textSize=t=>{if(e._font||e._g.textSize(t),null==t)return Et;Et=t,At||(Tt=t*Ot,kt=Tt-t)};let Dt={thin:100,extralight:200,light:300,normal:400,regular:400,medium:500,semibold:600,bold:700,bolder:800,extrabold:800,black:900,heavy:900},Lt=.5;e.textWeight=t=>{if(!t)return e._textWeight;if("string"==typeof t&&!(t=Dt[t.toLowerCase().replace(/[ _-]/g,"")]))throw new Error(`Invalid font weight: ${t}`);Lt=.6875-375e-6*t},e.textLeading=t=>e._font?t?(e._font.lineHeight=Tt=t,kt=Tt-Et,Ot=Tt/Et,void(At=!0)):Tt:e._g.textLeading(t),e.textAlign=(e,t)=>{It=e,t&&(Rt=t)},e.textStyle=e=>{};let Ft=[],Bt=[],zt=new Array(100),Ut=new Float32Array(4*Q5.MAX_CHARS),Nt=new Float32Array(8*Q5.MAX_TEXTS),Vt=(e,t,r)=>{let n=0,i=0,a=0,o=0,s=0,l=zt,d=t.charCodeAt(0);for(let c=0;c<t.length;++c){let u=d;switch(d=c<t.length-1?t.charCodeAt(c+1):-1,u){case 10:l.push(i),o++,n=Math.max(n,i),i=0,a-=e.lineHeight*Ot;break;case 13:break;case 32:i+=e.getXAdvance(u);break;case 9:i+=2*e.getXAdvance(u);break;default:r&&r(i,a,o,e.getChar(u)),i+=e.getXAdvance(u,d),s++}}l[o]=i,n=Math.max(n,i);let c=o+1;return{width:n,height:c*e.lineHeight*Ot,lineWidths:l,lineCount:c,printedCharCount:s}};e.text=(t,r,n,i,a)=>{if(Et<1)return;let o,s=typeof t;if("string"!=s)"object"==s?t=t.toString():t+="";else if(!t.length)return;if(!e._font){Ct||e.loadFont();let o=e.createTextImage(t,i,a);return e.textImage(o,r,n)}if(t.length>i){let e=[],r=0;for(;r<t.length&&e.length<a;){let n=r+i;if(n>=t.length){e.push(t.slice(r));break}let a=t.lastIndexOf(" ",n);(-1==a||a<r)&&(a=n),e.push(t.slice(r,a)),r=a+1}t=e.join("\n"),o=!0}o??=t.includes("\n");let l,d=[],c=It,u=Rt,h=Bt.length,f=0;if("left"!=c||o){l=Vt(e._font,t);let r=0;"alphabetic"==u?n-=Et:"center"==u?r=.5*l.height:"bottom"==u&&(r=l.height),Vt(e._font,t,((e,t,n,i)=>{let a=0;"center"==c?a=-.5*l.width- -.5*(l.width-l.lineWidths[n]):"right"==c&&(a=-l.lineWidths[n]),d[f]=e+a,d[f+1]=-(t+r),d[f+2]=i.charIndex,d[f+3]=h,f+=4}))}else l=Vt(e._font,t,((e,t,r,n)=>{d[f]=e,d[f+1]=-t,d[f+2]=n.charIndex,d[f+3]=h,f+=4})),"alphabetic"==u?n-=Et:"center"==u?n-=.5*Et:"bottom"==u&&(n-=Tt);Ft.push(d);let p=[];q&&j(),p[0]=r,p[1]=n,p[2]=Et/42,p[3]=H,p[4]=M&&E?A:1,p[5]=R,p[6]=P&&I?O:0,p[7]=Lt,Bt.push(p),_.push(xt,l.printedCharCount,e._font.index)},e.textWidth=t=>e._font?Vt(e._font,t).width*Et/42:(e._g.textSize(Et),e._g.textWidth(t)),e.textAscent=t=>e._font?Tt-kt:(e._g.textSize(Et),e._g.textAscent(t)),e.textDescent=t=>e._font?kt:(e._g.textSize(Et),e._g.textDescent(t)),e.createTextImage=(t,r,n)=>{if(e._g.textSize(Et),M&&E){let t=4*A;e._g.fill(x.slice(t,t+4))}if(P&&I){let t=4*R;e._g.stroke(x.slice(t,t+4))}let i=e._g.createTextImage(t,r,n);return e._makeDrawable(i),i},e.textImage=(t,r,n)=>{"string"==typeof t&&(t=e.createTextImage(t));let i=mt;mt="corner";let a=It;"center"==a?r-=t.canvas.hw:"right"==a&&(r-=t.width);let o=Rt;"alphabetic"==o?n-=t._leading:"center"==o?n-=t._middle:"bottom"==o?n-=t._bottom:"top"==o&&(n-=t._top),e.image(t,r,n),mt=i};let Ht=["frame","shapes","image","video","text"],qt={frame:10,shapes:1e3,image:2e3,video:3e3,text:4e3};e._createShader=(t,r="shapes")=>{t=t.trim();let n=e["_"+r+"ShaderCode"],i=n.indexOf("@vertex"),a=n.indexOf("@fragment");t=t.includes("@fragment")?t.includes("@vertex")?n.slice(0,i)+t:n.slice(0,a)+t:n.slice(0,i)+t+"\n\n"+n.slice(a);let o=Q5.device.createShaderModule({label:r+"Shader",code:t});o.type=r;let s=Ht.indexOf(r),l=Object.assign({},e._pipelineConfigs[s]);l.vertex.module=l.fragment.module=o;let d=qt[r];return e._pipelines[d]=Q5.device.createRenderPipeline(l),e._pipelines[d].shader=o,o.pipelineIndex=d,qt[r]++,o},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=e=>{let t=e.type,r=e.pipelineIndex;"frame"==t?e.applyBeforeDraw?g=r:m=r:"shapes"==t?fe=r:"image"==t?tt=r:"video"==t?rt=r:"text"==t&&(xt=r)},e.resetShader=e.resetShapesShader=()=>fe=1,e.resetFrameShader=()=>g=m=0,e.resetImageShader=()=>tt=2,e.resetVideoShader=()=>rt=3,e.resetTextShader=()=>xt=4,e.resetShaders=()=>{g=m=0,fe=1,tt=2,rt=3,xt=4}},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.MAX_TRANSFORMS=1e7,Q5.MAX_RECTS=200200,Q5.MAX_ELLIPSES=200200,Q5.MAX_CHARS=1e5,Q5.MAX_TEXTS=1e4,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){Q5.requestedGPU=!0;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){let r;return e&&"global"!=e||(Q5._hasGlobal=!0),await Q5.initWebGPU()||(r=new Q5(e,t,"webgpu-fallback")),r=new Q5(e,t,"webgpu"),await r.ready,r};const libLangs="\n# core\ncreateCanvas -> es:crearLienzo ja:キャンバスを作成する\n\n# color\nbackground -> es:fondo ja:背景\n\n# display\nwindowWidth -> es:anchoVentana\nwindowHeight -> es:altoVentana\nframeCount -> es:cuadroActual\nnoLoop -> es:pausar\nredraw -> es:redibujar\nloop -> es:reanudar\nframeRate -> es:frecuenciaRefresco\ngetTargetFrameRate -> es:frecuenciaIdeal\ngetFPS -> es:frecuenciaMaxima\ndeltaTime -> es:ultimoTiempo\n\n# shape\ncircle -> es:círculo\n",userLangs="\nupdate -> es:actualizar\ndraw -> es:dibujar\npostProcess -> es:retocarDibujo\n",parseLangs=function(e,t){let r={};for(let n of e.split("\n")){let e=n.indexOf(" "+t+":");e>0&&"#"!=n[0]&&(r[n.split(" ")[0]]=n.slice(e+4).split(" ")[0])}return r};Q5._lang="en",Object.defineProperty(Q5,"lang",{get:()=>Q5._lang,set:e=>{if(e==Q5._lang)return;if(Q5._lang=e,"en"==e)return Q5._userFns=Q5._userFns.slice(0,17),void(Q5._libMap=Q5._userFnsMap={});let t=parseLangs(libLangs,e);"object"==typeof window&&(window[t.createCanvas]=createCanvas);let r=parseLangs(userLangs,e);for(let e in r){let t=r[e];Q5.hasOwnProperty(t)||Object.defineProperty(Q5,t,{get:()=>Q5[e],set:t=>Q5[e]=t})}Q5._libMap=t,Q5._userFnsMap=r,Q5._userFns.push(...Object.values(r))}}),Q5.modules.lang=e=>{let t=Q5._userFnsMap;for(let r in t){let n=t[r];Object.defineProperty(e,n,{get:()=>e[r],set:t=>e[r]=t})}let r=Q5._libMap;r?.createCanvas&&(e[r.createCanvas]=e.createCanvas)},Q5.addHook("presetup",(e=>{let t=Q5._libMap;for(let r in t){e[t[r]]=e[r]}}));
|