{
  "version": 3,
  "sources": ["../package.json", "../src/math/clamp.ts", "../src/math/color.ts", "../src/math/math.ts", "../src/constants.ts", "../src/events/events.ts", "../src/utils/asserts.ts", "../src/utils/binaryheap.ts", "../src/utils/dataURL.ts", "../src/utils/deepEq.ts", "../src/utils/log.ts", "../src/utils/numbers.ts", "../src/utils/overload.ts", "../src/utils/runes.ts", "../src/utils/sets.ts", "../src/utils/uid.ts", "../src/data/gamepad.json", "../src/gfx/viewport.ts", "../src/app/inputBindings.ts", "../src/app/app.ts", "../src/app/frame.ts", "../src/gfx/anchor.ts", "../src/math/easings.ts", "../src/math/navigation.ts", "../src/math/navigationmesh.ts", "../src/math/various.ts", "../src/gfx/bg.ts", "../src/gfx/stack.ts", "../src/gfx/texPacker.ts", "../src/assets/utils.ts", "../src/assets/asset.ts", "../src/assets/sprite.ts", "../src/assets/aseprite.ts", "../src/assets/font.ts", "../src/assets/bitmapFont.ts", "../src/assets/pedit.ts", "../src/assets/shader.ts", "../src/assets/sound.ts", "../src/assets/spriteAtlas.ts", "../src/gfx/draw/drawRaw.ts", "../src/gfx/draw/drawPolygon.ts", "../src/gfx/draw/drawEllipse.ts", "../src/gfx/draw/drawCircle.ts", "../src/gfx/draw/drawLine.ts", "../src/gfx/draw/drawCurve.ts", "../src/gfx/draw/drawBezier.ts", "../src/gfx/gfx.ts", "../src/gfx/formatText.ts", "../src/gfx/draw/drawUVQuad.ts", "../src/gfx/draw/drawFormattedText.ts", "../src/gfx/draw/drawRect.ts", "../src/gfx/draw/drawUnscaled.ts", "../src/gfx/draw/drawInspectText.ts", "../src/gfx/draw/drawTriangle.ts", "../src/gfx/draw/drawDebug.ts", "../src/gfx/draw/drawFrame.ts", "../src/gfx/draw/drawLoadingScreen.ts", "../src/gfx/draw/drawStenciled.ts", "../src/gfx/draw/drawMasked.ts", "../src/gfx/draw/drawTexture.ts", "../src/gfx/draw/drawSprite.ts", "../src/gfx/draw/drawSubstracted.ts", "../src/gfx/draw/drawText.ts", "../src/gfx/gfxApp.ts", "../src/game/utils.ts", "../src/components/draw/circle.ts", "../src/components/draw/color.ts", "../src/components/draw/drawon.ts", "../src/components/draw/fadeIn.ts", "../src/components/draw/mask.ts", "../src/components/draw/opacity.ts", "../src/components/draw/outline.ts", "../src/components/draw/particles.ts", "../src/components/draw/polygon.ts", "../src/components/draw/raycast.ts", "../src/components/draw/rect.ts", "../src/components/draw/shader.ts", "../src/game/level.ts", "../src/events/globalEvents.ts", "../src/game/camera.ts", "../src/game/make.ts", "../src/game/game.ts", "../src/game/gravity.ts", "../src/audio/audio.ts", "../src/audio/playMusic.ts", "../src/audio/play.ts", "../src/audio/burp.ts", "../src/audio/volume.ts", "../src/game/initEvents.ts", "../src/game/kaboom.ts", "../src/game/layers.ts", "../src/game/object.ts", "../src/game/scenes.ts", "../src/components/draw/sprite.ts", "../src/components/draw/text.ts", "../src/components/draw/uvquad.ts", "../src/components/level/agent.ts", "../src/components/level/pathfinder.ts", "../src/components/level/patrol.ts", "../src/components/level/sentry.ts", "../src/components/level/tile.ts", "../src/components/misc/animate.ts", "../src/components/misc/boom.ts", "../src/components/misc/health.ts", "../src/components/misc/lifespan.ts", "../src/components/misc/named.ts", "../src/components/misc/state.ts", "../src/components/misc/stay.ts", "../src/components/misc/textInput.ts", "../src/components/misc/timer.ts", "../src/components/physics/area.ts", "../src/components/physics/body.ts", "../src/components/physics/doubleJump.ts", "../src/components/physics/effectors.ts", "../src/components/transform/anchor.ts", "../src/components/transform/fixed.ts", "../src/components/transform/follow.ts", "../src/components/transform/layer.ts", "../src/components/transform/move.ts", "../src/components/transform/offscreen.ts", "../src/components/transform/pos.ts", "../src/components/transform/rotate.ts", "../src/components/transform/scale.ts", "../src/components/transform/z.ts", "../src/kaplay.ts"],
  "sourcesContent": ["{\n  \"name\": \"kaplay\",\n  \"description\": \"KAPLAY is a JavaScript & TypeScript game library that helps you make games fast and fun! (formerly known as Kaboom.js)\",\n  \"version\": \"3001.0.19\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://kaplayjs.com/\",\n  \"bugs\": {\n    \"url\": \"https://github.com/kaplayjs/kaplay/issues\"\n  },\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/kaplay\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/kaplayjs/kaplay.git\"\n  },\n  \"type\": \"module\",\n  \"main\": \"./dist/kaplay.cjs\",\n  \"module\": \"./dist/kaplay.mjs\",\n  \"types\": \"./dist/doc.d.ts\",\n  \"readme\": \"./README.md\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/doc.d.ts\",\n        \"default\": \"./dist/kaplay.mjs\"\n      },\n      \"require\": {\n        \"types\": \"./dist/doc.d.ts\",\n        \"default\": \"./dist/kaplay.cjs\"\n      }\n    },\n    \"./global\": \"./dist/declaration/global.js\"\n  },\n  \"typesVersions\": {\n    \"*\": {\n      \"global\": [\n        \"./dist/declaration/global.d.ts\"\n      ]\n    }\n  },\n  \"keywords\": [\n    \"game development\",\n    \"javascript\",\n    \"typescript\",\n    \"game engine\",\n    \"2d games\",\n    \"physics engine\",\n    \"webgl\",\n    \"canvas\",\n    \"game library\",\n    \"kaplay\",\n    \"kaboom\",\n    \"kaboomjs\",\n    \"kaboom.js\"\n  ],\n  \"files\": [\n    \"dist/\",\n    \"kaplay.webp\",\n    \"CHANGELOG.md\"\n  ],\n  \"scripts\": {\n    \"dev\": \"NODE_ENV=development node scripts/dev.js\",\n    \"win:dev\": \"set NODE_ENV=development && node scripts/dev.js\",\n    \"build\": \"node scripts/generateIndex.js && npm run doc-dts && node scripts/build.js\",\n    \"build:fast\": \"node scripts/buildFast.js\",\n    \"check\": \"tsc\",\n    \"fmt\": \"dprint fmt\",\n    \"test\": \"node scripts/test.js\",\n    \"doc-dts\": \"dts-bundle-generator -o dist/doc.d.ts src/index.ts\",\n    \"test:vite\": \"vitest --typecheck\",\n    \"desktop\": \"tauri dev\",\n    \"prepare\": \"npm run build\",\n    \"publish:next\": \"npm publish --tag next\"\n  },\n  \"devDependencies\": {\n    \"@kaplayjs/dprint-config\": \"^1.2.0\",\n    \"@types/jest\": \"^29.5.14\",\n    \"dprint\": \"^0.49.1\",\n    \"dts-bundle-generator\": \"^9.5.1\",\n    \"ejs\": \"^3.1.10\",\n    \"esbuild\": \"^0.25.2\",\n    \"express\": \"^5.1.0\",\n    \"puppeteer\": \"^22.15.0\",\n    \"tar-fs\": \"3.0.8\",\n    \"typescript\": \"5.6.3\",\n    \"vite\": \"5.4.16\",\n    \"vitest\": \"^3.1.1\",\n    \"vitest-environment-puppeteer\": \"^11.0.3\",\n    \"vitest-puppeteer\": \"^11.0.3\"\n  },\n  \"engines\": {\n    \"node\": \">=20.0.0\"\n  },\n  \"packageManager\": \"pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1\"\n}\n", "export function clamp(\n    val: number,\n    min: number,\n    max: number,\n): number {\n    if (min > max) {\n        return clamp(val, max, min);\n    }\n    return Math.min(Math.max(val, min), max);\n}\n", "import { clamp } from \"./clamp.js\";\nimport { lerp } from \"./math\";\n\nexport type RGBValue = [number, number, number];\nexport type RGBAValue = [number, number, number, number];\n\n/**\n * 0-255 RGBA color.\n *\n * @group Math\n */\nexport class Color {\n    /** Red (0-255. */\n    r: number = 255;\n    /** Green (0-255). */\n    g: number = 255;\n    /** Blue (0-255). */\n    b: number = 255;\n\n    constructor(r: number, g: number, b: number) {\n        this.r = clamp(r, 0, 255);\n        this.g = clamp(g, 0, 255);\n        this.b = clamp(b, 0, 255);\n    }\n\n    // TODO: Type arr as tuple (no in ts-strict branch yet)\n    static fromArray(arr: number[]) {\n        return new Color(arr[0], arr[1], arr[2]);\n    }\n\n    /**\n     * Create color from hex string or literal.\n     *\n     * @example\n     * ```js\n     * Color.fromHex(0xfcef8d)\n     * Color.fromHex(\"#5ba675\")\n     * Color.fromHex(\"d46eb3\")\n     * ```\n     *\n     * @since v3000.0\n     */\n    static fromHex(hex: string | number) {\n        if (typeof hex === \"number\") {\n            return new Color(\n                (hex >> 16) & 0xff,\n                (hex >> 8) & 0xff,\n                (hex >> 0) & 0xff,\n            );\n        }\n        else if (typeof hex === \"string\") {\n            const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(\n                hex,\n            );\n\n            if (!result) throw new Error(\"Invalid hex color format\");\n\n            return new Color(\n                parseInt(result[1], 16),\n                parseInt(result[2], 16),\n                parseInt(result[3], 16),\n            );\n        }\n        else {\n            throw new Error(\"Invalid hex color format\");\n        }\n    }\n\n    // TODO: use range of [0, 360] [0, 100] [0, 100]?\n    static fromHSL(h: number, s: number, l: number) {\n        if (s == 0) {\n            return new Color(255 * l, 255 * l, 255 * l);\n        }\n\n        const hue2rgb = (p: number, q: number, t: number) => {\n            if (t < 0) t += 1;\n            if (t > 1) t -= 1;\n            if (t < 1 / 6) return p + (q - p) * 6 * t;\n            if (t < 1 / 2) return q;\n            if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n            return p;\n        };\n\n        const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n        const p = 2 * l - q;\n        const r = hue2rgb(p, q, h + 1 / 3);\n        const g = hue2rgb(p, q, h);\n        const b = hue2rgb(p, q, h - 1 / 3);\n\n        return new Color(\n            Math.round(r * 255),\n            Math.round(g * 255),\n            Math.round(b * 255),\n        );\n    }\n\n    static RED = new Color(255, 0, 0);\n    static GREEN = new Color(0, 255, 0);\n    static BLUE = new Color(0, 0, 255);\n    static YELLOW = new Color(255, 255, 0);\n    static MAGENTA = new Color(255, 0, 255);\n    static CYAN = new Color(0, 255, 255);\n    static WHITE = new Color(255, 255, 255);\n    static BLACK = new Color(0, 0, 0);\n\n    clone(): Color {\n        return new Color(this.r, this.g, this.b);\n    }\n\n    /** Lighten the color (adds RGB by n). */\n    lighten(a: number): Color {\n        return new Color(this.r + a, this.g + a, this.b + a);\n    }\n\n    /** Darkens the color (subtracts RGB by n). */\n    darken(a: number): Color {\n        return this.lighten(-a);\n    }\n\n    invert(): Color {\n        return new Color(255 - this.r, 255 - this.g, 255 - this.b);\n    }\n\n    mult(other: Color): Color {\n        return new Color(\n            this.r * other.r / 255,\n            this.g * other.g / 255,\n            this.b * other.b / 255,\n        );\n    }\n\n    /**\n     * Linear interpolate to a destination color.\n     *\n     * @since v3000.0\n     */\n    lerp(dest: Color, t: number): Color {\n        return new Color(\n            lerp(this.r, dest.r, t),\n            lerp(this.g, dest.g, t),\n            lerp(this.b, dest.b, t),\n        );\n    }\n\n    /**\n     * Convert color into HSL format.\n     *\n     * @since v3001.0\n     */\n    toHSL(): [number, number, number] {\n        const r = this.r / 255;\n        const g = this.g / 255;\n        const b = this.b / 255;\n        const max = Math.max(r, g, b), min = Math.min(r, g, b);\n        let h = (max + min) / 2;\n        let s = h;\n        const l = h;\n        if (max == min) {\n            h = s = 0;\n        }\n        else {\n            const d = max - min;\n            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n            switch (max) {\n                case r:\n                    h = (g - b) / d + (g < b ? 6 : 0);\n                    break;\n                case g:\n                    h = (b - r) / d + 2;\n                    break;\n                case b:\n                    h = (r - g) / d + 4;\n                    break;\n            }\n            h /= 6;\n        }\n        return [h, s, l];\n    }\n\n    eq(other: Color): boolean {\n        return this.r === other.r\n            && this.g === other.g\n            && this.b === other.b;\n    }\n\n    toString(): string {\n        return `rgb(${this.r}, ${this.g}, ${this.b})`;\n    }\n\n    /**\n     * Return the hex string of color.\n     *\n     * @since v3000.0\n     */\n    toHex(): string {\n        return \"#\"\n            + ((1 << 24) + (this.r << 16) + (this.g << 8) + this.b).toString(16)\n                .slice(1);\n    }\n\n    /**\n     * Return the color converted to an array.\n     *\n     * @since v3001.0\n     */\n    toArray(): Array<number> {\n        return [this.r, this.g, this.b];\n    }\n}\n\nexport type ColorArgs =\n    // rgb(new Color(255, 255, 255))\n    | [Color]\n    /**\n     * rgb(new Color(255, 255, 255), 1)\n     *\n     * This is only used to parse directly the color of background. This\n     * syntax shouldn't be used to set opacity. Use `opacity()` comp instead.\n     */\n    | [Color, number]\n    // rgb(255, 255, 255)\n    | RGBValue\n    /**\n     * rgb(255, 255, 255, 1)\n     *\n     * This is only used to parse directly the color of background. This\n     * syntax shouldn't be used to set opacity. Use `opacity()` comp instead.\n     */\n    | RGBAValue\n    // rgb(\"#ffffff\")\n    | [string]\n    | [number[]]\n    | [];\n\nexport function rgb(...args: ColorArgs): Color {\n    if (args.length === 0) {\n        return new Color(255, 255, 255);\n    }\n    else if (args.length === 1) {\n        if (args[0] instanceof Color) {\n            // rgb(new Color(255, 255, 255))\n            return args[0].clone();\n        }\n        else if (typeof args[0] === \"string\") {\n            // rgb(\"#ffffff\")\n            return Color.fromHex(args[0]);\n        }\n        else if (Array.isArray(args[0]) && args[0].length === 3) {\n            // rgb([255, 255, 255])\n            return Color.fromArray(args[0]);\n        }\n    }\n    else if (args.length === 2) {\n        if (args[0] instanceof Color) {\n            return args[0].clone();\n        }\n    }\n    else if (args.length === 3 || args.length === 4) {\n        return new Color(args[0], args[1], args[2]);\n    }\n\n    throw new Error(\"Invalid color arguments\");\n}\n\nexport const hsl2rgb = (h: number, s: number, l: number) =>\n    Color.fromHSL(h, s, l);\n", "import type { GameObj, LerpValue, RNGValue } from \"../types\";\nimport { clamp } from \"./clamp.js\";\nimport { Color, rgb } from \"./color\";\n\n/**\n * Possible arguments for a Vec2.\n *\n * @group Math\n */\nexport type Vec2Args =\n    | [number, number]\n    | [number]\n    | [Vec2]\n    | [number | Vec2]\n    | [];\n\nexport function deg2rad(deg: number): number {\n    return deg * Math.PI / 180;\n}\n\nexport function rad2deg(rad: number): number {\n    return rad * 180 / Math.PI;\n}\n\nexport function lerp<V extends LerpValue>(\n    a: V,\n    b: V,\n    t: number,\n): V {\n    if (typeof a === \"number\" && typeof b === \"number\") {\n        return a + (b - a) * t as V;\n    }\n    else if (a instanceof Vec2 && b instanceof Vec2) {\n        return a.lerp(b, t) as V;\n    }\n    else if (a instanceof Color && b instanceof Color) {\n        return a.lerp(b, t) as V;\n    }\n    throw new Error(\n        `Bad value for lerp(): ${a}, ${b}. Only number, Vec2 and Color is supported.`,\n    );\n}\n\nexport function map(\n    v: number,\n    l1: number,\n    h1: number,\n    l2: number,\n    h2: number,\n): number {\n    return l2 + (v - l1) / (h1 - l1) * (h2 - l2);\n}\n\nexport function mapc(\n    v: number,\n    l1: number,\n    h1: number,\n    l2: number,\n    h2: number,\n): number {\n    return clamp(map(v, l1, h1, l2, h2), l2, h2);\n}\n\nexport function step(edge: number, x: number) {\n    return x < edge ? 0 : 1;\n}\n\nexport function smoothstep(edge0: number, edge1: number, x: number) {\n    x = clamp((x - edge0) / (edge1 - edge0), 0, 1);\n    return x * x * (3.0 - 2.0 * x);\n}\n\n/**\n * A 2D vector.\n *\n * @group Math\n */\nexport class Vec2 {\n    /** The x coordinate */\n    x: number = 0;\n    /** The y coordinate */\n    y: number = 0;\n\n    constructor(x: number = 0, y: number = x) {\n        this.x = x;\n        this.y = y;\n    }\n\n    /** Create a new Vec2 from an angle in degrees */\n    static fromAngle(deg: number) {\n        const angle = deg2rad(deg);\n        return new Vec2(Math.cos(angle), Math.sin(angle));\n    }\n\n    /** Create a new Vec2 from an array */\n    static fromArray(arr: Array<number>) {\n        return new Vec2(arr[0], arr[1]);\n    }\n\n    /** An empty vector. (0, 0) */\n    static ZERO = new Vec2(0, 0);\n    /** A vector with both components of 1. (1, 1) */\n    static ONE = new Vec2(1, 1);\n    /** A vector signaling to the left. (-1, 0) */\n    static LEFT = new Vec2(-1, 0);\n    /** A vector signaling to the right. (1, 0) */\n    static RIGHT = new Vec2(1, 0);\n    /** A vector signaling up. (0, -1) */\n    static UP = new Vec2(0, -1);\n    /** A vector signaling down. (0, 1) */\n    static DOWN = new Vec2(0, 1);\n\n    /** Clone the vector */\n    clone(): Vec2 {\n        return new Vec2(this.x, this.y);\n    }\n\n    /** Returns the addition with another vector. */\n    add(...args: Vec2Args): Vec2 {\n        const p2 = vec2(...args);\n        return new Vec2(this.x + p2.x, this.y + p2.y);\n    }\n\n    /** Returns the subtraction with another vector. */\n    sub(...args: Vec2Args): Vec2 {\n        const p2 = vec2(...args);\n        return new Vec2(this.x - p2.x, this.y - p2.y);\n    }\n\n    /** Scale by another vector. or a single number */\n    scale(...args: Vec2Args): Vec2 {\n        const s = vec2(...args);\n        return new Vec2(this.x * s.x, this.y * s.y);\n    }\n\n    /** Get distance between another vector */\n    dist(...args: Vec2Args): number {\n        const p2 = vec2(...args);\n        return this.sub(p2).len();\n    }\n\n    /** Get squared distance between another vector */\n    sdist(...args: Vec2Args): number {\n        const p2 = vec2(...args);\n        return this.sub(p2).slen();\n    }\n\n    /**\n     * Calculates the squared distance between the vectors\n     * @param v The vector\n     * @param other The other vector\n     * @returns The distance between the vectors\n     */\n    static sdist(v: Vec2, other: Vec2): number {\n        const x = v.x - other.x;\n        const y = v.y - other.y;\n        return x * x + y * y;\n    }\n\n    /**\n     * Get length of the vector\n     *\n     * @since v3000.0\n     */\n    len(): number {\n        return Math.sqrt(this.dot(this));\n    }\n\n    /**\n     * Get squared length of the vector\n     *\n     * @since v3000.0\n     */\n    slen(): number {\n        return this.dot(this);\n    }\n\n    /**\n     * Get the unit vector (length of 1).\n     */\n    unit(): Vec2 {\n        const len = this.len();\n        return len === 0 ? new Vec2(0) : this.scale(1 / len);\n    }\n\n    /**\n     * Get the perpendicular vector.\n     */\n    normal(): Vec2 {\n        return new Vec2(this.y, -this.x);\n    }\n\n    /**\n     * Get the reflection of a vector with a normal.\n     *\n     * @since v3000.0\n     */\n    reflect(normal: Vec2) {\n        return this.sub(normal.scale(2 * this.dot(normal)));\n    }\n\n    /**\n     * Get the projection of a vector onto another vector.\n     *\n     * @since v3000.0\n     */\n    project(on: Vec2) {\n        return on.scale(on.dot(this) / on.len());\n    }\n\n    /**\n     * Get the rejection of a vector onto another vector.\n     *\n     * @since v3000.0\n     */\n    reject(on: Vec2) {\n        return this.sub(this.project(on));\n    }\n\n    /**\n     * Get the dot product with another vector.\n     */\n    dot(p2: Vec2): number {\n        return this.x * p2.x + this.y * p2.y;\n    }\n\n    /**\n     * Get the dot product between 2 vectors.\n     *\n     * @since v3000.0\n     */\n    static dot(v: Vec2, other: Vec2): number {\n        return v.x * other.x + v.y * other.y;\n    }\n\n    /**\n     * Get the cross product with another vector.\n     *\n     * @since v3000.0\n     */\n    cross(p2: Vec2): number {\n        return this.x * p2.y - this.y * p2.x;\n    }\n\n    /**\n     * Get the cross product between 2 vectors.\n     *\n     * @since v3000.0\n     */\n    static cross(v: Vec2, other: Vec2): number {\n        return v.x * other.y - v.y * other.x;\n    }\n\n    /**\n     * Get the angle of the vector in degrees.\n     */\n    angle(...args: Vec2Args): number {\n        const p2 = vec2(...args);\n        return rad2deg(Math.atan2(this.y - p2.y, this.x - p2.x));\n    }\n\n    /**\n     * Get the angle between this vector and another vector.\n     *\n     * @since v3000.0\n     */\n    angleBetween(...args: Vec2Args): number {\n        const p2 = vec2(...args);\n        return rad2deg(Math.atan2(this.cross(p2), this.dot(p2)));\n    }\n\n    /**\n     * Linear interpolate to a destination vector (for positions).\n     */\n    lerp(dest: Vec2, t: number): Vec2 {\n        return new Vec2(lerp(this.x, dest.x, t), lerp(this.y, dest.y, t));\n    }\n\n    /**\n     * Spherical linear interpolate to a destination vector (for rotations).\n     *\n     * @since v3000.0\n     */\n    slerp(dest: Vec2, t: number): Vec2 {\n        const cos = this.dot(dest);\n        const sin = this.cross(dest);\n        const angle = Math.atan2(sin, cos);\n        return this\n            .scale(Math.sin((1 - t) * angle))\n            .add(dest.scale(Math.sin(t * angle)))\n            .scale(1 / sin);\n    }\n\n    /**\n     * If the vector (x, y) is zero.\n     *\n     * @since v3000.0\n     */\n    isZero(): boolean {\n        return this.x === 0 && this.y === 0;\n    }\n\n    /**\n     * To n precision floating point.\n     */\n    toFixed(n: number): Vec2 {\n        return new Vec2(Number(this.x.toFixed(n)), Number(this.y.toFixed(n)));\n    }\n\n    /**\n     * Multiply by a Mat4.\n     *\n     * @since v3000.0\n     */\n    transform(m: Mat4): Vec2 {\n        return m.multVec2(this);\n    }\n\n    /**\n     * See if one vector is equal to another.\n     *\n     * @since v3000.0\n     */\n    eq(other: Vec2): boolean {\n        return this.x === other.x && this.y === other.y;\n    }\n\n    /** Converts the vector to a {@link Rect `Rect()`} with the vector as the origin.\n     * @since v3000.0.\n     */\n    bbox(): Rect {\n        return new Rect(this, 0, 0);\n    }\n\n    /** Converts the vector to a readable string. */\n    toString(): string {\n        return `vec2(${this.x.toFixed(2)}, ${this.y.toFixed(2)})`;\n    }\n\n    /** Converts the vector to an array.\n     * @since v3001.0\n     */\n    toArray(): Array<number> {\n        return [this.x, this.y];\n    }\n}\n\nexport function vec2(...args: Vec2Args): Vec2 {\n    if (args.length === 1) {\n        if (args[0] instanceof Vec2) {\n            return new Vec2(args[0].x, args[0].y);\n        }\n        else if (Array.isArray(args[0]) && args[0].length === 2) {\n            return new Vec2(...args[0]);\n        }\n    }\n    // @ts-ignore\n    return new Vec2(...args);\n}\n\n/**\n * @group Math\n */\nexport class Quad {\n    x: number = 0;\n    y: number = 0;\n    w: number = 1;\n    h: number = 1;\n    constructor(x: number, y: number, w: number, h: number) {\n        this.x = x;\n        this.y = y;\n        this.w = w;\n        this.h = h;\n    }\n    scale(other: Quad): Quad {\n        return new Quad(\n            this.x + this.w * other.x,\n            this.y + this.h * other.y,\n            this.w * other.w,\n            this.h * other.h,\n        );\n    }\n    pos() {\n        return new Vec2(this.x, this.y);\n    }\n    clone(): Quad {\n        return new Quad(this.x, this.y, this.w, this.h);\n    }\n    eq(other: Quad): boolean {\n        return this.x === other.x\n            && this.y === other.y\n            && this.w === other.w\n            && this.h === other.h;\n    }\n    toString(): string {\n        return `quad(${this.x}, ${this.y}, ${this.w}, ${this.h})`;\n    }\n}\n\nexport function quad(x: number, y: number, w: number, h: number): Quad {\n    return new Quad(x, y, w, h);\n}\n\n// Internal class\nclass Mat2 {\n    // 2x2 matrix\n    a: number;\n    b: number;\n    c: number;\n    d: number;\n\n    constructor(a: number, b: number, c: number, d: number) {\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n    }\n\n    mul(other: Mat2) {\n        return new Mat2(\n            this.a * other.a + this.b * other.c,\n            this.a * other.b + this.b * other.d,\n            this.c * other.a + this.d * other.c,\n            this.c * other.b + this.d * other.d,\n        );\n    }\n\n    transform(point: Vec2): Vec2 {\n        return vec2(\n            this.a * point.x + this.b * point.y,\n            this.c * point.x + this.d * point.y,\n        );\n    }\n\n    get inverse() {\n        const det = this.det;\n        return new Mat2(\n            this.d / det,\n            -this.b / det,\n            -this.c / det,\n            this.a / det,\n        );\n    }\n\n    get transpose() {\n        return new Mat2(\n            this.a,\n            this.c,\n            this.b,\n            this.d,\n        );\n    }\n\n    get eigenvalues() {\n        const m = this.trace / 2;\n        const d = this.det;\n        const e1 = m + Math.sqrt(m * m - d);\n        const e2 = m - Math.sqrt(m * m - d);\n        return [e1, e2];\n    }\n\n    eigenvectors(e1: number, e2: number) {\n        if (this.c != 0) {\n            return [[e1 - this.d, this.c], [e2 - this.d, this.c]];\n        }\n        else if (this.b != 0) {\n            return [[this.b, e1 - this.a], [this.b, e2 - this.a]];\n        }\n        else {\n            if (Math.abs(this.transform(vec2(1, 0)).x - e1) < Number.EPSILON) {\n                return [[1, 0], [0, 1]];\n            }\n            else {\n                return [[0, 1], [1, 0]];\n            }\n        }\n    }\n\n    get det() {\n        return this.a * this.d - this.b * this.c;\n    }\n\n    get trace() {\n        return this.a + this.d;\n    }\n\n    static rotation(radians: number) {\n        const c = Math.cos(radians);\n        const s = Math.sin(radians);\n        return new Mat2(\n            c,\n            s,\n            -s,\n            c,\n        );\n    }\n\n    static scale(x: number, y: number) {\n        return new Mat2(x, 0, 0, y);\n    }\n}\n\n// Internal class\nclass Mat23 {\n    // 2x3 matrix, since the last column is always (0, 0, 1)\n    a: number;\n    b: number; // 0\n    c: number;\n    d: number; // 0\n    e: number;\n    f: number; // 1\n    constructor(\n        a: number = 1,\n        b: number = 0,\n        c: number = 0,\n        d: number = 1,\n        e: number = 0,\n        f: number = 0,\n    ) {\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.e = e;\n        this.f = f;\n    }\n    static fromMat2(m: Mat2) {\n        return new Mat23(\n            m.a,\n            m.b,\n            m.c,\n            m.d,\n            0,\n            0,\n        );\n    }\n    toMat2() {\n        return new Mat2(\n            this.a,\n            this.b,\n            this.c,\n            this.d,\n        );\n    }\n    static fromTranslation(t: Vec2) {\n        return new Mat23(\n            1,\n            0,\n            0,\n            1,\n            t.x,\n            t.y,\n        );\n    }\n    static fromRotation(radians: number) {\n        const c = Math.cos(radians);\n        const s = Math.sin(radians);\n        return new Mat23(\n            c,\n            s,\n            -s,\n            c,\n            0,\n            0,\n        );\n    }\n    static fromScale(s: Vec2): Mat23 {\n        return new Mat23(\n            s.x,\n            0,\n            0,\n            s.y,\n            0,\n            0,\n        );\n    }\n    mul(other: Mat23): Mat23 {\n        return new Mat23(\n            other.a * this.a + other.b * this.c,\n            other.a * this.b + other.b * this.d,\n            other.c * this.a + other.d * this.c,\n            other.c * this.b + other.d * this.d,\n            other.e * this.a + other.f * this.c + this.e,\n            other.e * this.b + other.f * this.d + this.f,\n        );\n    }\n    translate(t: Vec2): Mat23 {\n        this.e += t.x * this.a + t.y * this.c;\n        this.f += t.y * this.b + t.x * this.d;\n        return this;\n    }\n    rotate(radians: number): Mat23 {\n        const c = Math.cos(radians);\n        const s = Math.sin(radians);\n        const oldA = this.a;\n        const oldB = this.b;\n        this.a = c * this.a + s * this.c;\n        this.b = c * this.b + s * this.d;\n        this.c = c * this.c - s * oldA;\n        this.d = c * this.d - s * oldB;\n        return this;\n    }\n    scale(s: Vec2): Mat23 {\n        this.a *= s.x;\n        this.b *= s.x;\n        this.c *= s.y;\n        this.d *= s.y;\n        return this;\n    }\n    transform(p: Vec2) {\n        return vec2(\n            this.a * p.x + this.c * p.y + this.e,\n            this.b * p.x + this.d * p.y + this.f,\n        );\n    }\n\n    get det() {\n        return this.a * this.d - this.b * this.c;\n    }\n\n    get inverse() {\n        const det = this.det;\n        return new Mat23(\n            this.d / det,\n            -this.b / det,\n            -this.c / det,\n            this.a / det,\n            (this.c * this.f - this.d * this.e) / det,\n            (this.b * this.e - this.a * this.f) / det,\n        );\n    }\n}\n\n// Internal class\nclass Mat3 {\n    // m11 m12 m13\n    // m21 m22 m23\n    // m31 m32 m33\n    m11: number;\n    m12: number;\n    m13: number;\n    m21: number;\n    m22: number;\n    m23: number;\n    m31: number;\n    m32: number;\n    m33: number;\n\n    constructor(\n        m11: number,\n        m12: number,\n        m13: number,\n        m21: number,\n        m22: number,\n        m23: number,\n        m31: number,\n        m32: number,\n        m33: number,\n    ) {\n        this.m11 = m11;\n        this.m12 = m12;\n        this.m13 = m13;\n        this.m21 = m21;\n        this.m22 = m22;\n        this.m23 = m23;\n        this.m31 = m31;\n        this.m32 = m32;\n        this.m33 = m33;\n    }\n\n    static fromMat2(m: Mat2) {\n        return new Mat3(\n            m.a,\n            m.b,\n            0,\n            m.c,\n            m.d,\n            0,\n            0,\n            0,\n            1,\n        );\n    }\n\n    toMat2() {\n        return new Mat2(\n            this.m11,\n            this.m12,\n            this.m21,\n            this.m22,\n        );\n    }\n\n    mul(other: Mat3): Mat3 {\n        return new Mat3(\n            this.m11 * other.m11 + this.m12 * other.m21 + this.m13 * other.m31,\n            this.m11 * other.m12 + this.m12 * other.m22 + this.m13 * other.m32,\n            this.m11 * other.m13 + this.m12 * other.m23 + this.m13 * other.m33,\n            this.m21 * other.m11 + this.m22 * other.m21 + this.m23 * other.m31,\n            this.m21 * other.m12 + this.m22 * other.m22 + this.m23 * other.m32,\n            this.m21 * other.m13 + this.m22 * other.m23 + this.m23 * other.m33,\n            this.m31 * other.m11 + this.m32 * other.m21 + this.m33 * other.m31,\n            this.m31 * other.m12 + this.m32 * other.m22 + this.m33 * other.m32,\n            this.m31 * other.m13 + this.m32 * other.m23 + this.m33 * other.m33,\n        );\n    }\n\n    get det(): number {\n        return this.m11 * this.m22 * this.m33 + this.m12 * this.m23 * this.m31\n            + this.m13 * this.m21 * this.m32 - this.m13 * this.m22 * this.m31\n            - this.m12 * this.m21 * this.m33 - this.m11 * this.m23 * this.m32;\n    }\n\n    rotate(radians: number) {\n        const c = Math.cos(radians);\n        const s = Math.sin(radians);\n        const oldA = this.m11;\n        const oldB = this.m12;\n        this.m11 = c * this.m11 + s * this.m21;\n        this.m12 = c * this.m12 + s * this.m22;\n        this.m21 = c * this.m21 - s * oldA;\n        this.m22 = c * this.m22 - s * oldB;\n        return this;\n    }\n\n    scale(x: number, y: number) {\n        this.m11 *= x;\n        this.m12 *= x;\n        this.m21 *= y;\n        this.m22 *= y;\n        return this;\n    }\n\n    get inverse(): Mat3 {\n        const det = this.det;\n        return new Mat3(\n            (this.m22 * this.m33 - this.m23 * this.m32) / det,\n            (this.m13 * this.m32 - this.m12 * this.m33) / det,\n            (this.m12 * this.m23 - this.m13 * this.m22) / det,\n            (this.m23 * this.m31 - this.m21 * this.m33) / det,\n            (this.m11 * this.m33 - this.m13 * this.m31) / det,\n            (this.m13 * this.m21 - this.m11 * this.m23) / det,\n            (this.m21 * this.m32 - this.m22 * this.m31) / det,\n            (this.m12 * this.m31 - this.m11 * this.m32) / det,\n            (this.m11 * this.m22 - this.m12 * this.m21) / det,\n        );\n    }\n\n    get transpose(): Mat3 {\n        return new Mat3(\n            this.m11,\n            this.m21,\n            this.m31,\n            this.m12,\n            this.m22,\n            this.m32,\n            this.m13,\n            this.m23,\n            this.m33,\n        );\n    }\n}\n\n/**\n * @group Math\n */\nexport class Mat4 {\n    m: number[] = [\n        1,\n        0,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        1,\n    ];\n\n    constructor(m?: number[]) {\n        if (m) {\n            this.m = m;\n        }\n    }\n\n    static translate(p: Vec2): Mat4 {\n        return new Mat4([\n            1,\n            0,\n            0,\n            0,\n            0,\n            1,\n            0,\n            0,\n            0,\n            0,\n            1,\n            0,\n            p.x,\n            p.y,\n            0,\n            1,\n        ]);\n    }\n\n    static scale(s: Vec2): Mat4 {\n        return new Mat4([\n            s.x,\n            0,\n            0,\n            0,\n            0,\n            s.y,\n            0,\n            0,\n            0,\n            0,\n            1,\n            0,\n            0,\n            0,\n            0,\n            1,\n        ]);\n    }\n\n    static rotateX(a: number): Mat4 {\n        a = deg2rad(-a);\n        const c = Math.cos(a);\n        const s = Math.sin(a);\n        return new Mat4([\n            1,\n            0,\n            0,\n            0,\n            0,\n            c,\n            -s,\n            0,\n            0,\n            s,\n            c,\n            0,\n            0,\n            0,\n            0,\n            1,\n        ]);\n    }\n\n    static rotateY(a: number): Mat4 {\n        a = deg2rad(-a);\n        const c = Math.cos(a);\n        const s = Math.sin(a);\n        return new Mat4([\n            c,\n            0,\n            s,\n            0,\n            0,\n            1,\n            0,\n            0,\n            -s,\n            0,\n            c,\n            0,\n            0,\n            0,\n            0,\n            1,\n        ]);\n    }\n\n    static rotateZ(a: number): Mat4 {\n        a = deg2rad(-a);\n        const c = Math.cos(a);\n        const s = Math.sin(a);\n        return new Mat4([\n            c,\n            -s,\n            0,\n            0,\n            s,\n            c,\n            0,\n            0,\n            0,\n            0,\n            1,\n            0,\n            0,\n            0,\n            0,\n            1,\n        ]);\n    }\n\n    translate(p: Vec2) {\n        this.m[12] += this.m[0] * p.x + this.m[4] * p.y;\n        this.m[13] += this.m[1] * p.x + this.m[5] * p.y;\n        this.m[14] += this.m[2] * p.x + this.m[6] * p.y;\n        this.m[15] += this.m[3] * p.x + this.m[7] * p.y;\n        return this;\n    }\n\n    scale(p: Vec2) {\n        this.m[0] *= p.x;\n        this.m[4] *= p.y;\n        this.m[1] *= p.x;\n        this.m[5] *= p.y;\n        this.m[2] *= p.x;\n        this.m[6] *= p.y;\n        this.m[3] *= p.x;\n        this.m[7] *= p.y;\n        return this;\n    }\n\n    rotate(a: number): Mat4 {\n        a = deg2rad(-a);\n        const c = Math.cos(a);\n        const s = Math.sin(a);\n        const m0 = this.m[0];\n        const m1 = this.m[1];\n        const m4 = this.m[4];\n        const m5 = this.m[5];\n        this.m[0] = m0 * c + m1 * s;\n        this.m[1] = -m0 * s + m1 * c;\n        this.m[4] = m4 * c + m5 * s;\n        this.m[5] = -m4 * s + m5 * c;\n        return this;\n    }\n\n    // TODO: in-place variant\n    mult(other: Mat4): Mat4 {\n        const out = [];\n        for (let i = 0; i < 4; i++) {\n            for (let j = 0; j < 4; j++) {\n                out[i * 4 + j] = this.m[0 * 4 + j] * other.m[i * 4 + 0]\n                    + this.m[1 * 4 + j] * other.m[i * 4 + 1]\n                    + this.m[2 * 4 + j] * other.m[i * 4 + 2]\n                    + this.m[3 * 4 + j] * other.m[i * 4 + 3];\n            }\n        }\n        return new Mat4(out);\n    }\n\n    multVec2(p: Vec2): Vec2 {\n        return new Vec2(\n            p.x * this.m[0] + p.y * this.m[4] + this.m[12],\n            p.x * this.m[1] + p.y * this.m[5] + this.m[13],\n        );\n    }\n\n    getTranslation() {\n        return new Vec2(this.m[12], this.m[13]);\n    }\n\n    getScale() {\n        if (this.m[0] != 0 || this.m[1] != 0) {\n            const det = this.m[0] * this.m[5] - this.m[1] * this.m[4];\n            const r = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1]);\n            return new Vec2(r, det / r);\n        }\n        else if (this.m[4] != 0 || this.m[5] != 0) {\n            const det = this.m[0] * this.m[5] - this.m[1] * this.m[4];\n            const s = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5]);\n            return new Vec2(det / s, s);\n        }\n        else {\n            return new Vec2(0, 0);\n        }\n    }\n\n    getRotation() {\n        if (this.m[0] != 0 || this.m[1] != 0) {\n            const r = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1]);\n            return rad2deg(\n                this.m[1] > 0\n                    ? Math.acos(this.m[0] / r)\n                    : -Math.acos(this.m[0] / r),\n            );\n        }\n        else if (this.m[4] != 0 || this.m[5] != 0) {\n            const s = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5]);\n            return rad2deg(\n                Math.PI / 2 - (this.m[5] > 0\n                    ? Math.acos(-this.m[4] / s)\n                    : -Math.acos(this.m[4] / s)),\n            );\n        }\n        else {\n            return 0;\n        }\n    }\n\n    getSkew() {\n        if (this.m[0] != 0 || this.m[1] != 0) {\n            const r = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1]);\n            return new Vec2(\n                Math.atan(this.m[0] * this.m[4] + this.m[1] * this.m[5])\n                    / (r * r),\n                0,\n            );\n        }\n        else if (this.m[4] != 0 || this.m[5] != 0) {\n            const s = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5]);\n            return new Vec2(\n                0,\n                Math.atan(this.m[0] * this.m[4] + this.m[1] * this.m[5])\n                    / (s * s),\n            );\n        }\n        else {\n            return new Vec2(0, 0);\n        }\n    }\n\n    invert(): Mat4 {\n        const out = [];\n\n        const f00 = this.m[10] * this.m[15] - this.m[14] * this.m[11];\n        const f01 = this.m[9] * this.m[15] - this.m[13] * this.m[11];\n        const f02 = this.m[9] * this.m[14] - this.m[13] * this.m[10];\n        const f03 = this.m[8] * this.m[15] - this.m[12] * this.m[11];\n        const f04 = this.m[8] * this.m[14] - this.m[12] * this.m[10];\n        const f05 = this.m[8] * this.m[13] - this.m[12] * this.m[9];\n        const f06 = this.m[6] * this.m[15] - this.m[14] * this.m[7];\n        const f07 = this.m[5] * this.m[15] - this.m[13] * this.m[7];\n        const f08 = this.m[5] * this.m[14] - this.m[13] * this.m[6];\n        const f09 = this.m[4] * this.m[15] - this.m[12] * this.m[7];\n        const f10 = this.m[4] * this.m[14] - this.m[12] * this.m[6];\n        const f11 = this.m[5] * this.m[15] - this.m[13] * this.m[7];\n        const f12 = this.m[4] * this.m[13] - this.m[12] * this.m[5];\n        const f13 = this.m[6] * this.m[11] - this.m[10] * this.m[7];\n        const f14 = this.m[5] * this.m[11] - this.m[9] * this.m[7];\n        const f15 = this.m[5] * this.m[10] - this.m[9] * this.m[6];\n        const f16 = this.m[4] * this.m[11] - this.m[8] * this.m[7];\n        const f17 = this.m[4] * this.m[10] - this.m[8] * this.m[6];\n        const f18 = this.m[4] * this.m[9] - this.m[8] * this.m[5];\n\n        out[0] = this.m[5] * f00 - this.m[6] * f01 + this.m[7] * f02;\n        out[4] = -(this.m[4] * f00 - this.m[6] * f03 + this.m[7] * f04);\n        out[8] = this.m[4] * f01 - this.m[5] * f03 + this.m[7] * f05;\n        out[12] = -(this.m[4] * f02 - this.m[5] * f04 + this.m[6] * f05);\n\n        out[1] = -(this.m[1] * f00 - this.m[2] * f01 + this.m[3] * f02);\n        out[5] = this.m[0] * f00 - this.m[2] * f03 + this.m[3] * f04;\n        out[9] = -(this.m[0] * f01 - this.m[1] * f03 + this.m[3] * f05);\n        out[13] = this.m[0] * f02 - this.m[1] * f04 + this.m[2] * f05;\n\n        out[2] = this.m[1] * f06 - this.m[2] * f07 + this.m[3] * f08;\n        out[6] = -(this.m[0] * f06 - this.m[2] * f09 + this.m[3] * f10);\n        out[10] = this.m[0] * f11 - this.m[1] * f09 + this.m[3] * f12;\n        out[14] = -(this.m[0] * f08 - this.m[1] * f10 + this.m[2] * f12);\n\n        out[3] = -(this.m[1] * f13 - this.m[2] * f14 + this.m[3] * f15);\n        out[7] = this.m[0] * f13 - this.m[2] * f16 + this.m[3] * f17;\n        out[11] = -(this.m[0] * f14 - this.m[1] * f16 + this.m[3] * f18);\n        out[15] = this.m[0] * f15 - this.m[1] * f17 + this.m[2] * f18;\n\n        const det = this.m[0] * out[0]\n            + this.m[1] * out[4]\n            + this.m[2] * out[8]\n            + this.m[3] * out[12];\n\n        for (let i = 0; i < 4; i++) {\n            for (let j = 0; j < 4; j++) {\n                out[i * 4 + j] *= 1.0 / det;\n            }\n        }\n\n        return new Mat4(out);\n    }\n\n    clone(): Mat4 {\n        return new Mat4([...this.m]);\n    }\n\n    toString(): string {\n        return this.m.toString();\n    }\n}\n\nexport function wave(\n    lo: number,\n    hi: number,\n    t: number,\n    f = (t: number) => -Math.cos(t),\n): number {\n    return lo + (f(t) + 1) / 2 * (hi - lo);\n}\n\n// basic ANSI C LCG\nconst A = 1103515245;\nconst C = 12345;\nconst M = 2147483648;\n\n/**\n * @group Math\n */\nexport class RNG {\n    seed: number;\n    constructor(seed: number) {\n        this.seed = seed;\n    }\n    gen(): number {\n        this.seed = (A * this.seed + C) % M;\n        return this.seed / M;\n    }\n    genNumber(a: number, b: number): number {\n        return a + this.gen() * (b - a);\n    }\n    genVec2(a: Vec2, b: Vec2): Vec2 {\n        return new Vec2(\n            this.genNumber(a.x, b.x),\n            this.genNumber(a.y, b.y),\n        );\n    }\n    genColor(a: Color, b: Color): Color {\n        return new Color(\n            this.genNumber(a.r, b.r),\n            this.genNumber(a.g, b.g),\n            this.genNumber(a.b, b.b),\n        );\n    }\n    genAny<T = RNGValue>(...args: [] | [T] | [T, T]): T {\n        if (args.length === 0) {\n            return this.gen() as T;\n        }\n        else if (args.length === 1) {\n            if (typeof args[0] === \"number\") {\n                return this.genNumber(0, args[0]) as T;\n            }\n            else if (args[0] instanceof Vec2) {\n                return this.genVec2(vec2(0, 0), args[0]) as T;\n            }\n            else if (args[0] instanceof Color) {\n                return this.genColor(rgb(0, 0, 0), args[0]) as T;\n            }\n        }\n        else if (args.length === 2) {\n            if (typeof args[0] === \"number\" && typeof args[1] === \"number\") {\n                return this.genNumber(args[0], args[1]) as T;\n            }\n            else if (args[0] instanceof Vec2 && args[1] instanceof Vec2) {\n                return this.genVec2(args[0], args[1]) as T;\n            }\n            else if (args[0] instanceof Color && args[1] instanceof Color) {\n                return this.genColor(args[0], args[1]) as T;\n            }\n        }\n\n        throw new Error(\"More than 2 arguments not supported\");\n    }\n}\n\n// TODO: let user pass seed\nconst defRNG = new RNG(Date.now());\n\nexport function randSeed(seed?: number): number {\n    if (seed != null) {\n        defRNG.seed = seed;\n    }\n    return defRNG.seed;\n}\n\nexport function rand<T = number>(...args: [] | [T] | [T, T]) {\n    return defRNG.genAny(...args);\n}\n\nexport function randi(...args: [] | [number] | [number, number]) {\n    return Math.floor(rand(...(args.length > 0 ? args : [2])));\n}\n\nexport function chance(p: number): boolean {\n    return rand() <= p;\n}\n\nexport function shuffle<T>(list: T[]): T[] {\n    for (let i = list.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [list[i], list[j]] = [list[j], list[i]];\n    }\n    return list;\n}\n\nexport function chooseMultiple<T>(list: T[], count: number): T[] {\n    return list.length <= count\n        ? list.slice()\n        : shuffle(list.slice()).slice(0, count);\n}\n\nexport function choose<T>(list: T[]): T {\n    return list[randi(list.length)];\n}\n\n// TODO: better name\nexport function testRectRect2(r1: Rect, r2: Rect): boolean {\n    return r1.pos.x + r1.width >= r2.pos.x\n        && r1.pos.x <= r2.pos.x + r2.width\n        && r1.pos.y + r1.height >= r2.pos.y\n        && r1.pos.y <= r2.pos.y + r2.height;\n}\n\nexport function testRectRect(r1: Rect, r2: Rect): boolean {\n    return r1.pos.x + r1.width > r2.pos.x\n        && r1.pos.x < r2.pos.x + r2.width\n        && r1.pos.y + r1.height > r2.pos.y\n        && r1.pos.y < r2.pos.y + r2.height;\n}\n\n// TODO: better name\nexport function testLineLineT(l1: Line, l2: Line): number | null {\n    if (\n        (l1.p1.x === l1.p2.x && l1.p1.y === l1.p2.y)\n        || (l2.p1.x === l2.p2.x && l2.p1.y === l2.p2.y)\n    ) {\n        return null;\n    }\n\n    const denom = (l2.p2.y - l2.p1.y) * (l1.p2.x - l1.p1.x)\n        - (l2.p2.x - l2.p1.x) * (l1.p2.y - l1.p1.y);\n\n    // parallel\n    if (denom === 0) {\n        return null;\n    }\n\n    const ua = ((l2.p2.x - l2.p1.x) * (l1.p1.y - l2.p1.y)\n        - (l2.p2.y - l2.p1.y) * (l1.p1.x - l2.p1.x)) / denom;\n    const ub = ((l1.p2.x - l1.p1.x) * (l1.p1.y - l2.p1.y)\n        - (l1.p2.y - l1.p1.y) * (l1.p1.x - l2.p1.x)) / denom;\n\n    // is the intersection on the segments\n    if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {\n        return null;\n    }\n\n    return ua;\n}\n\nexport function testLineLine(l1: Line, l2: Line): Vec2 | null {\n    const t = testLineLineT(l1, l2);\n    if (!t) return null;\n    return vec2(\n        l1.p1.x + t * (l1.p2.x - l1.p1.x),\n        l1.p1.y + t * (l1.p2.y - l1.p1.y),\n    );\n}\n\nexport function testRectLine(r: Rect, l: Line): boolean {\n    /*if (testRectPoint(r, l.p1) || testRectPoint(r, l.p2)) {\n        return true\n    }\n    const pts = r.points()\n    return !!testLineLine(l, new Line(pts[0], pts[1]))\n        || !!testLineLine(l, new Line(pts[1], pts[2]))\n        || !!testLineLine(l, new Line(pts[2], pts[3]))\n        || !!testLineLine(l, new Line(pts[3], pts[0]))*/\n    const dir = l.p2.sub(l.p1);\n    let tmin = Number.NEGATIVE_INFINITY, tmax = Number.POSITIVE_INFINITY;\n\n    if (dir.x != 0.0) {\n        const tx1 = (r.pos.x - l.p1.x) / dir.x;\n        const tx2 = (r.pos.x + r.width - l.p1.x) / dir.x;\n\n        tmin = Math.max(tmin, Math.min(tx1, tx2));\n        tmax = Math.min(tmax, Math.max(tx1, tx2));\n    }\n\n    if (dir.y != 0.0) {\n        const ty1 = (r.pos.y - l.p1.y) / dir.y;\n        const ty2 = (r.pos.y + r.height - l.p1.y) / dir.y;\n\n        tmin = Math.max(tmin, Math.min(ty1, ty2));\n        tmax = Math.min(tmax, Math.max(ty1, ty2));\n    }\n\n    return tmax >= tmin && tmax >= 0 && tmin <= 1;\n}\n\nexport function testRectPoint2(r: Rect, pt: Vec2): boolean {\n    return pt.x >= r.pos.x\n        && pt.x <= r.pos.x + r.width\n        && pt.y >= r.pos.y\n        && pt.y <= r.pos.y + r.height;\n}\n\nexport function testRectPoint(r: Rect, pt: Vec2): boolean {\n    return pt.x > r.pos.x\n        && pt.x < r.pos.x + r.width\n        && pt.y > r.pos.y\n        && pt.y < r.pos.y + r.height;\n}\n\nexport function testRectCircle(r: Rect, c: Circle): boolean {\n    const nx = Math.max(r.pos.x, Math.min(c.center.x, r.pos.x + r.width));\n    const ny = Math.max(r.pos.y, Math.min(c.center.y, r.pos.y + r.height));\n    const nearestPoint = vec2(nx, ny);\n    return nearestPoint.sdist(c.center) <= c.radius * c.radius;\n}\n\nexport function testRectPolygon(r: Rect, p: Polygon): boolean {\n    return testPolygonPolygon(p, new Polygon(r.points()));\n}\n\nexport function testLinePoint(l: Line, pt: Vec2): boolean {\n    const v1 = pt.sub(l.p1);\n    const v2 = l.p2.sub(l.p1);\n\n    // Check if sine is 0, in that case lines are parallel.\n    // If not parallel, the point cannot lie on the line.\n    if (Math.abs(v1.cross(v2)) > Number.EPSILON) {\n        return false;\n    }\n\n    // Scalar projection of v1 on v2\n    const t = v1.dot(v2) / v2.dot(v2);\n    // Since t is percentual distance of pt from line.p1 on the line,\n    // it should be between 0% and 100%\n    return t >= 0 && t <= 1;\n}\n\nexport function testLineCircle(l: Line, circle: Circle): boolean {\n    const v = l.p2.sub(l.p1);\n    const a = v.dot(v);\n    const centerToOrigin = l.p1.sub(circle.center);\n    const b = 2 * v.dot(centerToOrigin);\n    const c = centerToOrigin.dot(centerToOrigin)\n        - circle.radius * circle.radius;\n    // Calculate the discriminant of ax^2 + bx + c\n    const dis = b * b - 4 * a * c;\n\n    // No root\n    if ((a <= Number.EPSILON) || (dis < 0)) {\n        return false;\n    }\n    // One possible root\n    else if (dis == 0) {\n        const t = -b / (2 * a);\n        if (t >= 0 && t <= 1) {\n            return true;\n        }\n    }\n    // Two possible roots\n    else {\n        const t1 = (-b + Math.sqrt(dis)) / (2 * a);\n        const t2 = (-b - Math.sqrt(dis)) / (2 * a);\n        if ((t1 >= 0 && t1 <= 1) || (t2 >= 0 && t2 <= 1)) {\n            return true;\n        }\n    }\n\n    // Check if line is completely within the circle\n    // We only need to check one point, since the line didn't cross the circle\n    return testCirclePoint(circle, l.p1);\n}\n\nexport function testLinePolygon(l: Line, p: Polygon): boolean {\n    // test if line is inside\n    if (testPolygonPoint(p, l.p1) || testPolygonPoint(p, l.p2)) {\n        return true;\n    }\n\n    // test each line\n    for (let i = 0; i < p.pts.length; i++) {\n        const p1 = p.pts[i];\n        const p2 = p.pts[(i + 1) % p.pts.length];\n        if (testLineLine(l, new Line(p1, p2))) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\nexport function testCirclePoint(c: Circle, p: Vec2): boolean {\n    return c.center.sdist(p) < c.radius * c.radius;\n}\n\nexport function testCircleCircle(c1: Circle, c2: Circle): boolean {\n    return c1.center.sdist(c2.center)\n        < (c1.radius + c2.radius) * (c1.radius + c2.radius);\n}\n\nexport function testCirclePolygon(c: Circle, p: Polygon): boolean {\n    // For each edge check for intersection\n    let prev = p.pts[p.pts.length - 1];\n    for (const cur of p.pts) {\n        if (testLineCircle(new Line(prev, cur), c)) {\n            return true;\n        }\n        prev = cur;\n    }\n\n    // Check if the polygon is completely within the circle\n    // We only need to check one point, since the polygon didn't cross the circle\n    if (testCirclePoint(c, p.pts[0])) {\n        return true;\n    }\n\n    // Check if the circle is completely within the polygon\n    return testPolygonPoint(p, c.center);\n}\n\nexport function testPolygonPolygon(p1: Polygon, p2: Polygon): boolean {\n    for (let i = 0; i < p1.pts.length; i++) {\n        if (\n            testLinePolygon(\n                new Line(p1.pts[i], p1.pts[(i + 1) % p1.pts.length]),\n                p2,\n            )\n        ) {\n            return true;\n        }\n    }\n    // Check if any of the points of the polygon lie in the other polygon\n    if (\n        p1.pts.some(p => testPolygonPoint(p2, p))\n        || p2.pts.some(p => testPolygonPoint(p1, p))\n    ) {\n        return true;\n    }\n    return false;\n}\n\n// https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html\nexport function testPolygonPoint(poly: Polygon, pt: Vec2): boolean {\n    let c = false;\n    const p = poly.pts;\n\n    for (let i = 0, j = p.length - 1; i < p.length; j = i++) {\n        if (\n            ((p[i].y > pt.y) != (p[j].y > pt.y))\n            && (pt.x\n                < (p[j].x - p[i].x) * (pt.y - p[i].y) / (p[j].y - p[i].y)\n                    + p[i].x)\n        ) {\n            c = !c;\n        }\n    }\n\n    return c;\n}\n\nexport function testEllipsePoint(ellipse: Ellipse, pt: Vec2): boolean {\n    // Transform the point into the ellipse's unrotated coordinate system at the origin\n    pt = pt.sub(ellipse.center);\n    const angle = deg2rad(ellipse.angle);\n    const c = Math.cos(angle);\n    const s = Math.sin(angle);\n    const vx = pt.x * c + pt.y * s;\n    const vy = -pt.x * s + pt.y * c;\n    return vx * vx / (ellipse.radiusX * ellipse.radiusX)\n            + vy * vy / (ellipse.radiusY * ellipse.radiusY) < 1;\n}\n\nexport function testEllipseCircle(ellipse: Ellipse, circle: Circle): boolean {\n    // This is an approximation, because the parallel curve of an ellipse is an octic algebraic curve, not just a larger ellipse.\n    // Transform the circle's center into the ellipse's unrotated coordinate system at the origin\n    const center = circle.center.sub(ellipse.center);\n    const angle = deg2rad(ellipse.angle);\n    const c = Math.cos(angle);\n    const s = Math.sin(angle);\n    const cx = center.x * c + center.y * s;\n    const cy = -center.x * s + center.y * c;\n    // Test with an approximate Minkowski sum of the ellipse and the circle\n    return testEllipsePoint(\n        new Ellipse(\n            vec2(),\n            ellipse.radiusX + circle.radius,\n            ellipse.radiusY + circle.radius,\n            0,\n        ),\n        vec2(cx, cy),\n    );\n}\n\nexport function testEllipseLine(ellipse: Ellipse, line: Line): boolean {\n    // Transform the line to the coordinate system where the ellipse is a unit circle\n    const T = ellipse.toMat2().inverse;\n    line = new Line(\n        T.transform(line.p1.sub(ellipse.center)),\n        T.transform(line.p2.sub(ellipse.center)),\n    );\n    return testLineCircle(line, new Circle(vec2(), 1));\n}\n\nexport function testEllipseEllipse(\n    ellipse1: Ellipse,\n    ellipse2: Ellipse,\n): boolean {\n    // First check if one of the ellipses isn't secretly a circle\n    if (ellipse1.radiusX === ellipse1.radiusY) {\n        return testEllipseCircle(\n            ellipse2,\n            new Circle(ellipse1.center, ellipse1.radiusX),\n        );\n    }\n    else if (ellipse2.radiusX === ellipse2.radiusY) {\n        return testEllipseCircle(\n            ellipse1,\n            new Circle(ellipse2.center, ellipse2.radiusX),\n        );\n    }\n    // No luck, we need to solve the equation\n    /*\n    Etayo, Fernando, Laureano Gonzalez-Vega, and Natalia del Rio. \"A new approach to characterizing the relative position of two ellipses depending on one parameter.\" Computer aided geometric design 23, no. 4 (2006): 324-350.\n    */\n    const A1 = new Mat3(\n        1 / ellipse1.radiusX ** 2,\n        0,\n        0,\n        0,\n        1 / ellipse1.radiusY ** 2,\n        0,\n        0,\n        0,\n        -1,\n    );\n    const A2 = new Mat3(\n        1 / ellipse2.radiusX ** 2,\n        0,\n        0,\n        0,\n        1 / ellipse2.radiusY ** 2,\n        0,\n        0,\n        0,\n        -1,\n    );\n\n    const x1 = ellipse1.center.x;\n    const y1 = ellipse1.center.y;\n    const x2 = ellipse2.center.x;\n    const y2 = ellipse2.center.y;\n    const theta1 = deg2rad(ellipse1.angle);\n    const theta2 = deg2rad(ellipse2.angle);\n\n    const M1 = new Mat3(\n        Math.cos(theta1),\n        -Math.sin(theta1),\n        x1,\n        Math.sin(theta1),\n        Math.cos(theta1),\n        y1,\n        0,\n        0,\n        1,\n    );\n    const M2 = new Mat3(\n        Math.cos(theta2),\n        -Math.sin(theta2),\n        x2,\n        Math.sin(theta2),\n        Math.cos(theta2),\n        y2,\n        0,\n        0,\n        1,\n    );\n    const M1inv = M1.inverse;\n    const M2inv = M2.inverse;\n\n    const A = M1inv.transpose.mul(A1).mul(M1inv);\n    const B = M2inv.transpose.mul(A2).mul(M2inv);\n\n    const a11 = A.m11;\n    const a12 = A.m12;\n    const a13 = A.m13;\n    const a21 = A.m21;\n    const a22 = A.m22;\n    const a23 = A.m23;\n    const a31 = A.m31;\n    const a32 = A.m32;\n    const a33 = A.m33;\n\n    const b11 = B.m11;\n    const b12 = B.m12;\n    const b13 = B.m13;\n    const b21 = B.m21;\n    const b22 = B.m22;\n    const b23 = B.m23;\n    const b31 = B.m31;\n    const b32 = B.m32;\n    const b33 = B.m33;\n\n    const factor = a11 * a22 * a33 - a11 * a23 * a32 - a12 * a21 * a33\n        + a12 * a23 * a31 + a13 * a21 * a32 - a13 * a22 * a31;\n    const a =\n        (a11 * a22 * b33 - a11 * a23 * b32 - a11 * a32 * b23 + a11 * a33 * b22\n            - a12 * a21 * b33 + a12 * a23 * b31 + a12 * a31 * b23\n            - a12 * a33 * b21 + a13 * a21 * b32 - a13 * a22 * b31\n            - a13 * a31 * b22 + a13 * a32 * b21 + a21 * a32 * b13\n            - a21 * a33 * b12 - a22 * a31 * b13 + a22 * a33 * b11\n            + a23 * a31 * b12 - a23 * a32 * b11) / factor;\n    const b =\n        (a11 * b22 * b33 - a11 * b23 * b32 - a12 * b21 * b33 + a12 * b23 * b31\n            + a13 * b21 * b32 - a13 * b22 * b31 - a21 * b12 * b33\n            + a21 * b13 * b32 + a22 * b11 * b33 - a22 * b13 * b31\n            - a23 * b11 * b32 + a23 * b12 * b31 + a31 * b12 * b23\n            - a31 * b13 * b22 - a32 * b11 * b23 + a32 * b13 * b21\n            + a33 * b11 * b22 - a33 * b12 * b21) / factor;\n    const c =\n        (b11 * b22 * b33 - b11 * b23 * b32 - b12 * b21 * b33 + b12 * b23 * b31\n            + b13 * b21 * b32 - b13 * b22 * b31) / factor;\n\n    if (a >= 0) {\n        const condition1 = -3 * b + a ** 2;\n        const condition2 = 3 * a * c + b * a ** 2 - 4 * b ** 2;\n        const condition3 = -27 * c ** 2 + 18 * c * a * b + a ** 2 * b ** 2\n            - 4 * a ** 3 * c - 4 * b ** 3;\n        if (condition1 > 0 && condition2 < 0 && condition3 > 0) {\n            return false;\n        }\n        else {\n            return true;\n        }\n    }\n    else {\n        const condition1 = -3 * b + a ** 2;\n        const condition2 = -27 * c ** 2 + 18 * c * a * b + a ** 2 * b ** 2\n            - 4 * a ** 3 * c - 4 * b ** 3;\n        if (condition1 > 0 && condition2 > 0) {\n            return false;\n        }\n        else {\n            return true;\n        }\n    }\n}\n\nexport function testEllipseRect(ellipse: Ellipse, rect: Rect): boolean {\n    return testEllipsePolygon(ellipse, new Polygon(rect.points()));\n}\n\nexport function testEllipsePolygon(ellipse: Ellipse, poly: Polygon): boolean {\n    // Transform the polygon to the coordinate system where the ellipse is a unit circle\n    const T = ellipse.toMat2().inverse;\n    poly = new Polygon(poly.pts.map(p => T.transform(p.sub(ellipse.center))));\n    return testCirclePolygon(new Circle(vec2(), 1), poly);\n}\n\nexport function testPointPoint(p1: Vec2, p2: Vec2): boolean {\n    return p1.x === p2.x && p1.y === p2.y;\n}\n\n/**\n * @group Math\n */\nexport type ShapeType = Point | Circle | Line | Rect | Polygon | Ellipse;\n\nexport function testPointShape(point: Point, shape: ShapeType): boolean {\n    if (shape instanceof Vec2) {\n        return testPointPoint(shape as Vec2, point.pt);\n    }\n    else if (shape instanceof Circle) {\n        return testCirclePoint(shape as Circle, point.pt);\n    }\n    else if (shape instanceof Line) {\n        return testLinePoint(shape as Line, point.pt);\n    }\n    else if (shape instanceof Rect) {\n        return testRectPoint(shape as Rect, point.pt);\n    }\n    else if (shape instanceof Polygon) {\n        return testPolygonPoint(shape as Polygon, point.pt);\n    }\n    else if (shape instanceof Ellipse) {\n        return testEllipsePoint(shape as Ellipse, point.pt);\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testLineShape(line: Line, shape: ShapeType | Vec2): boolean {\n    if (shape instanceof Vec2) {\n        return testLinePoint(line, shape as Vec2);\n    }\n    else if (shape instanceof Circle) {\n        return testLineCircle(line, shape as Circle);\n    }\n    else if (shape instanceof Line) {\n        return testLineLine(line, shape as Line) != null;\n    }\n    else if (shape instanceof Rect) {\n        return testRectLine(shape as Rect, line);\n    }\n    else if (shape instanceof Polygon) {\n        return testLinePolygon(line, shape as Polygon);\n    }\n    else if (shape instanceof Ellipse) {\n        return testEllipseLine(shape as Ellipse, line);\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testCircleShape(\n    circle: Circle,\n    shape: ShapeType | Vec2,\n): boolean {\n    if (shape instanceof Vec2) {\n        return testCirclePoint(circle, shape as Vec2);\n    }\n    else if (shape instanceof Circle) {\n        return testCircleCircle(circle, shape as Circle);\n    }\n    else if (shape instanceof Line) {\n        return testLineCircle(shape as Line, circle);\n    }\n    else if (shape instanceof Rect) {\n        return testRectCircle(shape as Rect, circle);\n    }\n    else if (shape instanceof Polygon) {\n        return testCirclePolygon(circle, shape as Polygon);\n    }\n    else if (shape instanceof Ellipse) {\n        return testEllipseCircle(shape as Ellipse, circle);\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testRectShape(rect: Rect, shape: ShapeType | Vec2): boolean {\n    if (shape instanceof Vec2) {\n        return testRectPoint(rect, shape as Vec2);\n    }\n    else if (shape instanceof Circle) {\n        return testRectCircle(rect, shape as Circle);\n    }\n    else if (shape instanceof Line) {\n        return testRectLine(rect, shape as Line);\n    }\n    else if (shape instanceof Rect) {\n        return testRectRect(rect, shape as Rect);\n    }\n    else if (shape instanceof Polygon) {\n        return testRectPolygon(rect, shape as Polygon);\n    }\n    else if (shape instanceof Ellipse) {\n        return testEllipseRect(shape as Ellipse, rect);\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testPolygonShape(\n    polygon: Polygon,\n    shape: ShapeType | Vec2,\n): boolean {\n    if (shape instanceof Vec2) {\n        return testPolygonPoint(polygon, shape as Vec2);\n    }\n    else if (shape instanceof Circle) {\n        return testCirclePolygon(shape as Circle, polygon);\n    }\n    else if (shape instanceof Line) {\n        return testLinePolygon(shape as Line, polygon);\n    }\n    else if (shape instanceof Rect) {\n        return testRectPolygon(shape as Rect, polygon);\n    }\n    else if (shape instanceof Polygon) {\n        return testPolygonPolygon(shape as Polygon, polygon);\n    }\n    else if (shape instanceof Ellipse) {\n        return testEllipsePolygon(shape as Ellipse, polygon);\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testEllipseShape(ellipse: Ellipse, shape: ShapeType): boolean {\n    if (shape instanceof Vec2) {\n        return testEllipsePoint(ellipse, shape as Vec2);\n    }\n    else if (shape instanceof Circle) {\n        return testEllipseCircle(ellipse, shape as Circle);\n    }\n    else if (shape instanceof Line) {\n        return testEllipseLine(ellipse, shape as Line);\n    }\n    else if (shape instanceof Rect) {\n        return testEllipseRect(ellipse, shape as Rect);\n    }\n    else if (shape instanceof Polygon) {\n        return testEllipsePolygon(ellipse, shape as Polygon);\n    }\n    else if (shape instanceof Ellipse) {\n        return testEllipseEllipse(shape as Ellipse, ellipse);\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testShapeShape(shape1: ShapeType, shape2: ShapeType): boolean {\n    if (shape1 instanceof Vec2) {\n        return testPointShape(new Point(shape1), shape2);\n    }\n    else if (shape1 instanceof Circle) {\n        return testCircleShape(shape1 as Circle, shape2);\n    }\n    else if (shape1 instanceof Line) {\n        return testLineShape(shape1 as Line, shape2);\n    }\n    else if (shape1 instanceof Rect) {\n        return testRectShape(shape1 as Rect, shape2);\n    }\n    else if (shape1 instanceof Polygon) {\n        return testPolygonShape(shape1 as Polygon, shape2);\n    }\n    else if (shape1 instanceof Ellipse) {\n        return testEllipseShape(shape1 as Ellipse, shape2);\n    }\n    else {\n        return false;\n    }\n}\n\n/**\n * @group Math\n */\nexport type RaycastHit = {\n    fraction: number;\n    normal: Vec2;\n    point: Vec2;\n    gridPos?: Vec2;\n    object?: GameObj;\n};\n\n/**\n * @group Math\n */\nexport type RaycastResult = RaycastHit | null;\n\nfunction raycastLine(origin: Vec2, direction: Vec2, line: Line): RaycastResult {\n    const a = origin;\n    const c = line.p1;\n    const d = line.p2;\n    const ab = direction;\n    const cd = d.sub(c);\n    const abxcd = ab.cross(cd);\n    // If parallel, no intersection\n    if (Math.abs(abxcd) < Number.EPSILON) {\n        return null;\n    }\n    const ac = c.sub(a);\n    const s = ac.cross(cd) / abxcd;\n    // Outside the ray\n    if (s <= 0 || s >= 1) {\n        return null;\n    }\n    // Outside the line\n    const t = ac.cross(ab) / abxcd;\n    if (t <= 0 || t >= 1) {\n        return null;\n    }\n\n    const normal = cd.normal().unit();\n    if (direction.dot(normal) > 0) {\n        normal.x *= -1;\n        normal.y *= -1;\n    }\n\n    return {\n        point: a.add(ab.scale(s)),\n        normal: normal,\n        fraction: s,\n    };\n}\n\nfunction raycastRect(origin: Vec2, direction: Vec2, rect: Rect) {\n    let tmin = Number.NEGATIVE_INFINITY, tmax = Number.POSITIVE_INFINITY;\n    let normal;\n\n    if (origin.x != 0.0) {\n        const tx1 = (rect.pos.x - origin.x) / direction.x;\n        const tx2 = (rect.pos.x + rect.width - origin.x) / direction.x;\n\n        normal = vec2(-Math.sign(direction.x), 0);\n\n        tmin = Math.max(tmin, Math.min(tx1, tx2));\n        tmax = Math.min(tmax, Math.max(tx1, tx2));\n    }\n\n    if (origin.y != 0.0) {\n        const ty1 = (rect.pos.y - origin.y) / direction.y;\n        const ty2 = (rect.pos.y + rect.height - origin.y) / direction.y;\n\n        if (Math.min(ty1, ty2) > tmin) {\n            normal = vec2(0, -Math.sign(direction.y));\n        }\n\n        tmin = Math.max(tmin, Math.min(ty1, ty2));\n        tmax = Math.min(tmax, Math.max(ty1, ty2));\n    }\n\n    if (tmax >= tmin && tmin >= 0 && tmin <= 1) {\n        const point = origin.add(direction.scale(tmin));\n\n        return {\n            point: point,\n            normal: normal,\n            fraction: tmin,\n        };\n    }\n    else {\n        return null;\n    }\n}\n\nfunction raycastCircle(\n    origin: Vec2,\n    direction: Vec2,\n    circle: Circle,\n): RaycastResult {\n    const a = origin;\n    const c = circle.center;\n    const ab = direction;\n    const A = ab.dot(ab);\n    const centerToOrigin = a.sub(c);\n    const B = 2 * ab.dot(centerToOrigin);\n    const C = centerToOrigin.dot(centerToOrigin)\n        - circle.radius * circle.radius;\n    // Calculate the discriminant of ax^2 + bx + c\n    const disc = B * B - 4 * A * C;\n    // No root\n    if ((A <= Number.EPSILON) || (disc < 0)) {\n        return null;\n    }\n    // One possible root\n    else if (disc == 0) {\n        const t = -B / (2 * A);\n        if (t >= 0 && t <= 1) {\n            const point = a.add(ab.scale(t));\n            return {\n                point: point,\n                normal: point.sub(c),\n                fraction: t,\n            };\n        }\n    }\n    // Two possible roots\n    else {\n        const t1 = (-B + Math.sqrt(disc)) / (2 * A);\n        const t2 = (-B - Math.sqrt(disc)) / (2 * A);\n        let t = null;\n        if (t1 >= 0 && t1 <= 1) {\n            t = t1;\n        }\n        if (t2 >= 0 && t2 <= 1) {\n            t = Math.min(t2, t ?? t2);\n        }\n        if (t != null) {\n            const point = a.add(ab.scale(t));\n            return {\n                point: point,\n                normal: point.sub(c).unit(),\n                fraction: t,\n            };\n        }\n    }\n\n    return null;\n}\n\nfunction raycastPolygon(\n    origin: Vec2,\n    direction: Vec2,\n    polygon: Polygon,\n): RaycastResult {\n    const points = polygon.pts;\n    let minHit = null;\n\n    let prev = points[points.length - 1];\n    for (let i = 0; i < points.length; i++) {\n        const cur = points[i];\n        const hit = raycastLine(origin, direction, new Line(prev, cur));\n        if (hit && (!minHit || minHit.fraction > hit.fraction)) {\n            minHit = hit;\n        }\n        prev = cur;\n    }\n\n    return minHit;\n}\n\nfunction raycastEllipse(\n    origin: Vec2,\n    direction: Vec2,\n    ellipse: Ellipse,\n): RaycastResult {\n    // Transforms from unit circle to rotated ellipse\n    const T = ellipse.toMat2();\n    // Transforms from rotated ellipse to unit circle\n    const TI = T.inverse;\n    // Transform both origin and direction into the unit circle coordinate system\n    const Torigin = TI.transform(origin.sub(ellipse.center));\n    const Tdirection = TI.transform(direction);\n    // Raycast as if we have a circle\n    const result = raycastCircle(Torigin, Tdirection, new Circle(vec2(), 1));\n    if (result) {\n        const R = Mat2.rotation(deg2rad(-ellipse.angle));\n        const S = Mat2.scale(ellipse.radiusX, ellipse.radiusY);\n        // Scale the point so we have a point on the unrotated ellipse\n        const p = S.transform(result.point);\n        // transform the result point to the coordinate system of the rotated ellipse\n        const point = T.transform(result.point).add(ellipse.center);\n        const fraction = point.dist(origin) / direction.len();\n        return {\n            point: point,\n            // Calculate the normal at the unrotated ellipse, then rotate the normal to the rotated ellipse\n            normal: R.transform(\n                vec2(ellipse.radiusY ** 2 * p.x, ellipse.radiusX ** 2 * p.y),\n            ).unit(),\n            fraction,\n        };\n    }\n    return result;\n}\n\nexport function raycastGrid(\n    origin: Vec2,\n    direction: Vec2,\n    gridPosHit: (gridPos: Vec2) => boolean | RaycastResult,\n    maxDistance: number = 64,\n): RaycastResult | null {\n    const pos = origin;\n    const len = direction.len();\n    const dir = direction.scale(1 / len);\n    let t = 0;\n    const gridPos = vec2(Math.floor(origin.x), Math.floor(origin.y));\n    const step = vec2(dir.x > 0 ? 1 : -1, dir.y > 0 ? 1 : -1);\n    const tDelta = vec2(Math.abs(1 / dir.x), Math.abs(1 / dir.y));\n    const dist = vec2(\n        (step.x > 0) ? (gridPos.x + 1 - origin.x) : (origin.x - gridPos.x),\n        (step.y > 0) ? (gridPos.y + 1 - origin.y) : (origin.y - gridPos.y),\n    );\n    const tMax = vec2(\n        (tDelta.x < Infinity) ? tDelta.x * dist.x : Infinity,\n        (tDelta.y < Infinity) ? tDelta.y * dist.y : Infinity,\n    );\n    let steppedIndex = -1;\n    while (t <= maxDistance) {\n        const hit = gridPosHit(gridPos);\n        if (hit === true) {\n            return {\n                point: pos.add(dir.scale(t)),\n                normal: vec2(\n                    steppedIndex === 0 ? -step.x : 0,\n                    steppedIndex === 1 ? -step.y : 0,\n                ),\n                fraction: t / len, // Since dir is normalized, t is len times too large\n                gridPos,\n            };\n        }\n        else if (hit) {\n            return hit;\n        }\n        if (tMax.x < tMax.y) {\n            gridPos.x += step.x;\n            t = tMax.x;\n            tMax.x += tDelta.x;\n            steppedIndex = 0;\n        }\n        else {\n            gridPos.y += step.y;\n            t = tMax.y;\n            tMax.y += tDelta.y;\n            steppedIndex = 1;\n        }\n    }\n\n    return null;\n}\n\nexport class Point {\n    pt: Vec2;\n    constructor(pt: Vec2) {\n        this.pt = pt.clone();\n    }\n    transform(m: Mat4): Point {\n        return new Point(m.multVec2(this.pt));\n    }\n    bbox(): Rect {\n        return new Rect(this.pt, 0, 0);\n    }\n    area(): number {\n        return 0;\n    }\n    clone(): Point {\n        return new Point(this.pt);\n    }\n    collides(shape: ShapeType): boolean {\n        return testPointShape(this, shape);\n    }\n    contains(point: Vec2): boolean {\n        return this.pt.eq(point);\n    }\n    raycast(origin: Vec2, direction: Vec2): RaycastResult {\n        return null;\n    }\n    random(): Vec2 {\n        return this.pt.clone();\n    }\n}\n\n/**\n * @group Math\n */\nexport class Line {\n    p1: Vec2;\n    p2: Vec2;\n    constructor(p1: Vec2, p2: Vec2) {\n        this.p1 = p1.clone();\n        this.p2 = p2.clone();\n    }\n    transform(m: Mat4): Line {\n        return new Line(m.multVec2(this.p1), m.multVec2(this.p2));\n    }\n    bbox(): Rect {\n        return Rect.fromPoints(this.p1, this.p2);\n    }\n    area(): number {\n        return this.p1.dist(this.p2);\n    }\n    clone(): Line {\n        return new Line(this.p1, this.p2);\n    }\n    collides(shape: ShapeType | Vec2): boolean {\n        return testLineShape(this, shape);\n    }\n    contains(point: Vec2): boolean {\n        return this.collides(point);\n    }\n    raycast(origin: Vec2, direction: Vec2): RaycastResult {\n        return raycastLine(origin, direction, this);\n    }\n    random(): Vec2 {\n        return this.p1.add(this.p2.sub(this.p1).scale(rand(1)));\n    }\n}\n\n// TODO: use x: number y: number (x, y, width, height)\n/**\n * @group Math\n */\nexport class Rect {\n    pos: Vec2;\n    width: number;\n    height: number;\n    constructor(pos: Vec2, width: number, height: number) {\n        this.pos = pos.clone();\n        this.width = width;\n        this.height = height;\n    }\n    static fromPoints(p1: Vec2, p2: Vec2): Rect {\n        return new Rect(p1.clone(), p2.x - p1.x, p2.y - p1.y);\n    }\n    center(): Vec2 {\n        return new Vec2(\n            this.pos.x + this.width / 2,\n            this.pos.y + this.height / 2,\n        );\n    }\n    points(): [Vec2, Vec2, Vec2, Vec2] {\n        return [\n            this.pos,\n            this.pos.add(this.width, 0),\n            this.pos.add(this.width, this.height),\n            this.pos.add(0, this.height),\n        ];\n    }\n    transform(m: Mat4): Polygon {\n        return new Polygon(this.points().map((pt) => m.multVec2(pt)));\n    }\n    bbox(): Rect {\n        return this.clone();\n    }\n    area(): number {\n        return this.width * this.height;\n    }\n    clone(): Rect {\n        return new Rect(this.pos.clone(), this.width, this.height);\n    }\n    distToPoint(p: Vec2): number {\n        return Math.sqrt(this.sdistToPoint(p));\n    }\n    sdistToPoint(p: Vec2): number {\n        const min = this.pos;\n        const max = this.pos.add(this.width, this.height);\n        const dx = Math.max(min.x - p.x, 0, p.x - max.x);\n        const dy = Math.max(min.y - p.y, 0, p.y - max.y);\n        return dx * dx + dy * dy;\n    }\n    collides(shape: ShapeType | Vec2): boolean {\n        return testRectShape(this, shape);\n    }\n    contains(point: Vec2): boolean {\n        return this.collides(point);\n    }\n    raycast(origin: Vec2, direction: Vec2): RaycastResult {\n        // Further type checking is needed here @mflerackers\n        // @ts-ignore\n        return raycastRect(origin, direction, this);\n    }\n    random(): Vec2 {\n        return this.pos.add(rand(this.width), rand(this.height));\n    }\n}\n\n/**\n * @group Math\n */\nexport class Circle {\n    center: Vec2;\n    radius: number;\n    constructor(center: Vec2, radius: number) {\n        this.center = center.clone();\n        this.radius = radius;\n    }\n    transform(tr: Mat4): Ellipse {\n        return new Ellipse(this.center, this.radius, this.radius).transform(tr);\n    }\n    bbox(): Rect {\n        return Rect.fromPoints(\n            this.center.sub(vec2(this.radius)),\n            this.center.add(vec2(this.radius)),\n        );\n    }\n    area(): number {\n        return this.radius * this.radius * Math.PI;\n    }\n    clone(): Circle {\n        return new Circle(this.center, this.radius);\n    }\n    collides(shape: ShapeType | Vec2): boolean {\n        return testCircleShape(this, shape);\n    }\n    contains(point: Vec2): boolean {\n        return this.collides(point);\n    }\n    raycast(origin: Vec2, direction: Vec2): RaycastResult {\n        return raycastCircle(origin, direction, this);\n    }\n    random(): Vec2 {\n        // TODO: Not uniform!!\n        return this.center.add(\n            Vec2.fromAngle(rand(360)).scale(rand(this.radius)),\n        );\n    }\n}\n\n/**\n * @group Math\n */\nexport class Ellipse {\n    center: Vec2;\n    radiusX: number;\n    radiusY: number;\n    angle: number;\n    constructor(center: Vec2, rx: number, ry: number, degrees: number = 0) {\n        this.center = center.clone();\n        this.radiusX = rx;\n        this.radiusY = ry;\n        this.angle = degrees;\n    }\n    static fromMat2(tr: Mat2): Ellipse {\n        const inv = tr.inverse;\n        const M = inv.transpose.mul(inv);\n        const [e1, e2] = M.eigenvalues;\n        const [v1, v2] = M.eigenvectors(e1, e2);\n\n        const [a, b] = [1 / Math.sqrt(e1), 1 / Math.sqrt(e2)];\n\n        // Make sure we use the semi-major axis for the rotation\n        if (a > b) {\n            return new Ellipse(\n                vec2(),\n                a,\n                b,\n                rad2deg(Math.atan2(-v1[1], v1[0])),\n            );\n        }\n        else {\n            return new Ellipse(\n                vec2(),\n                b,\n                a,\n                rad2deg(Math.atan2(-v2[1], v2[0])),\n            );\n        }\n    }\n    toMat2(): Mat2 {\n        const a = deg2rad(this.angle);\n        const c = Math.cos(a);\n        const s = Math.sin(a);\n        return new Mat2(\n            c * this.radiusX,\n            -s * this.radiusY,\n            s * this.radiusX,\n            c * this.radiusY,\n        );\n    }\n    transform(tr: Mat4): Ellipse {\n        if (this.angle == 0 && tr.getRotation() == 0) {\n            // No rotation, so we can just take the scale and translation\n            return new Ellipse(\n                tr.multVec2(this.center),\n                tr.m[0] * this.radiusX,\n                tr.m[5] * this.radiusY,\n            );\n        }\n        else {\n            // Rotation. We can't just add angles, as the scale can squeeze the\n            // ellipse and thus change the angle.\n            // Get the transformation which maps the unit circle onto the ellipse\n            let T = this.toMat2();\n            // Transform the transformation matrix with the rotation+scale matrix\n            const angle = tr.getRotation();\n            const scale = tr.getScale();\n            const M = Mat3.fromMat2(T).scale(scale.x, scale.y).rotate(angle);\n            T = M.toMat2();\n            // Return the ellipse made from the transformed unit circle\n            const ellipse = Ellipse.fromMat2(T);\n            ellipse.center = tr.multVec2(this.center);\n            return ellipse;\n        }\n    }\n    bbox(): Rect {\n        if (this.angle == 0) {\n            // No rotation, so the semi-major and semi-minor axis give the extends\n            return Rect.fromPoints(\n                this.center.sub(vec2(this.radiusX, this.radiusY)),\n                this.center.add(vec2(this.radiusX, this.radiusY)),\n            );\n        }\n        else {\n            // Rotation. We need to find the maximum x and y distance from the\n            // center of the rotated ellipse\n            const angle = deg2rad(this.angle);\n            const c = Math.cos(angle);\n            const s = Math.sin(angle);\n            const ux = this.radiusX * c;\n            const uy = this.radiusX * s;\n            const vx = this.radiusY * s;\n            const vy = this.radiusY * c;\n\n            const halfwidth = Math.sqrt(ux * ux + vx * vx);\n            const halfheight = Math.sqrt(uy * uy + vy * vy);\n\n            return Rect.fromPoints(\n                this.center.sub(vec2(halfwidth, halfheight)),\n                this.center.add(vec2(halfwidth, halfheight)),\n            );\n        }\n    }\n    area(): number {\n        return this.radiusX * this.radiusY * Math.PI;\n    }\n    clone(): Ellipse {\n        return new Ellipse(this.center, this.radiusX, this.radiusY, this.angle);\n    }\n    collides(shape: ShapeType): boolean {\n        return testEllipseShape(this, shape);\n    }\n    contains(point: Vec2): boolean {\n        // Both methods work, but the second one is faster\n        /*let T = this.toTransform()\n        point = point.sub(this.center)\n        point = T.inverse.transform(point)\n        return testCirclePoint(new Circle(vec2(), 1), point)*/\n        point = point.sub(this.center);\n        const angle = deg2rad(this.angle);\n        const c = Math.cos(angle);\n        const s = Math.sin(angle);\n        const vx = point.x * c + point.y * s;\n        const vy = -point.x * s + point.y * c;\n        return vx * vx / (this.radiusX * this.radiusX)\n                + vy * vy / (this.radiusY * this.radiusY) < 1;\n    }\n    raycast(origin: Vec2, direction: Vec2): RaycastResult {\n        return raycastEllipse(origin, direction, this);\n    }\n    random(): Vec2 {\n        return this.center;\n    }\n}\n\nfunction segmentLineIntersection(a: Vec2, b: Vec2, c: Vec2, d: Vec2) {\n    const ab = b.sub(a);\n    const cd = d.sub(c);\n    let s = ab.cross(cd);\n    if (s < 0.00001 && s > -0.00001) return null;\n    const ac = c.sub(a);\n    s = ac.cross(cd) / s;\n    if (s < 0 || s > 1) return null;\n    return a.add(ab.scale(s));\n}\n\n/**\n * @group Math\n */\nexport class Polygon {\n    pts: Vec2[];\n    constructor(pts: Vec2[]) {\n        if (pts.length < 3) {\n            throw new Error(\"Polygons should have at least 3 vertices\");\n        }\n        this.pts = pts;\n    }\n    transform(m: Mat4): Polygon {\n        return new Polygon(this.pts.map((pt) => m.multVec2(pt)));\n    }\n    bbox(): Rect {\n        const p1 = vec2(Number.MAX_VALUE);\n        const p2 = vec2(-Number.MAX_VALUE);\n        for (const pt of this.pts) {\n            p1.x = Math.min(p1.x, pt.x);\n            p2.x = Math.max(p2.x, pt.x);\n            p1.y = Math.min(p1.y, pt.y);\n            p2.y = Math.max(p2.y, pt.y);\n        }\n        return Rect.fromPoints(p1, p2);\n    }\n    area(): number {\n        let total = 0;\n        const l = this.pts.length;\n        for (let i = 0; i < l; i++) {\n            const p1 = this.pts[i];\n            const p2 = this.pts[(i + 1) % l];\n            total += p1.x * p2.y * 0.5;\n            total -= p2.x * p1.y * 0.5;\n        }\n        return Math.abs(total);\n    }\n    clone(): Polygon {\n        return new Polygon(this.pts.map((pt) => pt.clone()));\n    }\n    collides(shape: ShapeType | Vec2): boolean {\n        return testPolygonShape(this, shape);\n    }\n    contains(point: Vec2): boolean {\n        return this.collides(point);\n    }\n    raycast(origin: Vec2, direction: Vec2): RaycastResult {\n        return raycastPolygon(origin, direction, this);\n    }\n    random(): Vec2 {\n        /**\n         * TODO:\n         * - cut into triangles\n         * - choose a random triangle with probability linked to surface area\n         * - choose a random point in the triangle\n         */\n        return vec2();\n    }\n    cut(a: Vec2, b: Vec2): [Polygon | null, Polygon | null] {\n        const surfaceLine = new Line(a, b);\n        const left: Array<Vec2> = [];\n        const right: Array<Vec2> = [];\n        const ab = b.sub(a);\n        let prev = this.pts[this.pts.length - 1];\n        let ap = prev.sub(a);\n        let wasLeft = ab.cross(ap) > 0;\n        this.pts.forEach(p => {\n            ap = p.sub(a);\n            const isLeft = ab.cross(ap) > 0;\n            if (wasLeft != isLeft) {\n                // Since the points are on opposite sides of the line, we know they intersect\n                const intersection = segmentLineIntersection(prev, p, a, b);\n                left.push(intersection!);\n                right.push(intersection!);\n                wasLeft = isLeft;\n            }\n            (isLeft ? left : right).push(p);\n            prev = p;\n        });\n        return [\n            left.length ? new Polygon(left) : null,\n            right.length ? new Polygon(right) : null,\n        ];\n    }\n}\n\nexport function evaluateQuadratic(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    t: number,\n) {\n    const t2 = t * t;\n    const mt = 1 - t;\n    const mt2 = mt * mt;\n    return pt1.scale(mt2).add(pt2.scale(2 * mt * t)).add(\n        pt3.scale(t2),\n    );\n}\n\nexport function evaluateQuadraticFirstDerivative(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    t: number,\n) {\n    const mt = 1 - t;\n    return pt2.sub(pt1).scale(2 * mt).add(pt3.sub(pt2).scale(2 * t));\n}\n\nexport function evaluateQuadraticSecondDerivative(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    t: number,\n) {\n    return pt3.sub(pt2.scale(2)).add(pt1).scale(2);\n}\n\nexport function evaluateBezier(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    t: number,\n) {\n    const t2 = t * t;\n    const t3 = t2 * t;\n    const mt = 1 - t;\n    const mt2 = mt * mt;\n    const mt3 = mt2 * mt;\n    return pt1.scale(mt3).add(pt2.scale(3 * mt2 * t)).add(\n        pt3.scale(3 * mt * t2),\n    ).add(pt4.scale(t3));\n}\n\nexport function evaluateBezierFirstDerivative(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    t: number,\n) {\n    const t2 = t * t;\n    const mt = 1 - t;\n    const mt2 = mt * mt;\n    return pt2.sub(pt1).scale(3 * mt2).add(pt3.sub(pt2).scale(6 * mt * t)).add(\n        pt4.sub(pt3).scale(3 * t2),\n    );\n}\n\nexport function evaluateBezierSecondDerivative(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    t: number,\n) {\n    const mt = 1 - t;\n    return pt3.sub(pt2.scale(2)).add(pt1).scale(6 * mt).add(\n        pt4.sub(pt3.scale(2)).add(pt2).scale(6 * t),\n    );\n}\n\nexport function evaluateCatmullRom(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    t: number,\n) {\n    const A = 0.5 * (((-t + 2) * t - 1) * t);\n    const B = 0.5 * (((3 * t - 5) * t) * t + 2);\n    const C = 0.5 * (((-3 * t + 4) * t + 1) * t);\n    const D = 0.5 * (((t - 1) * t) * t);\n    return pt1.scale(A).add(pt2.scale(B)).add(pt3.scale(C)).add(pt4.scale(D));\n}\n\nexport function evaluateCatmullRomFirstDerivative(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    t: number,\n) {\n    const A = 0.5 * ((-3 * t + 4) * t - 1);\n    const B = 0.5 * ((9 * t - 10) * t);\n    const C = 0.5 * ((-9 * t + 8) * t + 1);\n    const D = 0.5 * ((3 * t - 2) * t);\n    return pt1.scale(A).add(pt2.scale(B)).add(pt3.scale(C)).add(pt4.scale(D));\n}\n\nexport function normalizedCurve(curve: (t: number) => Vec2) {\n    const curveLength = curveLengthApproximation(curve);\n    const length = curveLength(1);\n    return (s: number) => {\n        const l = s * length;\n        const t = curveLength(l, true);\n        return curve(t);\n    };\n}\n\nexport function curveLengthApproximation(\n    curve: (t: number) => Vec2,\n    entries: number = 10,\n    detail: number = 10,\n) {\n    const llut = [0];\n    const tlut = [0];\n    const dt = 1 / (entries - 1);\n    const ddt = dt / detail;\n    let length = 0;\n    let pp = curve(0);\n    let t = 0;\n    for (let e = 1; e < entries; e++) {\n        for (let d = 0; d < detail; d++) {\n            t += ddt;\n            const p = curve(t);\n            const l = p.dist(pp);\n            length += l;\n            pp = p;\n        }\n        llut[e] = length;\n        tlut[e] = t;\n    }\n    tlut[entries - 1] = 1;\n    return (t: number, inverse: boolean = false) => {\n        if (inverse) {\n            const l = t;\n            if (l <= 0) return 0;\n            if (l >= length) return 1;\n            let index = 0;\n            while (llut[index + 1] < l) index++;\n            const t1 = tlut[index];\n            const t2 = tlut[index + 1];\n            const l1 = llut[index];\n            const l2 = llut[index + 1];\n            const a = (l - l1) / (l2 - l1);\n            return t1 + (t2 - t1) * a;\n        }\n        else {\n            if (t <= 0) return 0;\n            if (t >= 1) return llut[entries - 1];\n            let index = 0;\n            while (tlut[index + 1] < t) index++;\n            const t1 = tlut[index];\n            const t2 = tlut[index + 1];\n            const l1 = llut[index];\n            const l2 = llut[index + 1];\n            const a = (t - t1) / (t2 - t1);\n            return l1 + (l2 - l1) * a;\n        }\n    };\n}\n\n/**\n * A second order function returning an evaluator for the given 1D Hermite curve\n * @param pt1 First point\n * @param m1 First control point (tangent)\n * @param m2 Second control point (tangent)\n * @param pt2 Second point\n * @returns A function which gives the value on the 1D Hermite curve at t\n */\nexport function hermite(pt1: number, m1: number, m2: number, pt2: number) {\n    const A = 2 * pt1 + m1 - 2 * pt2 + m2;\n    const B = -3 * pt1 + 3 * pt2 - 2 * m1 - m2;\n    const C = m1;\n    const D = pt1;\n\n    return (t: number) => {\n        const t2 = t * t;\n        const t3 = t2 * t;\n        return A * t3 + B * t2 + C * t + D;\n    };\n}\n\n/**\n * A second order function returning an evaluator for the given 2D Cardinal curve\n * @param pt1 Previous point\n * @param pt2 First point\n * @param pt3 Second point\n * @param pt4 Next point\n * @param tension The tension of the curve, [0..1] from round to tight.\n * @param h The hermite function or one of its derivatives.\n * @returns A function which gives the value on the 2D Cardinal curve at t\n */\nexport function cardinal(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    tension: number,\n    h = hermite,\n) {\n    const hx = h(\n        pt2.x,\n        (1 - tension) * (pt3.x - pt1.x),\n        (1 - tension) * (pt4.x - pt2.x),\n        pt3.x,\n    );\n    const hy = h(\n        pt2.y,\n        (1 - tension) * (pt3.y - pt1.y),\n        (1 - tension) * (pt4.y - pt2.y),\n        pt3.y,\n    );\n    return (t: number) => {\n        return new Vec2(hx(t), hy(t));\n    };\n}\n\n/**\n * A second order function returning an evaluator for the given 2D Catmull-Rom curve\n * @param pt1 Previous point\n * @param pt2 First point\n * @param pt3 Second point\n * @param pt4 Next point\n * @returns A function which gives the value on the 2D Catmull-Rom curve at t\n */\nexport function catmullRom(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    h = hermite,\n) {\n    // A Catmull-Rom curve is a Cardinal curve with as tension 0.5\n    return cardinal(pt1, pt2, pt3, pt4, 0.5, h);\n}\n\n/**\n * A second order function returning an evaluator for the given 2D quadratic Bezier curve\n * @param pt1 First point\n * @param pt2 First control point\n * @param pt3 Second control point\n * @param pt4 Second point\n * @returns A function which gives the value on the 2D quadratic Bezier curve at t\n */\nexport function bezier(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    h = hermite,\n) {\n    // Convert the Bezier to a Catmull-Rom curve\n    return catmullRom(\n        pt4.add(pt1.sub(pt2).scale(6)),\n        pt1,\n        pt4,\n        pt1.add(pt4.sub(pt3).scale(6)),\n        h,\n    );\n}\n\n/**\n * A second order function returning an evaluator for the given 2D Kochanek\u2013Bartels curve\n * @param pt1 Previous point\n * @param pt2 First point\n * @param pt3 Second point\n * @param pt4 Next point\n * @param tension The tension of the curve, [-1..1] from round to tight.\n * @param continuity The continuity of the curve, [-1..1] from box corners to inverted corners.\n * @param bias The bias of the curve, [-1..1] from pre-shoot to post-shoot.\n * @returns A function which gives the value on the 2D Kochanek\u2013Bartels curve at t\n */\nexport function kochanekBartels(\n    pt1: Vec2,\n    pt2: Vec2,\n    pt3: Vec2,\n    pt4: Vec2,\n    tension: number,\n    continuity: number,\n    bias: number,\n    h = hermite,\n) {\n    const hx = h(\n        pt2.x,\n        0.5 * (1 - tension) * (1 + bias) * (1 + continuity) * (pt2.x - pt1.x)\n            + 0.5 * (1 - tension) * (1 - bias) * (1 - continuity)\n                * (pt3.x - pt2.x),\n        0.5 * (1 - tension) * (1 + bias) * (1 - continuity) * (pt3.x - pt2.x)\n            + 0.5 * (1 - tension) * (1 - bias) * (1 + continuity)\n                * (pt4.x - pt3.x),\n        pt3.x,\n    );\n    const hy = h(\n        pt2.y,\n        0.5 * (1 - tension) * (1 + bias) * (1 + continuity) * (pt2.y - pt1.y)\n            + 0.5 * (1 - tension) * (1 - bias) * (1 - continuity)\n                * (pt3.y - pt2.y),\n        0.5 * (1 - tension) * (1 + bias) * (1 - continuity) * (pt3.y - pt2.y)\n            + 0.5 * (1 - tension) * (1 - bias) * (1 + continuity)\n                * (pt4.y - pt3.y),\n        pt3.y,\n    );\n    return (t: number) => {\n        return new Vec2(hx(t), hy(t));\n    };\n}\n\n/**\n * A second order function returning an evaluator for the derivative of the given 1D Hermite curve\n * @param pt1 First point\n * @param m1 First control point (tangent)\n * @param m2 Second control point (tangent)\n * @param pt2 Second point\n * @returns A function which gives the first derivative on the 1D Hermite curve at t\n */\nexport function hermiteFirstDerivative(\n    pt1: number,\n    m1: number,\n    m2: number,\n    pt2: number,\n) {\n    const A = 2 * pt1 + m1 - 2 * pt2 + m2;\n    const B = -3 * pt1 + 3 * pt2 - 2 * m1 + m2;\n    const C = m1;\n\n    return (t: number) => {\n        const t2 = t * t;\n        return 3 * A * t2 + 2 * B * t + C;\n    };\n}\n\n// True if t is between 0 and 1\nfunction inZeroOneDomain(t: number) {\n    return 0 <= t && t <= 1;\n}\n\n// True if a and b are almost equal\nfunction approximately(a: number, b: number) {\n    return Math.abs(a - b) <= Number.EPSILON;\n}\n\n// Calculates the cube root \u221B of the given number\nfunction cubeRoot(v: number) {\n    if (v < 0) {\n        return -Math.pow(-v, 1 / 3);\n    }\n    else {\n        return Math.pow(v, 1 / 3);\n    }\n}\n\n// Get all cubic roots of the given 1 dimensional bezier\nfunction getCubicRoots(pa: number, pb: number, pc: number, pd: number) {\n    let a = 3 * pa - 6 * pb + 3 * pc;\n    let b = -3 * pa + 3 * pb;\n    let c = pa;\n    let d = -pa + 3 * pb - 3 * pc + pd;\n\n    if (approximately(d, 0)) {\n        if (approximately(a, 0)) {\n            if (approximately(b, 0)) {\n                return [];\n            }\n            return [-c / b].filter(inZeroOneDomain);\n        }\n        const q = Math.sqrt(b * b - 4 * a * c);\n        const a2 = 2 * a;\n        return [(q - b) / a2, (-b - q) / a2].filter(inZeroOneDomain);\n    }\n\n    a /= d;\n    b /= d;\n    c /= d;\n\n    const p = (3 * b - a * a) / 3;\n    const p3 = p / 3;\n    const q = (2 * a * a * a - 9 * a * b + 27 * c) / 27;\n    const q2 = q / 2;\n    const discriminant = q2 * q2 + p3 * p3 * p3;\n\n    if (discriminant < 0) {\n        const mp3 = -p / 3;\n        const mp33 = mp3 * mp3 * mp3;\n        const r = Math.sqrt(mp33);\n        const t = -q / (2 * r);\n        const cosphi = t < -1 ? -1 : t > 1 ? 1 : t;\n        const phi = Math.acos(cosphi);\n        const crtr = cubeRoot(r);\n        const t1 = 2 * crtr;\n        const root1 = t1 * Math.cos(phi / 3) - a / 3;\n        const root2 = t1 * Math.cos((phi + 2 * Math.PI) / 3) - a / 3;\n        const root3 = t1 * Math.cos((phi + 4 * Math.PI) / 3) - a / 3;\n        return [root1, root2, root3].filter(inZeroOneDomain);\n    }\n\n    if (discriminant === 0) {\n        const u1 = q2 < 0 ? cubeRoot(-q2) : -cubeRoot(q2);\n        const root1 = 2 * u1 - a / 3;\n        const root2 = -u1 - a / 3;\n        return [root1, root2].filter(inZeroOneDomain);\n    }\n\n    const sd = Math.sqrt(discriminant);\n    const u1 = cubeRoot(sd - q2);\n    const v1 = cubeRoot(sd + q2);\n    const root1 = u1 - v1 - a / 3;\n    return [root1].filter(inZeroOneDomain);\n}\n\n// Returns y for the given x on the cubic bezier by first calculating the t for the given x, then calculating y from t\nfunction cubicBezierYforX(a: Vec2, b: Vec2, c: Vec2, d: Vec2, x: number) {\n    // Get t for x\n    const t = getCubicRoots(a.x - x, b.x - x, c.x - x, d.x - x);\n    if (t.length > 0) {\n        // Get y for t\n        return evaluateBezier(a, b, c, d, t[0]).y;\n    }\n    return NaN;\n}\n\nexport function easingLinear(keys: Vec2[]) {\n    if (!keys || keys.length == 0) {\n        throw new Error(\n            \"Need at least one point for easingLinear.\",\n        );\n    }\n    const len = keys.length;\n    return (x: number) => {\n        // Before start\n        if (x <= 0 || keys.length == 1 || x <= keys[0].x) {\n            return keys[0].y;\n        }\n        for (let i = 0; i < len; i++) {\n            if (keys[i].x >= x) {\n                // Linear map\n                return map(\n                    x,\n                    keys[i - 1].x,\n                    keys[i].x,\n                    keys[i - 1].y,\n                    keys[i].y,\n                );\n            }\n        }\n        // After end\n        return keys[keys.length - 1].y;\n    };\n}\n\nexport function easingCubicBezier(p1: Vec2, p2: Vec2) {\n    return (x: number) => {\n        return cubicBezierYforX(vec2(0, 0), p1, p2, vec2(1, 1), x);\n    };\n}\n\nexport type StepPosition =\n    | \"jump-start\"\n    | \"jump-end\"\n    | \"jump-none\"\n    | \"jump-both\";\n\nexport function easingSteps(\n    steps: number,\n    position: StepPosition = \"jump-end\",\n) {\n    const xdist = 1 / steps;\n    const jumpStart = position == \"jump-start\" || position == \"jump-both\";\n    const jumpEnd = position == \"jump-end\" || position == \"jump-both\";\n    const ydist = 1 / (steps + (jumpEnd ? 1 : 0));\n    const startY = jumpStart ? ydist : 0;\n    return (x: number) => {\n        const step = Math.floor(x / xdist);\n        return startY + step * ydist;\n    };\n}\n\nexport type SatResult = {\n    normal: Vec2;\n    distance: number;\n};\n\nexport function sat(p1: Polygon, p2: Polygon): SatResult | null {\n    let overlap = Number.MAX_VALUE;\n    let result: SatResult = { normal: vec2(0), distance: 0 };\n    for (const poly of [p1, p2]) {\n        for (let i = 0; i < poly.pts.length; i++) {\n            const a = poly.pts[i];\n            const b = poly.pts[(i + 1) % poly.pts.length];\n            const axisProj = b.sub(a).normal().unit();\n            let min1 = Number.MAX_VALUE;\n            let max1 = -Number.MAX_VALUE;\n            for (let j = 0; j < p1.pts.length; j++) {\n                const q = p1.pts[j].dot(axisProj);\n                min1 = Math.min(min1, q);\n                max1 = Math.max(max1, q);\n            }\n            let min2 = Number.MAX_VALUE;\n            let max2 = -Number.MAX_VALUE;\n            for (let j = 0; j < p2.pts.length; j++) {\n                const q = p2.pts[j].dot(axisProj);\n                min2 = Math.min(min2, q);\n                max2 = Math.max(max2, q);\n            }\n            const o = Math.min(max1, max2) - Math.max(min1, min2);\n            if (o < 0) {\n                return null;\n            }\n            if (o < Math.abs(overlap)) {\n                const o1 = max2 - min1;\n                const o2 = min2 - max1;\n                overlap = Math.abs(o1) < Math.abs(o2) ? o1 : o2;\n                result.normal = axisProj;\n                result.distance = overlap;\n            }\n        }\n    }\n    return result;\n}\n\n// true if the angle is oriented counter clockwise\nfunction isOrientedCcw(a: Vec2, b: Vec2, c: Vec2) {\n    // return det(b-a, c-a) >= 0\n    return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) >= 0;\n}\n\n// true if the polygon is oriented counter clockwise\nfunction isOrientedCcwPolygon(polygon: Vec2[]) {\n    let total = 0;\n    let prev: Vec2 = polygon[polygon.length - 1];\n    for (let i = 0; i < polygon.length; i++) {\n        total += (polygon[i].x - prev.x) * (polygon[i].y + prev.y);\n        prev = polygon[i];\n    }\n    return total < 0;\n}\n\n// true if a and b are on the same side of the line c->d\nfunction onSameSide(a: Vec2, b: Vec2, c: Vec2, d: Vec2) {\n    const px = d.x - c.x, py = d.y - c.y;\n    // return det(p, a-c) * det(p, b-c) >= 0\n    const l = px * (a.y - c.y) - py * (a.x - c.x);\n    const m = px * (b.y - c.y) - py * (b.x - c.x);\n    return l * m >= 0;\n}\n\n// true if p is contained in the triangle abc\nfunction pointInTriangle(p: Vec2, a: Vec2, b: Vec2, c: Vec2) {\n    return onSameSide(p, a, b, c) && onSameSide(p, b, a, c)\n        && onSameSide(p, c, a, b);\n}\n\n// true if any vertex in the list `vertices' is in the triangle abc.\nfunction someInTriangle(vertices: Vec2[], a: Vec2, b: Vec2, c: Vec2) {\n    for (const p of vertices) {\n        if (\n            (p !== a) && (p !== b) && (p !== c) && pointInTriangle(p, a, b, c)\n        ) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\n// true if the triangle is an ear, which is whether it can be cut off from the polygon without leaving a hole behind\nfunction isEar(a: Vec2, b: Vec2, c: Vec2, vertices: Vec2[]) {\n    return isOrientedCcw(a, b, c) && !someInTriangle(vertices, a, b, c);\n}\n\nexport function triangulate(pts: Vec2[]): Vec2[][] {\n    if (pts.length < 3) {\n        return [];\n    }\n    if (pts.length == 3) {\n        return [pts];\n    }\n\n    /* Create a list of indexes to the previous and next points of a given point\n    prev_idx[i] gives the index to the previous point of the point at i */\n    let nextIdx = [];\n    let prevIdx = [];\n    let idx = 0;\n    for (let i = 0; i < pts.length; i++) {\n        const lm = pts[idx];\n        const pt = pts[i];\n        if (pt.x < lm.x || (pt.x == lm.x && pt.y < lm.y)) {\n            idx = idx;\n        }\n        nextIdx[i] = i + 1;\n        prevIdx[i] = i - 1;\n    }\n    nextIdx[nextIdx.length - 1] = 0;\n    prevIdx[0] = prevIdx.length - 1;\n\n    // If the polygon is not counter clockwise, swap the lists, thus reversing the winding\n    if (!isOrientedCcwPolygon(pts)) {\n        [nextIdx, prevIdx] = [prevIdx, nextIdx];\n    }\n\n    const concaveVertices = [];\n    for (let i = 0; i < pts.length; ++i) {\n        if (!isOrientedCcw(pts[prevIdx[i]], pts[i], pts[nextIdx[i]])) {\n            concaveVertices.push(pts[i]);\n        }\n    }\n\n    const triangles = [];\n    let nVertices = pts.length;\n    let current = 1;\n    let skipped = 0;\n    let next;\n    let prev;\n    while (nVertices > 3) {\n        next = nextIdx[current];\n        prev = prevIdx[current];\n        const a = pts[prev];\n        const b = pts[current];\n        const c = pts[next];\n        if (isEar(a, b, c, concaveVertices)) {\n            triangles.push([a, b, c]);\n            nextIdx[prev] = next;\n            prevIdx[next] = prev;\n            concaveVertices.splice(concaveVertices.indexOf(b), 1);\n            --nVertices;\n            skipped = 0;\n        }\n        else if (++skipped > nVertices) {\n            return [];\n        }\n        current = next;\n    }\n    next = nextIdx[current];\n    prev = prevIdx[current];\n    triangles.push([pts[prev], pts[current], pts[next]]);\n\n    return triangles;\n}\n\nexport function isConvex(pts: Vec2[]) {\n    if (pts.length < 3) {\n        return false;\n    }\n\n    // a polygon is convex if all corners turn in the same direction\n    // turning direction can be determined using the cross-product of\n    // the forward difference vectors\n    let i = pts.length - 2;\n    let j = pts.length - 1;\n    let k = 0;\n    let p = pts[j].sub(pts[i]);\n    let q = pts[k].sub(pts[j]);\n    let winding = p.cross(q);\n\n    while (k + 1 < pts.length) {\n        i = j;\n        j = k;\n        k++;\n        p = pts[j].sub(pts[i]);\n        q = pts[k].sub(pts[j]);\n\n        if (p.cross(q) * winding < 0) {\n            return false;\n        }\n    }\n    return true;\n}\n", "// some default charsets for loading bitmap fonts\nexport const ASCII_CHARS =\n\t\" !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\";\nexport const DEF_ANCHOR = \"topleft\";\nexport const BG_GRID_SIZE = 64;\nexport const DEF_FONT = \"monospace\";\nexport const DBG_FONT = \"monospace\";\nexport const DEF_TEXT_SIZE = 36;\nexport const DEF_TEXT_CACHE_SIZE = 64;\nexport const MAX_TEXT_CACHE_SIZE = 256;\nexport const FONT_ATLAS_WIDTH = 2048;\nexport const FONT_ATLAS_HEIGHT = 2048;\nexport const SPRITE_ATLAS_WIDTH = 2048;\nexport const SPRITE_ATLAS_HEIGHT = 2048;\n// 0.1 pixel padding to texture coordinates to prevent artifact\nexport const UV_PAD = 0.1;\nexport const DEF_HASH_GRID_SIZE = 64;\nexport const DEF_FONT_FILTER = \"linear\";\nexport const LOG_MAX = 8;\nexport const LOG_TIME = 4;\nexport const VERTEX_FORMAT = [\n\t{ name: \"a_pos\", size: 2 },\n\t{ name: \"a_uv\", size: 2 },\n\t{ name: \"a_color\", size: 4 },\n];\nconst STRIDE = VERTEX_FORMAT.reduce((sum, f) => sum + f.size, 0);\nconst MAX_BATCHED_QUAD = 2048;\nexport const MAX_BATCHED_VERTS = MAX_BATCHED_QUAD * 4 * STRIDE;\nexport const MAX_BATCHED_INDICES = MAX_BATCHED_QUAD * 6;\n// vertex shader template, replace {{user}} with user vertex shader code\nexport const VERT_TEMPLATE = `\nattribute vec2 a_pos;\nattribute vec2 a_uv;\nattribute vec4 a_color;\n\nvarying vec2 v_pos;\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvec4 def_vert() {\n\treturn vec4(a_pos, 0.0, 1.0);\n}\n\n{{user}}\n\nvoid main() {\n\tvec4 pos = vert(a_pos, a_uv, a_color);\n\tv_pos = a_pos;\n\tv_uv = a_uv;\n\tv_color = a_color;\n\tgl_Position = pos;\n}\n`;\n// fragment shader template, replace {{user}} with user fragment shader code\nexport const FRAG_TEMPLATE = `\nprecision mediump float;\n\nvarying vec2 v_pos;\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nuniform sampler2D u_tex;\n\nvec4 def_frag() {\n\tvec4 texColor = texture2D(u_tex, v_uv);\n\treturn vec4((v_color.rgb * texColor.rgb), texColor.a) * v_color.a;\n}\n\n{{user}}\n\nvoid main() {\n\tgl_FragColor = frag(v_pos, v_uv, v_color, u_tex);\n\tif (gl_FragColor.a == 0.0) {\n\t\tdiscard;\n\t}\n}\n`;\n// default {{user}} vertex shader code\nexport const DEF_VERT = `\nvec4 vert(vec2 pos, vec2 uv, vec4 color) {\n\treturn def_vert();\n}\n`;\n// default {{user}} fragment shader code\nexport const DEF_FRAG = `\nvec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {\n\treturn def_frag();\n}\n`;\nexport const COMP_DESC = new Set([\"id\", \"require\"]);\nexport const COMP_EVENTS = new Set([\n\t\"add\",\n\t\"fixedUpdate\",\n\t\"update\",\n\t\"draw\",\n\t\"destroy\",\n\t\"inspect\",\n\t\"drawInspect\",\n]);\nexport const DEF_OFFSCREEN_DIS = 200;\n// maximum y velocity with body()\nexport const DEF_JUMP_FORCE = 640;\nexport const MAX_VEL = 65536;\nexport const EVENT_CANCEL_SYMBOL = Symbol.for(\"kaplay.cancel\");\n", "import { EVENT_CANCEL_SYMBOL } from \"../constants\";\n\nexport class Registry<T> extends Map<number, T> {\n    private lastID: number = 0;\n    push(v: T): number {\n        const id = this.lastID;\n        this.set(id, v);\n        this.lastID++;\n        return id;\n    }\n    pushd(v: T): () => void {\n        const id = this.push(v);\n        return () => this.delete(id);\n    }\n}\n\n/**\n * A controller for all events in KAPLAY.\n *\n * @example\n * ```js\n * // Create a new event\n * const logHi = onUpdate(() => {\n *    debug.log(\"hi\");\n * });\n *\n * // Pause the event\n * logHi.paused = true;\n *\n * // Cancel the event\n * logHi.cancel();\n *\n * ```\n * @group Events\n */\nexport class KEventController {\n    /** If the event is paused */\n    paused: boolean = false;\n    /** Cancel the event */\n    cancel: () => void;\n\n    constructor(cancel: () => void) {\n        this.cancel = cancel;\n    }\n    static join(events: KEventController[]): KEventController {\n        const ev = new KEventController(() =>\n            events.forEach((e) => e.cancel())\n        );\n        Object.defineProperty(ev, \"paused\", {\n            get: () => events[0].paused,\n            set: (p: boolean) => events.forEach((e) => e.paused = p),\n        });\n        ev.paused = false;\n        return ev;\n    }\n    static replace(oldEv: KEventController, newEv: KEventController) {\n        oldEv.cancel = () => newEv.cancel();\n        newEv.paused = oldEv.paused;\n        Object.defineProperty(oldEv, \"paused\", {\n            get: () => newEv.paused,\n            set: (p: boolean) => newEv.paused = p,\n        });\n\n        return oldEv;\n    }\n}\n\nexport class KEvent<Args extends any[] = any[]> {\n    private cancellers: WeakMap<(...args: Args) => unknown, () => void> =\n        new WeakMap();\n    private handlers: Registry<(...args: Args) => unknown> = new Registry();\n\n    add(action: (...args: Args) => unknown): KEventController {\n        function handler(...args: Args) {\n            if (ev.paused) return;\n            return action(...args);\n        }\n\n        const cancel = this.handlers.pushd(handler);\n        const ev = new KEventController(cancel);\n        this.cancellers.set(handler, cancel);\n        return ev;\n    }\n    addOnce(\n        action: (...args: (Args | PromiseLike<Args>)[]) => void,\n    ): KEventController {\n        const ev = this.add((...args) => {\n            ev.cancel();\n            action(...args);\n        });\n        return ev;\n    }\n    next(): Promise<Args> {\n        return new Promise((res) => this.addOnce(res));\n    }\n    trigger(...args: Args) {\n        this.handlers.forEach((action) => {\n            const result = action(...args);\n            let cancel;\n\n            if (\n                result === EVENT_CANCEL_SYMBOL\n                && (cancel = this.cancellers.get(action))\n            ) {\n                cancel();\n            }\n        });\n    }\n    numListeners(): number {\n        return this.handlers.size;\n    }\n    clear() {\n        this.handlers.clear();\n    }\n}\n\n// TODO: only accept one argument?\nexport class KEventHandler<EventMap extends Record<string, any[]>> {\n    private handlers: Partial<\n        {\n            [Name in keyof EventMap]: KEvent<EventMap[Name]>;\n        }\n    > = {};\n    registers: Partial<\n        {\n            [Name in keyof EventMap]: Registry<\n                (...args: EventMap[Name]) => void\n            >;\n        }\n    > = {};\n    on<Name extends keyof EventMap>(\n        name: Name,\n        action: (...args: EventMap[Name]) => void,\n    ): KEventController {\n        if (!this.handlers[name]) {\n            this.handlers[name] = new KEvent<EventMap[Name]>();\n        }\n        return this.handlers[name].add(action);\n    }\n    onOnce<Name extends keyof EventMap>(\n        name: Name,\n        action: (...args: EventMap[Name]) => void,\n    ): KEventController {\n        const ev = this.on(name, (...args) => {\n            ev.cancel();\n            action(...args);\n        });\n        return ev;\n    }\n    next<Name extends keyof EventMap>(name: Name): Promise<unknown> {\n        return new Promise((res) => {\n            // TODO: can only pass 1 val to resolve()\n            this.onOnce(name, (...args: EventMap[Name]) => res(args[0]));\n        });\n    }\n    trigger<Name extends keyof EventMap>(name: Name, ...args: EventMap[Name]) {\n        if (this.handlers[name]) {\n            this.handlers[name].trigger(...args);\n        }\n    }\n    remove<Name extends keyof EventMap>(name: Name) {\n        delete this.handlers[name];\n    }\n    clear() {\n        this.handlers = {};\n    }\n    numListeners<Name extends keyof EventMap>(name: Name): number {\n        return this.handlers[name]?.numListeners() ?? 0;\n    }\n}\n", "import { Color } from \"../math/color\";\nimport { Vec2 } from \"../math/math\";\n\nexport const arrayIsColor = (arr: unknown[]): arr is Color[] => {\n    return arr[0] instanceof Color;\n};\n\nexport const arrayIsVec2 = (arr: unknown[]): arr is Vec2[] => {\n    return arr[0] instanceof Vec2;\n};\n\nexport const arrayIsNumber = (arr: unknown[]): arr is number[] => {\n    return typeof arr[0] === \"number\";\n};\n\nexport function isClass(obj: any): obj is Function {\n    return obj?.prototype\n        && Object.getOwnPropertyDescriptor(obj.prototype, \"constructor\")\n            !== undefined;\n}\n", "export class BinaryHeap<T> {\n    _items: T[];\n    _compareFn: (a: T, b: T) => boolean;\n\n    /**\n     * Creates a binary heap with the given compare function\n     * Not passing a compare function will give a min heap\n     */\n    constructor(compareFn = (a: T, b: T) => a < b) {\n        this._compareFn = compareFn;\n        this._items = [];\n    }\n\n    /**\n     * Insert an item into the binary heap\n     */\n    insert(item: T) {\n        this._items.push(item);\n        this.moveUp(this._items.length - 1);\n    }\n\n    /**\n     * Remove the smallest item from the binary heap in case of a min heap\n     * or the greatest item from the binary heap in case of a max heap\n     */\n    remove() {\n        if (this._items.length === 0) {\n            return null;\n        }\n        const item = this._items[0];\n        const lastItem = this._items.pop();\n        if (this._items.length !== 0) {\n            this._items[0] = lastItem as T;\n            this.moveDown(0);\n        }\n        return item;\n    }\n\n    /**\n     * Remove all items\n     */\n    clear() {\n        this._items.splice(0, this._items.length);\n    }\n\n    moveUp(pos: number) {\n        while (pos > 0) {\n            const parent = Math.floor((pos - 1) / 2);\n            if (!this._compareFn(this._items[pos], this._items[parent])) {\n                if (this._items[pos] >= this._items[parent]) {\n                    break;\n                }\n            }\n            this.swap(pos, parent);\n            pos = parent;\n        }\n    }\n\n    moveDown(pos: number) {\n        while (pos < Math.floor(this._items.length / 2)) {\n            let child = 2 * pos + 1;\n            if (\n                child < this._items.length - 1\n                && !this._compareFn(this._items[child], this._items[child + 1])\n            ) {\n                ++child;\n            }\n            if (this._compareFn(this._items[pos], this._items[child])) {\n                break;\n            }\n            this.swap(pos, child);\n            pos = child;\n        }\n    }\n\n    swap(index1: number, index2: number) {\n        [this._items[index1], this._items[index2]] = [\n            this._items[index2],\n            this._items[index1],\n        ];\n    }\n\n    /**\n     * Returns the amount of items\n     */\n    get length() {\n        return this._items.length;\n    }\n}\n", "export function base64ToArrayBuffer(base64: string): ArrayBuffer {\n    const binstr = window.atob(base64);\n    const len = binstr.length;\n    const bytes = new Uint8Array(len);\n    for (let i = 0; i < len; i++) {\n        bytes[i] = binstr.charCodeAt(i);\n    }\n    return bytes.buffer;\n}\n\nexport function dataURLToArrayBuffer(url: string): ArrayBuffer {\n    return base64ToArrayBuffer(url.split(\",\")[1]);\n}\n\nexport function download(filename: string, url: string) {\n    const a = document.createElement(\"a\");\n    a.href = url;\n    a.download = filename;\n    a.click();\n}\n\nexport function downloadText(filename: string, text: string) {\n    download(filename, \"data:text/plain;charset=utf-8,\" + text);\n}\n\nexport function downloadJSON(filename: string, data: any) {\n    downloadText(filename, JSON.stringify(data));\n}\n\nexport function downloadBlob(filename: string, blob: Blob) {\n    const url = URL.createObjectURL(blob);\n    download(filename, url);\n    URL.revokeObjectURL(url);\n}\n\nexport const isDataURL = (str: string) => str.match(/^data:\\w+\\/\\w+;base64,.+/);\nexport const getFileExt = (p: string) => p.split(\".\").pop();\nexport const getFileName = (p: string) => p.split(\".\").slice(0, -1).join(\".\");\n", "export function deepEq(o1: any, o2: any): boolean {\n    if (o1 === o2) {\n        return true;\n    }\n    const t1 = typeof o1;\n    const t2 = typeof o2;\n    if (t1 !== t2) {\n        return false;\n    }\n    if (t1 === \"object\" && t2 === \"object\" && o1 !== null && o2 !== null) {\n        if (Array.isArray(o1) !== Array.isArray(o2)) {\n            return false;\n        }\n        const k1 = Object.keys(o1);\n        const k2 = Object.keys(o2);\n        if (k1.length !== k2.length) {\n            return false;\n        }\n        for (const k of k1) {\n            const v1 = o1[k];\n            const v2 = o2[k];\n            if (!deepEq(v1, v2)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    return false;\n}\n", "const warned = new Set();\n\nexport const getErrorMessage = (error: unknown) =>\n    (error instanceof Error) ? error.message : String(error);\n\nexport function deprecate(\n    oldName: string,\n    newName: string,\n    newFunc: (...args: unknown[]) => any,\n) {\n    return (...args: unknown[]) => {\n        deprecateMsg(oldName, newName);\n        return newFunc(...args);\n    };\n}\n\nexport function warn(msg: string) {\n    if (!warned.has(msg)) {\n        warned.add(msg);\n        console.warn(msg);\n    }\n}\n\nexport function deprecateMsg(oldName: string, newName: string) {\n    warn(`${oldName} is deprecated. Use ${newName} instead.`);\n}\n", "export function toFixed(n: number, f: number) {\n    return Number(n.toFixed(f));\n}\n", "type Func = (...args: any[]) => any;\n\nexport function overload2<A extends Func, B extends Func>(\n    fn1: A,\n    fn2: B,\n): A & B {\n    return ((...args) => {\n        const al = args.length;\n        if (al === fn1.length) return fn1(...args);\n        if (al === fn2.length) return fn2(...args);\n    }) as A & B;\n}\n\nexport function overload3<\n    A extends Func,\n    B extends Func,\n    C extends Func,\n>(fn1: A, fn2: B, fn3: C): A & B & C {\n    return ((...args) => {\n        const al = args.length;\n        if (al === fn1.length) return fn1(...args);\n        if (al === fn2.length) return fn2(...args);\n        if (al === fn3.length) return fn3(...args);\n    }) as A & B & C;\n}\n\nexport function overload4<\n    A extends Func,\n    B extends Func,\n    C extends Func,\n    D extends Func,\n>(fn1: A, fn2: B, fn3: C, fn4: D): A & B & C & D {\n    return ((...args) => {\n        const al = args.length;\n        if (al === fn1.length) return fn1(...args);\n        if (al === fn2.length) return fn2(...args);\n        if (al === fn3.length) return fn3(...args);\n        if (al === fn4.length) return fn4(...args);\n    }) as A & B & C & D;\n}\n", "const enum EnumRunesCode {\n    HIGH_SURROGATE_START = 0xd800,\n    HIGH_SURROGATE_END = 0xdbff,\n\n    LOW_SURROGATE_START = 0xdc00,\n\n    REGIONAL_INDICATOR_START = 0x1f1e6,\n    REGIONAL_INDICATOR_END = 0x1f1ff,\n\n    FITZPATRICK_MODIFIER_START = 0x1f3fb,\n    FITZPATRICK_MODIFIER_END = 0x1f3ff,\n\n    VARIATION_MODIFIER_START = 0xfe00,\n    VARIATION_MODIFIER_END = 0xfe0f,\n\n    DIACRITICAL_MARKS_START = 0x20d0,\n    DIACRITICAL_MARKS_END = 0x20ff,\n\n    SUBDIVISION_INDICATOR_START = 0x1f3f4,\n    TAGS_START = 0xe0000,\n    TAGS_END = 0xe007f,\n\n    ZWJ = 0x200d,\n}\n\nconst GRAPHEMES = Object.freeze([\n    0x0308, // ( \u25CC\u0308 ) COMBINING DIAERESIS\n    0x0937, // ( \u0937 ) DEVANAGARI LETTER SSA\n    0x093F, // ( \u093F ) DEVANAGARI VOWEL SIGN I\n    0x0BA8, // ( \u0BA8 ) TAMIL LETTER NA\n    0x0BBF, // ( \u0BBF ) TAMIL VOWEL SIGN I\n    0x0BCD, // ( \u25CC\u0BCD) TAMIL SIGN VIRAMA\n    0x0E31, // ( \u25CC\u0E31 ) THAI CHARACTER MAI HAN-AKAT\n    0x0E33, // ( \u0E33 ) THAI CHARACTER SARA AM\n    0x0E40, // ( \u0E40 ) THAI CHARACTER SARA E\n    0x0E49, // ( \u0E40 ) THAI CHARACTER MAI THO\n    0x1100, // ( \u1100 ) HANGUL CHOSEONG KIYEOK\n    0x1161, // ( \u1161 ) HANGUL JUNGSEONG A\n    0x11A8, // ( \u11A8 ) HANGUL JONGSEONG KIYEOK\n]);\n\nenum EnumCodeUnits {\n    unit_1 = 1,\n    unit_2 = 2,\n    unit_4 = 4,\n}\n\nexport function runes(string: string): string[] {\n    if (typeof string !== \"string\") {\n        throw new TypeError(\"string cannot be undefined or null\");\n    }\n    const result: string[] = [];\n    let i = 0;\n    let increment = 0;\n    while (i < string.length) {\n        increment += nextUnits(i + increment, string);\n        if (isGrapheme(string[i + increment])) {\n            increment++;\n        }\n        if (isVariationSelector(string[i + increment])) {\n            increment++;\n        }\n        if (isDiacriticalMark(string[i + increment])) {\n            increment++;\n        }\n        if (isZeroWidthJoiner(string[i + increment])) {\n            increment++;\n            continue;\n        }\n        result.push(string.substring(i, i + increment));\n        i += increment;\n        increment = 0;\n    }\n    return result;\n}\n\n// Decide how many code units make up the current character.\n// BMP characters: 1 code unit\n// Non-BMP characters (represented by surrogate pairs): 2 code units\n// Emoji with skin-tone modifiers: 4 code units (2 code points)\n// Country flags: 4 code units (2 code points)\n// Variations: 2 code units\n// Subdivision flags: 14 code units (7 code points)\nfunction nextUnits(i: number, string: string) {\n    const current = string[i];\n    // If we don't have a value that is part of a surrogate pair, or we're at\n    // the end, only take the value at i\n    if (!isFirstOfSurrogatePair(current) || i === string.length - 1) {\n        return EnumCodeUnits.unit_1;\n    }\n\n    const currentPair = current + string[i + 1];\n    const nextPair = string.substring(i + 2, i + 5);\n\n    // Country flags are comprised of two regional indicator symbols,\n    // each represented by a surrogate pair.\n    // See http://emojipedia.org/flags/\n    // If both pairs are regional indicator symbols, take 4\n    if (isRegionalIndicator(currentPair) && isRegionalIndicator(nextPair)) {\n        return EnumCodeUnits.unit_4;\n    }\n\n    // https://unicode.org/emoji/charts/full-emoji-list.html#subdivision-flag\n    // See https://emojipedia.org/emoji-tag-sequence/\n    // If nextPair is in Tags(https://en.wikipedia.org/wiki/Tags_(Unicode_block)),\n    // then find next closest U+E007F(CANCEL TAG)\n    if (\n        isSubdivisionFlag(currentPair)\n        && isSupplementarySpecialpurposePlane(nextPair)\n    ) {\n        return string.slice(i).indexOf(\n            String.fromCodePoint(EnumRunesCode.TAGS_END),\n        ) + 2;\n    }\n\n    // If the next pair make a Fitzpatrick skin tone\n    // modifier, take 4\n    // See http://emojipedia.org/modifiers/\n    // Technically, only some code points are meant to be\n    // combined with the skin tone modifiers. This function\n    // does not check the current pair to see if it is\n    // one of them.\n    if (isFitzpatrickModifier(nextPair)) {\n        return EnumCodeUnits.unit_4;\n    }\n    return EnumCodeUnits.unit_2;\n}\n\nfunction isFirstOfSurrogatePair(string: string) {\n    return string\n        && betweenInclusive(\n            string[0].charCodeAt(0),\n            EnumRunesCode.HIGH_SURROGATE_START,\n            EnumRunesCode.HIGH_SURROGATE_END,\n        );\n}\n\nfunction isRegionalIndicator(string: string) {\n    return betweenInclusive(\n        codePointFromSurrogatePair(string),\n        EnumRunesCode.REGIONAL_INDICATOR_START,\n        EnumRunesCode.REGIONAL_INDICATOR_END,\n    );\n}\n\nfunction isSubdivisionFlag(string: string) {\n    return betweenInclusive(\n        codePointFromSurrogatePair(string),\n        EnumRunesCode.SUBDIVISION_INDICATOR_START,\n        EnumRunesCode.SUBDIVISION_INDICATOR_START,\n    );\n}\n\nfunction isFitzpatrickModifier(string: string) {\n    return betweenInclusive(\n        codePointFromSurrogatePair(string),\n        EnumRunesCode.FITZPATRICK_MODIFIER_START,\n        EnumRunesCode.FITZPATRICK_MODIFIER_END,\n    );\n}\n\nfunction isVariationSelector(string: string) {\n    return typeof string === \"string\"\n        && betweenInclusive(\n            string.charCodeAt(0),\n            EnumRunesCode.VARIATION_MODIFIER_START,\n            EnumRunesCode.VARIATION_MODIFIER_END,\n        );\n}\n\nfunction isDiacriticalMark(string: string) {\n    return typeof string === \"string\"\n        && betweenInclusive(\n            string.charCodeAt(0),\n            EnumRunesCode.DIACRITICAL_MARKS_START,\n            EnumRunesCode.DIACRITICAL_MARKS_END,\n        );\n}\n\nfunction isSupplementarySpecialpurposePlane(string: string) {\n    const codePoint = string.codePointAt(0);\n    return (typeof string === \"string\" && typeof codePoint === \"number\"\n        && betweenInclusive(\n            codePoint,\n            EnumRunesCode.TAGS_START,\n            EnumRunesCode.TAGS_END,\n        ));\n}\n\nfunction isGrapheme(string: string) {\n    return typeof string === \"string\"\n        && GRAPHEMES.includes(string.charCodeAt(0));\n}\n\nfunction isZeroWidthJoiner(string: string) {\n    return typeof string === \"string\"\n        && string.charCodeAt(0) === EnumRunesCode.ZWJ;\n}\n\nfunction codePointFromSurrogatePair(pair: string) {\n    const highOffset = pair.charCodeAt(0) - EnumRunesCode.HIGH_SURROGATE_START;\n    const lowOffset = pair.charCodeAt(1) - EnumRunesCode.LOW_SURROGATE_START;\n    return (highOffset << 10) + lowOffset + 0x10000;\n}\n\nfunction betweenInclusive(value: number, lower: number, upper: number) {\n    return value >= lower && value <= upper;\n}\n\nexport function substring(string: string, start?: number, width?: number) {\n    const chars = runes(string);\n    if (start === undefined) {\n        return string;\n    }\n    if (start >= chars.length) {\n        return \"\";\n    }\n    const rest = chars.length - start;\n    const stringWidth = width === undefined ? rest : width;\n    let endIndex: number | null = start + stringWidth;\n\n    if (endIndex > (start + rest)) {\n        endIndex = null;\n    }\n\n    if (endIndex === null) {\n        return chars.slice(start).join(\"\");\n    }\n\n    return chars.slice(start, endIndex).join(\"\");\n}\n", "export const isEqOrIncludes = <T>(listOrSmt: T | T[], el: unknown): boolean => {\n    if (Array.isArray(listOrSmt)) {\n        return (listOrSmt as any[])?.includes(el);\n    }\n\n    return listOrSmt === el;\n};\n\nexport const setHasOrIncludes = <K>(\n    set: Set<K>,\n    key: K | K[],\n): boolean => {\n    if (Array.isArray(key)) {\n        return key.some((k) => set.has(k));\n    }\n\n    return set.has(key);\n};\n\nexport const mapAddOrPush = <K, V>(\n    map: Map<K, V[]>,\n    key: K,\n    value: V,\n): void => {\n    if (map.has(key)) {\n        map.get(key)?.push(value);\n    }\n    else {\n        map.set(key, [value]);\n    }\n};\n", "export const uid = (() => {\n    let id = 0;\n    return () => id++;\n})();\n", "{\n  \"Joy-Con L+R (STANDARD GAMEPAD Vendor: 057e Product: 200e)\": {\n    \"buttons\": {\n      \"0\": \"south\",\n      \"1\": \"east\",\n      \"2\": \"west\",\n      \"3\": \"north\",\n      \"4\": \"lshoulder\",\n      \"5\": \"rshoulder\",\n      \"6\": \"ltrigger\",\n      \"7\": \"rtrigger\",\n      \"8\": \"select\",\n      \"9\": \"start\",\n      \"10\": \"lstick\",\n      \"11\": \"rstick\",\n      \"12\": \"dpad-up\",\n      \"13\": \"dpad-down\",\n      \"14\": \"dpad-left\",\n      \"15\": \"dpad-right\",\n      \"16\": \"home\",\n      \"17\": \"capture\"\n    },\n    \"sticks\": {\n      \"left\": { \"x\": 0, \"y\": 1 },\n      \"right\": { \"x\": 2, \"y\": 3 }\n    }\n  },\n  \"Joy-Con (L) (STANDARD GAMEPAD Vendor: 057e Product: 2006)\": {\n    \"buttons\": {\n      \"0\": \"south\",\n      \"1\": \"east\",\n      \"2\": \"west\",\n      \"3\": \"north\",\n      \"4\": \"lshoulder\",\n      \"5\": \"rshoulder\",\n      \"9\": \"select\",\n      \"10\": \"lstick\",\n      \"16\": \"start\"\n    },\n    \"sticks\": {\n      \"left\": { \"x\": 0, \"y\": 1 }\n    }\n  },\n  \"Joy-Con (R) (STANDARD GAMEPAD Vendor: 057e Product: 2007)\": {\n    \"buttons\": {\n      \"0\": \"south\",\n      \"1\": \"east\",\n      \"2\": \"west\",\n      \"3\": \"north\",\n      \"4\": \"lshoulder\",\n      \"5\": \"rshoulder\",\n      \"9\": \"start\",\n      \"10\": \"lstick\",\n      \"16\": \"select\"\n    },\n    \"sticks\": {\n      \"left\": { \"x\": 0, \"y\": 1 }\n    }\n  },\n  \"Pro Controller (STANDARD GAMEPAD Vendor: 057e Product: 2009)\": {\n    \"buttons\": {\n      \"0\": \"south\",\n      \"1\": \"east\",\n      \"2\": \"west\",\n      \"3\": \"north\",\n      \"4\": \"lshoulder\",\n      \"5\": \"rshoulder\",\n      \"6\": \"ltrigger\",\n      \"7\": \"rtrigger\",\n      \"8\": \"select\",\n      \"9\": \"start\",\n      \"10\": \"lstick\",\n      \"11\": \"rstick\",\n      \"12\": \"dpad-up\",\n      \"13\": \"dpad-down\",\n      \"14\": \"dpad-left\",\n      \"15\": \"dpad-right\",\n      \"16\": \"home\",\n      \"17\": \"capture\"\n    },\n    \"sticks\": {\n      \"left\": { \"x\": 0, \"y\": 1 },\n      \"right\": { \"x\": 2, \"y\": 3 }\n    }\n  },\n  \"default\": {\n    \"buttons\": {\n      \"0\": \"south\",\n      \"1\": \"east\",\n      \"2\": \"west\",\n      \"3\": \"north\",\n      \"4\": \"lshoulder\",\n      \"5\": \"rshoulder\",\n      \"6\": \"ltrigger\",\n      \"7\": \"rtrigger\",\n      \"8\": \"select\",\n      \"9\": \"start\",\n      \"10\": \"lstick\",\n      \"11\": \"rstick\",\n      \"12\": \"dpad-up\",\n      \"13\": \"dpad-down\",\n      \"14\": \"dpad-left\",\n      \"15\": \"dpad-right\",\n      \"16\": \"home\"\n    },\n    \"sticks\": {\n      \"left\": { \"x\": 0, \"y\": 1 },\n      \"right\": { \"x\": 2, \"y\": 3 }\n    }\n  }\n}\n", "import { _k } from \"../kaplay\";\nimport { Vec2 } from \"../math/math.js\";\n\n/*\nThe viewport is where the game is rendered. There's various concepts for\nrendering the viewport\n\n- Canvas size: The CSS size of the canvas element\n\n- Buffer size: The quantity of pixels that are rendered by WebGL. It varies\ndepending of the\n\n- Desired Size: The desired size is the size the user defines for keeping an\naspect ratio\n\n- Viewport size: The final rendered size\n\nWe update the canvas before run this, you should check initEvents.ts\nin onResize method.\n*/\n\nexport function updateViewport() {\n    const pixelDensity = _k.globalOpt.pixelDensity ?? 1;\n    const desiredWidth = _k.globalOpt.width;\n    const desiredHeight = _k.globalOpt.height;\n    const drawingBufferWidth = _k.gfx.ggl.gl.drawingBufferWidth;\n    const drawingBufferHeight = _k.gfx.ggl.gl.drawingBufferHeight;\n    const canvasWidth = drawingBufferWidth / pixelDensity;\n    const canvasHeight = drawingBufferHeight / pixelDensity;\n\n    // console.log(\"[vwp] buffer size\", drawingBufferWidth, drawingBufferHeight);\n    // console.log(\"[vwp] desired size\", desiredWidth, desiredHeight);\n    // console.log(\"[vwp] canvas size\", canvasWidth, canvasHeight);\n\n    let x = 0;\n    let y = 0;\n    let viewportWidth = canvasWidth;\n    let viewportHeight = canvasHeight;\n\n    if (_k.globalOpt.letterbox) {\n        if (!desiredWidth || !desiredHeight) {\n            throw new Error(\n                \"Letterboxing requires width and height defined.\",\n            );\n        }\n\n        const canvasAspectRatio = canvasWidth / canvasHeight;\n        const disairedAspectRatio = desiredWidth / desiredHeight;\n\n        // In letterbox, we scale one width/height for keep aspect ratio,\n        // depending of what side is larger\n        if (canvasAspectRatio > disairedAspectRatio) {\n            const scaledWidth = canvasHeight * disairedAspectRatio;\n\n            x = (canvasWidth - scaledWidth) / 2;\n            viewportWidth = scaledWidth;\n        }\n        else {\n            const scaledHeight = canvasWidth / disairedAspectRatio;\n\n            viewportHeight = scaledHeight;\n            y = (canvasHeight - scaledHeight) / 2;\n        }\n    }\n\n    if (_k.globalOpt.stretch) {\n        if (!_k.globalOpt.width || !_k.globalOpt.height) {\n            throw new Error(\n                \"Stretching requires width and height defined.\",\n            );\n        }\n    }\n\n    _k.gfx.viewport = {\n        x: x,\n        y: y,\n        width: viewportWidth,\n        height: viewportHeight,\n        scale: (_k.gfx.viewport.width + _k.gfx.viewport.height)\n            / (_k.gfx.width + _k.gfx.height),\n    };\n}\n\nexport function viewportToCanvas(pt: Vec2) {\n    return new Vec2(\n        pt.x * _k.gfx.viewport.width / _k.gfx.width,\n        pt.y * _k.gfx.viewport.height / _k.gfx.height,\n    );\n}\n\nexport function canvasToViewport(pt: Vec2) {\n    return new Vec2(\n        (pt.x - _k.gfx.viewport.x) * _k.gfx.width / _k.gfx.viewport.width,\n        (pt.y - _k.gfx.viewport.y) * _k.gfx.height / _k.gfx.viewport.height,\n    );\n}\n", "import type { KAPLAYCtx, Key, KGamepadButton, MouseButton } from \"../types\";\nimport { mapAddOrPush } from \"../utils\";\nimport { appState } from \"./app\";\n\n/**\n * A button binding.\n *\n * @group Button Bindings\n */\nexport type ButtonBinding = {\n    keyboard?: Key | Key[];\n    keyboardCode?: string | string[];\n    gamepad?: KGamepadButton | KGamepadButton[];\n    mouse?: MouseButton | MouseButton[];\n};\n\n/**\n * A buttons definition for an action (jump, walk-left, run).\n *\n * @group Button Bindings\n */\nexport type ButtonsDef = Record<string, ButtonBinding>;\n\n/**\n * A button binding device\n *\n * @group Button Bindings\n */\nexport type ButtonBindingDevice = \"keyboard\" | \"gamepad\" | \"mouse\";\n\nexport const getLastInputDeviceType: KAPLAYCtx[\"getLastInputDeviceType\"] =\n    () => {\n        return appState.lastInputDevice;\n    };\n\n// pass the user `buttons` definition to different keymaps\nexport const parseButtonBindings = () => {\n    const btns = appState.buttons;\n\n    for (const b in btns) {\n        const keyboardBtns = btns[b].keyboard && [btns[b].keyboard].flat();\n        const keyboardCodes = btns[b].keyboardCode\n            && [btns[b].keyboardCode].flat();\n        const gamepadBtns = btns[b].gamepad && [btns[b].gamepad].flat();\n        const mouseBtns = btns[b].mouse && [btns[b].mouse].flat();\n\n        if (keyboardBtns) {\n            keyboardBtns.forEach((k) => {\n                mapAddOrPush(appState.buttonsByKey, k, b);\n            });\n        }\n\n        if (keyboardCodes) {\n            keyboardCodes.forEach((k) => {\n                mapAddOrPush(appState.buttonsByKeyCode, k, b);\n            });\n        }\n\n        if (gamepadBtns) {\n            gamepadBtns.forEach((g) => {\n                mapAddOrPush(appState.buttonsByGamepad, g, b);\n            });\n        }\n\n        if (mouseBtns) {\n            mouseBtns.forEach((m) => {\n                mapAddOrPush(appState.buttonsByMouse, m, b);\n            });\n        }\n    }\n};\n", "// everything related to canvas, game loop and input\n\nimport type {\n    Cursor,\n    GamepadDef,\n    GamepadStick,\n    Key,\n    KGamepad,\n    KGamepadButton,\n    MouseButton,\n} from \"../types\";\n\nimport { map, Vec2, vec2 } from \"../math/math\";\n\nimport {\n    isEqOrIncludes,\n    KEventController,\n    KEventHandler,\n    overload2,\n    setHasOrIncludes,\n} from \"../utils\";\n\nimport GAMEPAD_MAP from \"../data/gamepad.json\" assert { type: \"json\" };\nimport type { AppEventMap } from \"../game\";\nimport { canvasToViewport } from \"../gfx/viewport.js\";\nimport {\n    type ButtonBinding,\n    type ButtonsDef,\n    getLastInputDeviceType,\n    parseButtonBindings,\n} from \"./inputBindings\";\n\nexport class ButtonState<T = string> {\n    pressed: Set<T> = new Set([]);\n    pressedRepeat: Set<T> = new Set([]);\n    released: Set<T> = new Set([]);\n    down: Set<T> = new Set([]);\n    update() {\n        this.pressed.clear();\n        this.released.clear();\n        this.pressedRepeat.clear();\n    }\n    press(btn: T) {\n        this.pressed.add(btn);\n        this.pressedRepeat.add(btn);\n        this.down.add(btn);\n    }\n    pressRepeat(btn: T) {\n        this.pressedRepeat.add(btn);\n    }\n    release(btn: T) {\n        this.down.delete(btn);\n        this.pressed.delete(btn);\n        this.released.add(btn);\n    }\n}\n\nclass GamepadState {\n    buttonState: ButtonState<KGamepadButton> = new ButtonState();\n    stickState: Map<GamepadStick, Vec2> = new Map();\n}\n\nclass FPSCounter {\n    private dts: number[] = [];\n    private timer: number = 0;\n    fps: number = 0;\n    tick(dt: number) {\n        this.dts.push(dt);\n        this.timer += dt;\n        if (this.timer >= 1) {\n            this.timer = 0;\n            this.fps = Math.round(\n                1 / (this.dts.reduce((a, b) => a + b) / this.dts.length),\n            );\n            this.dts = [];\n        }\n    }\n}\n\nexport type App = ReturnType<typeof initApp>;\nexport type AppState = ReturnType<typeof initAppState>;\n\nexport let appState: AppState;\n\nconst GP_MAP = GAMEPAD_MAP as Record<string, GamepadDef>;\n\nexport const initAppState = (opt: {\n    canvas: HTMLCanvasElement;\n    touchToMouse?: boolean;\n    gamepads?: Record<string, GamepadDef>;\n    pixelDensity?: number;\n    maxFPS?: number;\n    buttons?: ButtonsDef;\n}) => {\n    const buttons = opt.buttons ?? {};\n\n    return {\n        canvas: opt.canvas,\n        buttons: buttons,\n        buttonsByKey: new Map<Key, string[]>(),\n        buttonsByMouse: new Map<MouseButton, string[]>(),\n        buttonsByGamepad: new Map<KGamepadButton, string[]>(),\n        buttonsByKeyCode: new Map<string, string[]>(),\n        loopID: null as null | number,\n        stopped: false,\n        dt: 0,\n        fixedDt: 1 / 50,\n        restDt: 0,\n        time: 0,\n        realTime: 0,\n        fpsCounter: new FPSCounter(),\n        timeScale: 1,\n        skipTime: false,\n        isHidden: false,\n        numFrames: 0,\n        mousePos: new Vec2(0),\n        mouseDeltaPos: new Vec2(0),\n        keyState: new ButtonState<Key>(),\n        mouseState: new ButtonState<MouseButton>(),\n        mergedGamepadState: new GamepadState(),\n        gamepadStates: new Map<number, GamepadState>(),\n        lastInputDevice: null as \"mouse\" | \"keyboard\" | \"gamepad\" | null,\n        // unified input state\n        buttonState: new ButtonState<string>(),\n        gamepads: [] as KGamepad[],\n        charInputted: [] as string[],\n        isMouseMoved: false,\n        lastWidth: opt.canvas.offsetWidth,\n        lastHeight: opt.canvas.offsetHeight,\n        events: new KEventHandler<AppEventMap>(),\n    };\n};\n\nexport const initApp = (opt: {\n    canvas: HTMLCanvasElement;\n    touchToMouse?: boolean;\n    gamepads?: Record<string, GamepadDef>;\n    pixelDensity?: number;\n    maxFPS?: number;\n    buttons?: ButtonsDef;\n}) => {\n    if (!opt.canvas) {\n        throw new Error(\"Please provide a canvas\");\n    }\n\n    const state = initAppState(opt);\n    appState = state;\n    parseButtonBindings();\n\n    function dt() {\n        return state.dt * state.timeScale;\n    }\n\n    function fixedDt() {\n        return state.fixedDt * state.timeScale;\n    }\n\n    function restDt() {\n        return state.restDt * state.timeScale;\n    }\n\n    function isHidden() {\n        return state.isHidden;\n    }\n\n    function time() {\n        return state.time;\n    }\n\n    function fps() {\n        return state.fpsCounter.fps;\n    }\n\n    function numFrames() {\n        return state.numFrames;\n    }\n\n    function screenshot(): string {\n        return state.canvas.toDataURL();\n    }\n\n    function setCursor(c: Cursor): void {\n        state.canvas.style.cursor = c;\n    }\n\n    function getCursor(): Cursor {\n        return state.canvas.style.cursor;\n    }\n\n    function setCursorLocked(b: boolean): void {\n        if (b) {\n            try {\n                const res = state.canvas\n                    .requestPointerLock() as unknown as Promise<void>;\n                if (res?.catch) {\n                    res.catch((e) => console.error(e));\n                }\n            } catch (e) {\n                console.error(e);\n            }\n        }\n        else {\n            document.exitPointerLock();\n        }\n    }\n\n    function isCursorLocked(): boolean {\n        return !!document.pointerLockElement;\n    }\n\n    // wrappers around full screen functions to work across browsers\n    function enterFullscreen(el: HTMLElement) {\n        if (el.requestFullscreen) el.requestFullscreen();\n        // @ts-ignore\n        else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();\n    }\n\n    function exitFullscreen() {\n        if (document.exitFullscreen) document.exitFullscreen();\n        // @ts-ignore\n        else if (document.webkitExitFullScreen) document.webkitExitFullScreen();\n    }\n\n    function setFullscreen(f: boolean = true) {\n        if (f) {\n            enterFullscreen(state.canvas);\n        }\n        else {\n            exitFullscreen();\n        }\n    }\n\n    function isFullscreen(): boolean {\n        return document.fullscreenElement === state.canvas\n            // @ts-ignore\n            || document.webkitFullscreenElement === state.canvas;\n    }\n\n    function quit() {\n        state.stopped = true;\n        const ce = Object.entries(canvasEvents);\n        const de = Object.entries(docEvents);\n        const we = Object.entries(winEvents);\n        type EL = EventListenerOrEventListenerObject;\n        for (const [name, val] of ce) {\n            state.canvas.removeEventListener(name, val as EL);\n        }\n        for (const [name, val] of de) {\n            document.removeEventListener(name, val as EL);\n        }\n        for (const [name, val] of we) {\n            window.removeEventListener(name, val as EL);\n        }\n        resizeObserver.disconnect();\n    }\n\n    function run(\n        fixedUpdate: () => void,\n        update: (processInput: () => void, resetInput: () => void) => void,\n    ) {\n        if (state.loopID !== null) {\n            cancelAnimationFrame(state.loopID);\n        }\n\n        let fixedAccumulatedDt = 0;\n        let accumulatedDt = 0;\n\n        const frame = (t: number) => {\n            if (state.stopped) return;\n\n            // TODO: allow background actions?\n            if (document.visibilityState !== \"visible\") {\n                state.loopID = requestAnimationFrame(frame);\n                return;\n            }\n\n            const loopTime = t / 1000;\n            const realDt = Math.min(loopTime - state.realTime, 0.25);\n            const desiredDt = opt.maxFPS ? 1 / opt.maxFPS : 0;\n\n            state.realTime = loopTime;\n            accumulatedDt += realDt;\n\n            if (accumulatedDt > desiredDt) {\n                if (!state.skipTime) {\n                    fixedAccumulatedDt += accumulatedDt;\n                    state.dt = state.fixedDt;\n                    state.restDt = 0;\n                    while (fixedAccumulatedDt > state.fixedDt) {\n                        fixedAccumulatedDt -= state.fixedDt;\n                        if (fixedAccumulatedDt < state.fixedDt) {\n                            state.restDt = fixedAccumulatedDt;\n                        }\n                        fixedUpdate();\n                    }\n                    state.restDt = fixedAccumulatedDt;\n                    state.dt = accumulatedDt;\n                    state.time += dt();\n                    state.fpsCounter.tick(state.dt);\n                }\n                accumulatedDt = 0;\n                state.skipTime = false;\n                state.numFrames++;\n\n                update(processInput, resetInput);\n            }\n\n            state.loopID = requestAnimationFrame(frame);\n        };\n\n        frame(0);\n    }\n\n    function isTouchscreen() {\n        return (\"ontouchstart\" in window) || navigator.maxTouchPoints > 0;\n    }\n\n    function mousePos(): Vec2 {\n        return state.mousePos.clone();\n    }\n\n    function mouseDeltaPos(): Vec2 {\n        return state.mouseDeltaPos.clone();\n    }\n\n    function isMousePressed(m: MouseButton = \"left\"): boolean {\n        return state.mouseState.pressed.has(m);\n    }\n\n    function isMouseDown(m: MouseButton = \"left\"): boolean {\n        return state.mouseState.down.has(m);\n    }\n\n    function isMouseReleased(m: MouseButton = \"left\"): boolean {\n        return state.mouseState.released.has(m);\n    }\n\n    function isMouseMoved(): boolean {\n        return state.isMouseMoved;\n    }\n\n    function isKeyPressed(k?: Key | Key[]): boolean {\n        return k === undefined\n            ? state.keyState.pressed.size > 0\n            : setHasOrIncludes(state.keyState.pressed, k);\n    }\n\n    function isKeyPressedRepeat(k?: Key | Key[]): boolean {\n        return k === undefined\n            ? state.keyState.pressedRepeat.size > 0\n            : setHasOrIncludes(state.keyState.pressedRepeat, k);\n    }\n\n    function isKeyDown(k?: Key | Key[]): boolean {\n        return k === undefined\n            ? state.keyState.down.size > 0\n            : setHasOrIncludes(state.keyState.down, k);\n    }\n\n    function isKeyReleased(k?: Key | Key[]): boolean {\n        return k === undefined\n            ? state.keyState.released.size > 0\n            : setHasOrIncludes(state.keyState.released, k);\n    }\n\n    function isGamepadButtonPressed(\n        btn?: KGamepadButton | KGamepadButton[],\n    ): boolean {\n        return btn === undefined\n            ? state.mergedGamepadState.buttonState.pressed.size > 0\n            : setHasOrIncludes(\n                state.mergedGamepadState.buttonState.pressed,\n                btn,\n            );\n    }\n\n    function isGamepadButtonDown(\n        btn?: KGamepadButton | KGamepadButton[],\n    ): boolean {\n        return btn === undefined\n            ? state.mergedGamepadState.buttonState.down.size > 0\n            : setHasOrIncludes(state.mergedGamepadState.buttonState.down, btn);\n    }\n\n    function isGamepadButtonReleased(\n        btn?: KGamepadButton | KGamepadButton[],\n    ): boolean {\n        return btn === undefined\n            ? state.mergedGamepadState.buttonState.released.size > 0\n            : setHasOrIncludes(\n                state.mergedGamepadState.buttonState.released,\n                btn,\n            );\n    }\n\n    function isButtonPressed(btn?: string | string[]): boolean {\n        return btn === undefined\n            ? state.buttonState.pressed.size > 0\n            : setHasOrIncludes(state.buttonState.pressed, btn);\n    }\n\n    function isButtonDown(btn?: string | string[]): boolean {\n        return btn === undefined\n            ? state.buttonState.down.size > 0\n            : setHasOrIncludes(state.buttonState.down, btn);\n    }\n\n    function isButtonReleased(btn?: string | string[]): boolean {\n        return btn === undefined\n            ? state.buttonState.released.size > 0\n            : setHasOrIncludes(state.buttonState.released, btn);\n    }\n\n    function getButton(btn: string): ButtonBinding {\n        return state.buttons?.[btn];\n    }\n\n    function setButton(btn: string, binding: ButtonBinding) {\n        state.buttons[btn] = {\n            ...state.buttons[btn],\n            ...binding,\n        };\n    }\n\n    function pressButton(btn: string) {\n        state.buttonState.press(btn);\n        state.events.trigger(\"buttonPress\", btn);\n    }\n\n    function releaseButton(btn: string) {\n        state.buttonState.release(btn);\n        state.events.trigger(\"buttonRelease\", btn);\n    }\n\n    function onResize(action: () => void): KEventController {\n        return state.events.on(\"resize\", action);\n    }\n\n    // input callbacks\n    const onKeyDown = overload2((action: (key: Key) => void) => {\n        return state.events.on(\"keyDown\", action);\n    }, (key: Key | Key[], action: (key: Key) => void) => {\n        return state.events.on(\n            \"keyDown\",\n            (k) => isEqOrIncludes(key, k) && action(k),\n        );\n    });\n\n    // key pressed is equal to the key by the user\n    const onKeyPress = overload2((action: (key: Key) => void) => {\n        return state.events.on(\"keyPress\", (k) => action(k));\n    }, (key: Key | Key[], action: (key: Key) => void) => {\n        return state.events.on(\n            \"keyPress\",\n            (k) => isEqOrIncludes(key, k) && action(k),\n        );\n    });\n\n    const onKeyPressRepeat = overload2((action: (key: Key) => void) => {\n        return state.events.on(\"keyPressRepeat\", action);\n    }, (key: Key | Key[], action: (key: Key) => void) => {\n        return state.events.on(\n            \"keyPressRepeat\",\n            (k) => isEqOrIncludes(key, k) && action(k),\n        );\n    });\n\n    const onKeyRelease = overload2((action: (key: Key) => void) => {\n        return state.events.on(\"keyRelease\", action);\n    }, (key: Key | Key[], action: (key: Key) => void) => {\n        return state.events.on(\n            \"keyRelease\",\n            (k) => isEqOrIncludes(key, k) && action(k),\n        );\n    });\n\n    const onMouseDown = overload2((action: (m: MouseButton) => void) => {\n        return state.events.on(\"mouseDown\", (m) => action(m));\n    }, (\n        mouse: MouseButton | MouseButton[],\n        action: (m: MouseButton) => void,\n    ) => {\n        return state.events.on(\n            \"mouseDown\",\n            (m) => isEqOrIncludes(mouse, m) && action(m),\n        );\n    });\n\n    const onMousePress = overload2((action: (m: MouseButton) => void) => {\n        return state.events.on(\"mousePress\", (m) => action(m));\n    }, (\n        mouse: MouseButton | MouseButton[],\n        action: (m: MouseButton) => void,\n    ) => {\n        return state.events.on(\n            \"mousePress\",\n            (m) => isEqOrIncludes(mouse, m) && action(m),\n        );\n    });\n\n    const onMouseRelease = overload2((action: (m: MouseButton) => void) => {\n        return state.events.on(\"mouseRelease\", (m) => action(m));\n    }, (\n        mouse: MouseButton | MouseButton[],\n        action: (m: MouseButton) => void,\n    ) => {\n        return state.events.on(\"mouseRelease\", (m) => m === mouse && action(m));\n    });\n\n    function onMouseMove(f: (pos: Vec2, dpos: Vec2) => void): KEventController {\n        return state.events.on(\n            \"mouseMove\",\n            () => f(mousePos(), mouseDeltaPos()),\n        );\n    }\n\n    function onCharInput(action: (ch: string) => void): KEventController {\n        return state.events.on(\"charInput\", action);\n    }\n\n    function onTouchStart(f: (pos: Vec2, t: Touch) => void): KEventController {\n        return state.events.on(\"touchStart\", f);\n    }\n\n    function onTouchMove(f: (pos: Vec2, t: Touch) => void): KEventController {\n        return state.events.on(\"touchMove\", f);\n    }\n\n    function onTouchEnd(f: (pos: Vec2, t: Touch) => void): KEventController {\n        return state.events.on(\"touchEnd\", f);\n    }\n\n    function onScroll(action: (delta: Vec2) => void): KEventController {\n        return state.events.on(\"scroll\", action);\n    }\n\n    function onHide(action: () => void): KEventController {\n        return state.events.on(\"hide\", action);\n    }\n\n    function onShow(action: () => void): KEventController {\n        return state.events.on(\"show\", action);\n    }\n\n    const onGamepadButtonPress = overload2(\n        (action: (btn: KGamepadButton, gamepad: KGamepad) => void) => {\n            return state.events.on(\n                \"gamepadButtonPress\",\n                (b, gp) => action(b, gp),\n            );\n        },\n        (\n            btn: KGamepadButton | KGamepadButton[],\n            action: (btn: KGamepadButton, gamepad: KGamepad) => void,\n        ) => {\n            return state.events.on(\n                \"gamepadButtonPress\",\n                (b, gp) => isEqOrIncludes(btn, b) && action(b, gp),\n            );\n        },\n    );\n\n    const onGamepadButtonDown = overload2(\n        (action: (btn: KGamepadButton, gamepad: KGamepad) => void) => {\n            return state.events.on(\n                \"gamepadButtonDown\",\n                (b, gp) => action(b, gp),\n            );\n        },\n        (\n            btn: KGamepadButton,\n            action: (btn: KGamepadButton, gamepad: KGamepad) => void,\n        ) => {\n            return state.events.on(\n                \"gamepadButtonDown\",\n                (b, gp) => isEqOrIncludes(btn, b) && action(b, gp),\n            );\n        },\n    );\n\n    const onGamepadButtonRelease = overload2(\n        (action: (btn: KGamepadButton, gamepad: KGamepad) => void) => {\n            return state.events.on(\n                \"gamepadButtonRelease\",\n                (b, gp) => action(b, gp),\n            );\n        },\n        (\n            btn: KGamepadButton | KGamepadButton[],\n            action: (btn: KGamepadButton, gamepad: KGamepad) => void,\n        ) => {\n            return state.events.on(\n                \"gamepadButtonRelease\",\n                (b, gp) => isEqOrIncludes(btn, b) && action(b, gp),\n            );\n        },\n    );\n\n    function onGamepadStick(\n        stick: GamepadStick,\n        action: (value: Vec2, gp: KGamepad) => void,\n    ): KEventController {\n        return state.events.on(\n            \"gamepadStick\",\n            (a, v, gp) => a === stick && action(v, gp),\n        );\n    }\n\n    function onGamepadConnect(action: (gamepad: KGamepad) => void) {\n        state.events.on(\"gamepadConnect\", action);\n    }\n\n    function onGamepadDisconnect(action: (gamepad: KGamepad) => void) {\n        state.events.on(\"gamepadDisconnect\", action);\n    }\n\n    function getGamepadStick(stick: GamepadStick): Vec2 {\n        return state.mergedGamepadState.stickState.get(stick) || new Vec2(0);\n    }\n\n    function charInputted(): string[] {\n        return [...state.charInputted];\n    }\n\n    function getGamepads(): KGamepad[] {\n        return [...state.gamepads];\n    }\n\n    const onButtonPress = overload2((action: (btn: string) => void) => {\n        return state.events.on(\"buttonPress\", (b) => action(b));\n    }, (btn: string | string, action: (btn: string) => void) => {\n        return state.events.on(\n            \"buttonPress\",\n            (b) => isEqOrIncludes(btn, b) && action(b),\n        );\n    });\n\n    const onButtonDown = overload2((action: (btn: string) => void) => {\n        return state.events.on(\"buttonDown\", (b) => action(b));\n    }, (btn: string | string, action: (btn: string) => void) => {\n        return state.events.on(\n            \"buttonDown\",\n            (b) => isEqOrIncludes(btn, b) && action(b),\n        );\n    });\n\n    const onButtonRelease = overload2((action: (btn: string) => void) => {\n        return state.events.on(\"buttonRelease\", (b) => action(b));\n    }, (btn: string | string, action: (btn: string) => void) => {\n        return state.events.on(\n            \"buttonRelease\",\n            (b) => isEqOrIncludes(btn, b) && action(b),\n        );\n    });\n\n    function processInput() {\n        state.events.trigger(\"input\");\n        state.keyState.down.forEach((k) => state.events.trigger(\"keyDown\", k));\n        state.mouseState.down.forEach((k) =>\n            state.events.trigger(\"mouseDown\", k)\n        );\n        state.buttonState.down.forEach((btn) => {\n            state.events.trigger(\"buttonDown\", btn);\n        });\n\n        processGamepad();\n    }\n\n    function resetInput() {\n        state.keyState.update();\n        state.mouseState.update();\n        state.buttonState.update();\n\n        state.mergedGamepadState.buttonState.update();\n        state.mergedGamepadState.stickState.forEach((v, k) => {\n            state.mergedGamepadState.stickState.set(k, new Vec2(0));\n        });\n\n        state.charInputted = [];\n        state.isMouseMoved = false;\n        state.mouseDeltaPos = new Vec2(0);\n\n        state.gamepadStates.forEach((s) => {\n            s.buttonState.update();\n            s.stickState.forEach((v, k) => {\n                s.stickState.set(k, new Vec2(0));\n            });\n        });\n    }\n\n    function registerGamepad(browserGamepad: Gamepad) {\n        const gamepad: KGamepad = {\n            index: browserGamepad.index,\n            isPressed: (btn: KGamepadButton) => {\n                return state.gamepadStates.get(browserGamepad.index)\n                    ?.buttonState\n                    .pressed.has(btn) || false;\n            },\n            isDown: (btn: KGamepadButton) => {\n                return state.gamepadStates.get(browserGamepad.index)\n                    ?.buttonState\n                    .down.has(btn) || false;\n            },\n            isReleased: (btn: KGamepadButton) => {\n                return state.gamepadStates.get(browserGamepad.index)\n                    ?.buttonState\n                    .released.has(btn) || false;\n            },\n            getStick: (stick: GamepadStick) => {\n                return state.gamepadStates.get(browserGamepad.index)?.stickState\n                    .get(stick) || vec2();\n            },\n        };\n\n        state.gamepads.push(gamepad);\n\n        state.gamepadStates.set(browserGamepad.index, {\n            buttonState: new ButtonState(),\n            stickState: new Map([\n                [\"left\", new Vec2(0)],\n                [\"right\", new Vec2(0)],\n            ]),\n        });\n\n        return gamepad;\n    }\n\n    function removeGamepad(gamepad: Gamepad) {\n        state.gamepads = state.gamepads.filter((g) =>\n            g.index !== gamepad.index\n        );\n        state.gamepadStates.delete(gamepad.index);\n    }\n\n    // TODO: Clean up this function\n    function processGamepad() {\n        for (const browserGamepad of navigator.getGamepads()) {\n            if (\n                browserGamepad && !state.gamepadStates.has(\n                    browserGamepad.index,\n                )\n            ) {\n                registerGamepad(browserGamepad);\n            }\n        }\n\n        for (const gamepad of state.gamepads) {\n            const browserGamepad = navigator.getGamepads()[gamepad.index];\n            if (!browserGamepad) continue;\n\n            const customMap = opt.gamepads ?? {};\n            const map = customMap[browserGamepad.id]\n                || GP_MAP[browserGamepad.id] || GP_MAP[\"default\"];\n            const gamepadState = state.gamepadStates.get(gamepad.index);\n            if (!gamepadState) continue;\n\n            for (let i = 0; i < browserGamepad.buttons.length; i++) {\n                const gamepadBtn = map.buttons[i];\n                const browserGamepadBtn = browserGamepad.buttons[i];\n                const isGamepadButtonBind = state.buttonsByGamepad.has(\n                    gamepadBtn,\n                );\n\n                if (browserGamepadBtn.pressed) {\n                    if (gamepadState.buttonState.down.has(gamepadBtn)) {\n                        state.events.trigger(\n                            \"gamepadButtonDown\",\n                            gamepadBtn,\n                            gamepad,\n                        );\n\n                        continue;\n                    }\n\n                    state.lastInputDevice = \"gamepad\";\n\n                    if (isGamepadButtonBind) {\n                        // replicate input in merged state, defined button state and gamepad state\n                        state.buttonsByGamepad.get(gamepadBtn)?.forEach(\n                            (btn) => {\n                                state.buttonState.press(btn);\n                                state.events.trigger(\"buttonPress\", btn);\n                            },\n                        );\n                    }\n\n                    state.mergedGamepadState.buttonState.press(gamepadBtn);\n                    gamepadState.buttonState.press(gamepadBtn);\n                    state.events.trigger(\n                        \"gamepadButtonPress\",\n                        gamepadBtn,\n                        gamepad,\n                    );\n                }\n                else if (gamepadState.buttonState.down.has(gamepadBtn)) {\n                    if (isGamepadButtonBind) {\n                        state.buttonsByGamepad.get(gamepadBtn)?.forEach(\n                            (btn) => {\n                                state.buttonState.release(btn);\n                                state.events.trigger(\"buttonRelease\", btn);\n                            },\n                        );\n                    }\n\n                    state.mergedGamepadState.buttonState.release(\n                        gamepadBtn,\n                    );\n                    gamepadState.buttonState.release(gamepadBtn);\n\n                    state.events.trigger(\n                        \"gamepadButtonRelease\",\n                        gamepadBtn,\n                        gamepad,\n                    );\n                }\n            }\n\n            for (const stickName in map.sticks) {\n                const stick = map.sticks[stickName as GamepadStick];\n                if (!stick) continue;\n                const value = new Vec2(\n                    browserGamepad.axes[stick.x],\n                    browserGamepad.axes[stick.y],\n                );\n                gamepadState.stickState.set(stickName as GamepadStick, value);\n                state.mergedGamepadState.stickState.set(\n                    stickName as GamepadStick,\n                    value,\n                );\n                state.events.trigger(\"gamepadStick\", stickName, value, gamepad);\n            }\n        }\n    }\n\n    type EventList<M> = {\n        [event in keyof M]?: (event: M[event]) => void;\n    };\n\n    const canvasEvents: EventList<HTMLElementEventMap> = {};\n    const docEvents: EventList<DocumentEventMap> = {};\n    const winEvents: EventList<WindowEventMap> = {};\n\n    const pd = opt.pixelDensity || 1;\n\n    canvasEvents.mousemove = (e) => {\n        // Ironically, e.offsetX and e.offsetY are the mouse position. Is not\n        // related to what we call the \"offset\" in this code\n        const mousePos = canvasToViewport(new Vec2(e.offsetX, e.offsetY));\n        const mouseDeltaPos = new Vec2(e.movementX, e.movementY);\n\n        if (isFullscreen()) {\n            const cw = state.canvas.width / pd;\n            const ch = state.canvas.height / pd;\n            const ww = window.innerWidth;\n            const wh = window.innerHeight;\n            const rw = ww / wh;\n            const rc = cw / ch;\n            if (rw > rc) {\n                const ratio = wh / ch;\n                const offset = (ww - (cw * ratio)) / 2;\n                mousePos.x = map(e.offsetX - offset, 0, cw * ratio, 0, cw);\n                mousePos.y = map(e.offsetY, 0, ch * ratio, 0, ch);\n            }\n            else {\n                const ratio = ww / cw;\n                const offset = (wh - (ch * ratio)) / 2;\n                mousePos.x = map(e.offsetX, 0, cw * ratio, 0, cw);\n                mousePos.y = map(e.offsetY - offset, 0, ch * ratio, 0, ch);\n            }\n        }\n\n        state.events.onOnce(\"input\", () => {\n            state.isMouseMoved = true;\n            state.mousePos = mousePos;\n            state.mouseDeltaPos = mouseDeltaPos;\n            state.events.trigger(\"mouseMove\");\n        });\n    };\n\n    const MOUSE_BUTTONS: MouseButton[] = [\n        \"left\",\n        \"middle\",\n        \"right\",\n        \"back\",\n        \"forward\",\n    ];\n\n    canvasEvents.mousedown = (e) => {\n        state.events.onOnce(\"input\", () => {\n            const m = MOUSE_BUTTONS[e.button];\n            if (!m) return;\n\n            state.lastInputDevice = \"mouse\";\n\n            if (state.buttonsByMouse.has(m)) {\n                state.buttonsByMouse.get(m)?.forEach((btn) => {\n                    state.buttonState.press(btn);\n                    state.events.trigger(\"buttonPress\", btn);\n                });\n            }\n\n            state.mouseState.press(m);\n            state.events.trigger(\"mousePress\", m);\n        });\n    };\n\n    canvasEvents.mouseup = (e) => {\n        state.events.onOnce(\"input\", () => {\n            const m = MOUSE_BUTTONS[e.button];\n            if (!m) return;\n\n            if (state.buttonsByMouse.has(m)) {\n                state.buttonsByMouse.get(m)?.forEach((btn) => {\n                    state.buttonState.release(btn);\n                    state.events.trigger(\"buttonRelease\", btn);\n                });\n            }\n\n            state.mouseState.release(m);\n            state.events.trigger(\"mouseRelease\", m);\n        });\n    };\n\n    const PREVENT_DEFAULT_KEYS = new Set([\n        \" \",\n        \"ArrowLeft\",\n        \"ArrowRight\",\n        \"ArrowUp\",\n        \"ArrowDown\",\n        \"Tab\",\n    ]);\n\n    // translate these key names to a simpler version\n    const KEY_ALIAS = {\n        \"ArrowLeft\": \"left\",\n        \"ArrowRight\": \"right\",\n        \"ArrowUp\": \"up\",\n        \"ArrowDown\": \"down\",\n        \" \": \"space\",\n    };\n\n    canvasEvents.keydown = (e) => {\n        if (PREVENT_DEFAULT_KEYS.has(e.key)) {\n            e.preventDefault();\n        }\n        state.events.onOnce(\"input\", () => {\n            const k: Key = KEY_ALIAS[e.key as keyof typeof KEY_ALIAS] as Key\n                || e.key.toLowerCase();\n            const code = e.code;\n\n            if (k === undefined) throw new Error(`Unknown key: ${e.key}`);\n            if (k.length === 1) {\n                state.events.trigger(\"charInput\", k);\n                state.charInputted.push(k);\n            }\n            else if (k === \"space\") {\n                state.events.trigger(\"charInput\", \" \");\n                state.charInputted.push(\" \");\n            }\n            if (e.repeat) {\n                state.keyState.pressRepeat(k);\n                state.events.trigger(\"keyPressRepeat\", k);\n            }\n            else {\n                state.lastInputDevice = \"keyboard\";\n\n                if (state.buttonsByKey.has(k)) {\n                    state.buttonsByKey.get(k)?.forEach((btn) => {\n                        state.buttonState.press(btn);\n                        state.events.trigger(\"buttonPress\", btn);\n                    });\n                }\n\n                if (state.buttonsByKeyCode.has(code)) {\n                    state.buttonsByKeyCode.get(code)?.forEach((btn) => {\n                        state.buttonState.press(btn);\n                        state.events.trigger(\"buttonPress\", btn);\n                    });\n                }\n\n                state.keyState.press(k);\n                state.events.trigger(\"keyPressRepeat\", k);\n                state.events.trigger(\"keyPress\", k);\n            }\n        });\n    };\n\n    canvasEvents.keyup = (e) => {\n        state.events.onOnce(\"input\", () => {\n            const k: Key = KEY_ALIAS[e.key as keyof typeof KEY_ALIAS] as Key\n                || e.key.toLowerCase();\n            const code = e.code;\n\n            if (state.buttonsByKey.has(k)) {\n                state.buttonsByKey.get(k)?.forEach((btn) => {\n                    state.buttonState.release(btn);\n                    state.events.trigger(\"buttonRelease\", btn);\n                });\n            }\n\n            if (state.buttonsByKeyCode.has(code)) {\n                state.buttonsByKeyCode.get(code)?.forEach((btn) => {\n                    state.buttonState.release(btn);\n                    state.events.trigger(\"buttonRelease\", btn);\n                });\n            }\n\n            state.keyState.release(k);\n            state.events.trigger(\"keyRelease\", k);\n        });\n    };\n\n    // TODO: handle all touches at once instead of sequentially\n    canvasEvents.touchstart = (e) => {\n        // disable long tap context menu\n        e.preventDefault();\n\n        state.events.onOnce(\"input\", () => {\n            const touches = [...e.changedTouches];\n            const box = state.canvas.getBoundingClientRect();\n\n            if (opt.touchToMouse !== false) {\n                state.mousePos = canvasToViewport(\n                    new Vec2(\n                        touches[0].clientX - box.x,\n                        touches[0].clientY - box.y,\n                    ),\n                );\n\n                state.lastInputDevice = \"mouse\";\n\n                if (state.buttonsByMouse.has(\"left\")) {\n                    state.buttonsByMouse.get(\"left\")?.forEach((btn) => {\n                        state.buttonState.press(btn);\n                        state.events.trigger(\"buttonPress\", btn);\n                    });\n                }\n\n                state.mouseState.press(\"left\");\n                state.events.trigger(\"mousePress\", \"left\");\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchStart\",\n                    canvasToViewport(\n                        new Vec2(t.clientX - box.x, t.clientY - box.y),\n                    ),\n                    t,\n                );\n            });\n        });\n    };\n\n    canvasEvents.touchmove = (e) => {\n        // disable scrolling\n        e.preventDefault();\n        state.events.onOnce(\"input\", () => {\n            const touches = [...e.changedTouches];\n            const box = state.canvas.getBoundingClientRect();\n\n            if (opt.touchToMouse !== false) {\n                const lastMousePos = state.mousePos;\n                state.mousePos = canvasToViewport(\n                    new Vec2(\n                        touches[0].clientX - box.x,\n                        touches[0].clientY - box.y,\n                    ),\n                );\n                state.mouseDeltaPos = state.mousePos.sub(lastMousePos);\n                state.events.trigger(\"mouseMove\");\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchMove\",\n                    canvasToViewport(\n                        new Vec2(t.clientX - box.x, t.clientY - box.y),\n                    ),\n                    t,\n                );\n            });\n        });\n    };\n\n    canvasEvents.touchend = (e) => {\n        state.events.onOnce(\"input\", () => {\n            const touches = [...e.changedTouches];\n            const box = state.canvas.getBoundingClientRect();\n\n            if (opt.touchToMouse !== false) {\n                state.mousePos = canvasToViewport(\n                    new Vec2(\n                        touches[0].clientX - box.x,\n                        touches[0].clientY - box.y,\n                    ),\n                );\n\n                state.mouseDeltaPos = new Vec2(0, 0);\n\n                if (state.buttonsByMouse.has(\"left\")) {\n                    state.buttonsByMouse.get(\"left\")?.forEach((btn) => {\n                        state.buttonState.release(btn);\n                        state.events.trigger(\"buttonRelease\", btn);\n                    });\n                }\n\n                state.mouseState.release(\"left\");\n                state.events.trigger(\"mouseRelease\", \"left\");\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchEnd\",\n                    canvasToViewport(\n                        new Vec2(t.clientX - box.x, t.clientY - box.y),\n                    ),\n                    t,\n                );\n            });\n        });\n    };\n\n    canvasEvents.touchcancel = (e) => {\n        state.events.onOnce(\"input\", () => {\n            const touches = [...e.changedTouches];\n            const box = state.canvas.getBoundingClientRect();\n\n            if (opt.touchToMouse !== false) {\n                state.mousePos = canvasToViewport(\n                    new Vec2(\n                        touches[0].clientX - box.x,\n                        touches[0].clientY - box.y,\n                    ),\n                );\n                state.mouseState.release(\"left\");\n                state.events.trigger(\"mouseRelease\", \"left\");\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchEnd\",\n                    canvasToViewport(\n                        new Vec2(t.clientX - box.x, t.clientY - box.y),\n                    ),\n                    t,\n                );\n            });\n        });\n    };\n\n    // TODO: option to not prevent default?\n    canvasEvents.wheel = (e) => {\n        e.preventDefault();\n        state.events.onOnce(\"input\", () => {\n            state.events.trigger(\"scroll\", new Vec2(e.deltaX, e.deltaY));\n        });\n    };\n\n    canvasEvents.contextmenu = (e) => e.preventDefault();\n\n    docEvents.visibilitychange = () => {\n        if (document.visibilityState === \"visible\") {\n            // prevent a surge of dt when switch back after the tab being hidden for a while\n            state.skipTime = true;\n            state.isHidden = false;\n            state.events.trigger(\"show\");\n        }\n        else {\n            state.isHidden = true;\n            state.events.trigger(\"hide\");\n        }\n    };\n\n    winEvents.gamepadconnected = (e) => {\n        const kbGamepad = registerGamepad(e.gamepad);\n        state.events.onOnce(\"input\", () => {\n            state.events.trigger(\"gamepadConnect\", kbGamepad);\n        });\n    };\n\n    winEvents.gamepaddisconnected = (e) => {\n        const kbGamepad =\n            getGamepads().filter((g) => g.index === e.gamepad.index)[0];\n        removeGamepad(e.gamepad);\n        state.events.onOnce(\"input\", () => {\n            state.events.trigger(\"gamepadDisconnect\", kbGamepad);\n        });\n    };\n\n    for (const [name, val] of Object.entries(canvasEvents)) {\n        state.canvas.addEventListener(\n            name,\n            val as EventListenerOrEventListenerObject,\n        );\n    }\n\n    for (const [name, val] of Object.entries(docEvents)) {\n        document.addEventListener(\n            name,\n            val as EventListenerOrEventListenerObject,\n        );\n    }\n\n    for (const [name, val] of Object.entries(winEvents)) {\n        window.addEventListener(\n            name,\n            val as EventListenerOrEventListenerObject,\n        );\n    }\n\n    const resizeObserver = new ResizeObserver((entries) => {\n        for (const entry of entries) {\n            if (entry.target !== state.canvas) continue;\n            if (\n                state.lastWidth === state.canvas.offsetWidth\n                && state.lastHeight === state.canvas.offsetHeight\n            ) return;\n            state.lastWidth = state.canvas.offsetWidth;\n            state.lastHeight = state.canvas.offsetHeight;\n            state.events.onOnce(\"input\", () => {\n                state.events.trigger(\"resize\");\n            });\n        }\n    });\n\n    resizeObserver.observe(state.canvas);\n\n    return {\n        state,\n        dt,\n        fixedDt,\n        restDt,\n        time,\n        run,\n        canvas: state.canvas,\n        fps,\n        numFrames,\n        quit,\n        isHidden,\n        setFullscreen,\n        isFullscreen,\n        setCursor,\n        screenshot,\n        getGamepads,\n        getCursor,\n        setCursorLocked,\n        isCursorLocked,\n        isTouchscreen,\n        mousePos,\n        mouseDeltaPos,\n        isKeyDown,\n        isKeyPressed,\n        isKeyPressedRepeat,\n        isKeyReleased,\n        isMouseDown,\n        isMousePressed,\n        isMouseReleased,\n        isMouseMoved,\n        isGamepadButtonPressed,\n        isGamepadButtonDown,\n        isGamepadButtonReleased,\n        getGamepadStick,\n        isButtonPressed,\n        isButtonDown,\n        isButtonReleased,\n        setButton,\n        getButton,\n        pressButton,\n        releaseButton,\n        charInputted,\n        onResize,\n        onKeyDown,\n        onKeyPress,\n        onKeyPressRepeat,\n        onKeyRelease,\n        onMouseDown,\n        onMousePress,\n        onMouseRelease,\n        onMouseMove,\n        onCharInput,\n        onTouchStart,\n        onTouchMove,\n        onTouchEnd,\n        onScroll,\n        onHide,\n        onShow,\n        onGamepadButtonDown,\n        onGamepadButtonPress,\n        onGamepadButtonRelease,\n        onGamepadStick,\n        onGamepadConnect,\n        onGamepadDisconnect,\n        onButtonPress,\n        onButtonDown,\n        onButtonRelease,\n        getLastInputDeviceType,\n        events: state.events,\n    };\n};\n", "import { _k } from \"../kaplay\";\n\nexport function dt() {\n    return _k.app.dt();\n}\n\nexport function fixedDt() {\n    return _k.app.fixedDt();\n}\n\nexport function restDt() {\n    return _k.app.restDt();\n}\n", "import { Vec2 } from \"../math/math\";\nimport { type Anchor } from \"../types\";\nimport type { TextAlign } from \"./draw\";\n\nconst TOP_LEFT = new Vec2(-1, -1);\nconst TOP = new Vec2(0, -1);\nconst TOP_RIGHT = new Vec2(1, -1);\nconst LEFT = new Vec2(-1, 0);\nconst CENTER = new Vec2(0, 0);\nconst RIGHT = new Vec2(1, 0);\nconst BOTTOM_LEFT = new Vec2(-1, 1);\nconst BOTTOM = new Vec2(0, 1);\nconst BOTTOM_RIGHT = new Vec2(1, 1);\n\n// convert anchor string to a vec2 offset\nexport function anchorPt(orig: Anchor | Vec2): Vec2 {\n    switch (orig) {\n        case \"topleft\":\n            return TOP_LEFT;\n        case \"top\":\n            return TOP;\n        case \"topright\":\n            return TOP_RIGHT;\n        case \"left\":\n            return LEFT;\n        case \"center\":\n            return CENTER;\n        case \"right\":\n            return RIGHT;\n        case \"botleft\":\n            return BOTTOM_LEFT;\n        case \"bot\":\n            return BOTTOM;\n        case \"botright\":\n            return BOTTOM_RIGHT;\n        default:\n            return orig;\n    }\n}\n\nexport function alignPt(align: TextAlign): number {\n    switch (align) {\n        case \"left\":\n            return 0;\n        case \"center\":\n            return 0.5;\n        case \"right\":\n            return 1;\n        default:\n            return 0;\n    }\n}\n\nexport function createEmptyAudioBuffer(ctx: AudioContext) {\n    return ctx.createBuffer(1, 1, 44100);\n}\n", "// https://easings.net/\nconst c1 = 1.70158;\nconst c2 = c1 * 1.525;\nconst c3 = c1 + 1;\nconst c4 = (2 * Math.PI) / 3;\nconst c5 = (2 * Math.PI) / 4.5;\n\nconst easings = {\n    linear: (x: number) => x,\n    easeInSine: (x: number) => 1 - Math.cos((x * Math.PI) / 2),\n    easeOutSine: (x: number) => Math.sin((x * Math.PI) / 2),\n    easeInOutSine: (x: number) => -(Math.cos(Math.PI * x) - 1) / 2,\n    easeInQuad: (x: number) => x * x,\n    easeOutQuad: (x: number) => 1 - (1 - x) * (1 - x),\n    easeInOutQuad: (x: number) =>\n        x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2,\n    easeInCubic: (x: number) => x * x * x,\n    easeOutCubic: (x: number) => 1 - Math.pow(1 - x, 3),\n    easeInOutCubic: (x: number) =>\n        x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2,\n    easeInQuart: (x: number) => x * x * x * x,\n    easeOutQuart: (x: number) => 1 - Math.pow(1 - x, 4),\n    easeInOutQuart: (x: number) =>\n        x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2,\n    easeInQuint: (x: number) => x * x * x * x * x,\n    easeOutQuint: (x: number) => 1 - Math.pow(1 - x, 5),\n    easeInOutQuint: (x: number) =>\n        x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2,\n    easeInExpo: (x: number) => x === 0 ? 0 : Math.pow(2, 10 * x - 10),\n    easeOutExpo: (x: number) => x === 1 ? 1 : 1 - Math.pow(2, -10 * x),\n    easeInOutExpo: (x: number) => {\n        return x === 0\n            ? 0\n            : x === 1\n            ? 1\n            : x < 0.5\n            ? Math.pow(2, 20 * x - 10) / 2\n            : (2 - Math.pow(2, -20 * x + 10)) / 2;\n    },\n    easeInCirc: (x: number) => 1 - Math.sqrt(1 - Math.pow(x, 2)),\n    easeOutCirc: (x: number) => Math.sqrt(1 - Math.pow(x - 1, 2)),\n    easeInOutCirc: (x: number) => {\n        return x < 0.5\n            ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2\n            : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2;\n    },\n    easeInBack: (x: number) => c3 * x * x * x - c1 * x * x,\n    easeOutBack: (x: number) =>\n        1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2),\n    easeInOutBack: (x: number) => {\n        return x < 0.5\n            ? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2\n            : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;\n    },\n    easeInElastic: (x: number) => {\n        return x === 0\n            ? 0\n            : x === 1\n            ? 1\n            : -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * c4);\n    },\n    easeOutElastic: (x: number) => {\n        return x === 0\n            ? 0\n            : x === 1\n            ? 1\n            : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1;\n    },\n    easeInOutElastic: (x: number) => {\n        return x === 0\n            ? 0\n            : x === 1\n            ? 1\n            : x < 0.5\n            ? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2\n            : (Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5)) / 2\n                + 1;\n    },\n    easeInBounce: (x: number) => 1 - easings.easeOutBounce(1 - x),\n    easeOutBounce: (x: number) => {\n        const n1 = 7.5625;\n        const d1 = 2.75;\n        if (x < 1 / d1) {\n            return n1 * x * x;\n        }\n        else if (x < 2 / d1) {\n            return n1 * (x -= 1.5 / d1) * x + 0.75;\n        }\n        else if (x < 2.5 / d1) {\n            return n1 * (x -= 2.25 / d1) * x + 0.9375;\n        }\n        else {\n            return n1 * (x -= 2.625 / d1) * x + 0.984375;\n        }\n    },\n    easeInOutBounce: (x: number) => {\n        return x < 0.5\n            ? (1 - easings.easeOutBounce(1 - 2 * x)) / 2\n            : (1 + easings.easeOutBounce(2 * x - 1)) / 2;\n    },\n};\n\nexport default easings;\n", "import { BinaryHeap } from \"../utils\";\nimport { Vec2 } from \"./math\";\n\nexport interface Graph {\n    /* Returns the reachable neighbours of this location */\n    getNeighbours(node: number): number[];\n    /* Returns the cost to go from the node to its neighbor */\n    getCost(node: number, neighbor: number): number;\n    /* Returns the cost to go from the node to the goal */\n    getHeuristic(node: number, goal: number): number;\n    /* Returns the path as locations */\n    getPath(from: number, to: number): number[];\n    /* Returns the path as waypoints */\n    getWaypointPath(\n        from: Vec2,\n        to: Vec2,\n        opt: any,\n    ): Vec2[];\n}\n\nfunction buildPath(start: number, goal: number, cameFrom: Map<number, number>) {\n    const path = [];\n    let node = goal;\n    path.push(node);\n    while (node !== start) {\n        // TODO: Remove non-null assertion\n        node = cameFrom.get(node)!;\n        if (node == undefined) return null;\n        path.push(node);\n    }\n    return path.reverse();\n}\n\nexport function breadthFirstSearch(\n    graph: Graph,\n    start: number,\n    goal: number,\n) {\n    let frontier = [];\n    frontier.push(start);\n\n    let cameFrom = new Map<number, number>();\n    cameFrom.set(start, start);\n\n    while (frontier.length !== 0) {\n        let current = frontier.pop();\n\n        if (current === goal) {\n            break;\n        }\n\n        // TODO: Remove non-null assertion\n        const neighbours = graph.getNeighbours(current!);\n        for (let next of neighbours) {\n            if (!cameFrom.get(next)) {\n                frontier.push(next);\n                // TODO: Remove non-null assertion\n                cameFrom.set(next, current!);\n            }\n        }\n    }\n    return buildPath(start, goal, cameFrom);\n}\n\nexport function dijkstraSearch(\n    graph: Graph,\n    start: number,\n    goal: number,\n) {\n    interface CostNode {\n        cost: number;\n        node: number;\n    }\n    const frontier = new BinaryHeap<CostNode>();\n    frontier.insert({ cost: 0, node: start });\n\n    const cameFrom = new Map<number, number>();\n    cameFrom.set(start, start);\n    const costSoFar = new Map<number, number>();\n    costSoFar.set(start, 0);\n\n    while (frontier.length !== 0) {\n        const current = frontier.remove()?.node;\n\n        if (current === goal) {\n            break;\n        }\n\n        // TODO: Remove non-null assertion\n        const neighbours = graph.getNeighbours(current!);\n        for (let next of neighbours) {\n            const newCost = (costSoFar.get(current!) || 0)\n                + graph.getCost(current!, next);\n            if (\n                !costSoFar.has(next)\n                || newCost < costSoFar.get(next)!\n            ) {\n                costSoFar.set(next, newCost);\n                frontier.insert({ cost: newCost, node: next });\n                cameFrom.set(next, current!);\n            }\n        }\n    }\n\n    return buildPath(start, goal, cameFrom);\n}\n\nexport function aStarSearch(\n    graph: Graph,\n    start: number,\n    goal: number,\n): number[] {\n    interface CostNode {\n        cost: number;\n        node: number;\n    }\n    const frontier = new BinaryHeap<CostNode>((a, b) => a.cost < b.cost);\n    frontier.insert({ cost: 0, node: start });\n\n    const cameFrom = new Map<number, number>();\n    cameFrom.set(start, start);\n    const costSoFar = new Map<number, number>();\n    costSoFar.set(start, 0);\n\n    while (frontier.length !== 0) {\n        const current = frontier.remove()?.node;\n\n        if (current === goal) {\n            break;\n        }\n\n        // TODO: Remove non-null assertion\n        const neighbours = graph.getNeighbours(current!);\n        for (let next of neighbours) {\n            const newCost = (costSoFar.get(current!) || 0)\n                + graph.getCost(current!, next)\n                + graph.getHeuristic(next, goal);\n            if (\n                !costSoFar.has(next)\n                || newCost < costSoFar.get(next)!\n            ) {\n                costSoFar.set(next, newCost);\n                frontier.insert({ cost: newCost, node: next });\n                cameFrom.set(next, current!);\n            }\n        }\n    }\n\n    // TODO: Remove non-null assertion\n    return buildPath(start, goal, cameFrom)!;\n}\n", "import { Vec2, vec2 } from \"./math\";\nimport { aStarSearch, type Graph } from \"./navigation\";\n\nclass NavEdge {\n    a: Vec2;\n    b: Vec2;\n    polygon: WeakRef<NavPolygon>;\n\n    constructor(a: Vec2, b: Vec2, polygon: NavPolygon) {\n        this.a = a;\n        this.b = b;\n        this.polygon = new WeakRef(polygon);\n    }\n\n    isLeft(x: number, y: number) {\n        return ((this.b.x - this.a.x) * (y - this.a.y)\n            - (x - this.a.x) * (this.b.y - this.a.y));\n    }\n\n    get middle() {\n        return this.a.add(this.b).scale(0.5);\n    }\n}\n\nclass NavPolygon {\n    // I don't know if set a default affects how the code is did\n    // TODO: Remove non-null assertion\n    private _edges!: NavEdge[];\n    private _centroid!: Vec2;\n    private _id: number;\n\n    constructor(id: number) {\n        this._id = id;\n    }\n\n    get id() {\n        return this._id;\n    }\n\n    set edges(edges: NavEdge[]) {\n        this._edges = edges;\n        let centerX = 0;\n        let centerY = 0;\n        let area = 0;\n        for (let edge of this._edges) {\n            edge.polygon = new WeakRef(this);\n            const cross = edge.a.x * edge.b.y - edge.a.y * edge.b.x;\n            centerX += (edge.a.x + edge.b.x) * cross;\n            centerY += (edge.a.y + edge.b.y) * cross;\n            area += cross;\n        }\n        area /= 2;\n        this._centroid = vec2(centerX / (6 * area), centerY / (6 * area));\n    }\n\n    get edges(): NavEdge[] {\n        return this._edges;\n    }\n\n    get centroid(): Vec2 {\n        return this._centroid;\n    }\n\n    // https://web.archive.org/web/20130126163405/http://geomalgorithms.com/a03-_inclusion.html\n    /*contains(x: number, y: number) {\n        let wn = 0;\n\n        for (let edge of this._edges) {\n            if (edge.a.y <= y) {\n                if (edge.b.y > y) {\n                    if (edge.isLeft(x, y) > 0) {\n                        ++wn;\n                    }\n                }\n            } else {\n                if (edge.b.y <= y) {\n                    if (edge.isLeft(x, y) < 0) {\n                        --wn;\n                    }\n                }\n            }\n        }\n        return wn;\n    }*/\n\n    contains(p: Vec2) {\n        let c = false;\n\n        for (const e of this.edges) {\n            if (\n                ((e.b.y > p.y) != (e.a.y > p.y))\n                && (p.x\n                    < (e.a.x - e.b.x) * (p.y - e.b.y) / (e.a.y - e.b.y) + e.b.x)\n            ) {\n                c = !c;\n            }\n        }\n\n        return c;\n    }\n}\n\nexport class NavMesh implements Graph {\n    private _polygons: NavPolygon[];\n    private _pointCache: { [key: string]: Vec2 };\n    private _edgeCache: { [key: string]: NavEdge };\n\n    constructor() {\n        this._polygons = [];\n        this._pointCache = {};\n        this._edgeCache = {};\n    }\n\n    private _addPoint(p: Vec2) {\n        let point = this._pointCache[`${p.x}_${p.y}`];\n        if (point) {\n            return point;\n        }\n        point = p.clone();\n        this._pointCache[`${p.x}_${p.y}`] = point;\n        return point;\n    }\n\n    private _addEdge(edge: NavEdge): NavEdge {\n        const key = `${edge.a.x}_${edge.a.y}-${edge.b.x}_${edge.b.y}`;\n        this._edgeCache[key] = edge;\n        return edge;\n    }\n\n    private _findEdge(a: Vec2, b: Vec2) {\n        const key = `${a.x}_${a.y}-${b.x}_${b.y}`;\n        return this._edgeCache[key];\n    }\n\n    private _findCommonEdge(a: NavPolygon, b: NavPolygon): NavEdge | null {\n        for (const edge of a.edges) {\n            const e = this._findEdge(edge.b, edge.a);\n            // TODO: Remove non-null assertion\n            if (e && e.polygon.deref()!.id === b.id) {\n                return e;\n            }\n        }\n        return null;\n    }\n\n    addPolygon(vertices: Vec2[]) {\n        const polygon = new NavPolygon(this._polygons.length);\n        const edges = vertices.map((v, index) =>\n            new NavEdge(v, vertices[(index + 1) % vertices.length], polygon)\n        );\n        polygon.edges = edges;\n        this._polygons.push(polygon);\n        for (const edge of polygon.edges) {\n            this._addEdge(edge);\n        }\n        return polygon;\n    }\n\n    addRect(pos: Vec2, size: Vec2) {\n        const a = this._addPoint(pos);\n        const b = this._addPoint(pos.add(size.x, 0));\n        const c = this._addPoint(pos.add(size));\n        const d = this._addPoint(pos.add(0, size.y));\n        return this.addPolygon([a, b, c, d]);\n    }\n\n    private _getLocation(p: Vec2): NavPolygon | null {\n        for (let polygon of this._polygons) {\n            if (polygon.contains(p)) {\n                return polygon;\n            }\n        }\n        return null;\n    }\n\n    getNeighbours(index: number): number[] {\n        const neighbours = [];\n        for (let edge of this._polygons[index].edges) {\n            // Lookup polygons with reverse edge\n            const pairEdge = this._findEdge(edge.b, edge.a);\n            if (pairEdge) {\n                const pairPolygon = pairEdge.polygon.deref();\n                if (pairPolygon) {\n                    neighbours.push(pairPolygon.id);\n                }\n            }\n        }\n        return neighbours;\n    }\n\n    getCost(a: number, b: number) {\n        return 1;\n    }\n\n    getHeuristic(indexA: number, indexB: number) {\n        const a = this._polygons[indexA];\n        const b = this._polygons[indexB];\n        const x = a.centroid.x - b.centroid.x;\n        const y = a.centroid.y - b.centroid.y;\n        return Math.sqrt(x * x + y * y);\n    }\n\n    getPath(start: number, goal: number): number[] {\n        // Points are not within the navigation mesh\n        if (start === undefined || goal === undefined) {\n            return [];\n        }\n\n        // Same polygon\n        if (start === goal) {\n            return [start, goal];\n        }\n\n        return aStarSearch(this, start, goal);\n    }\n\n    getWaypointPath(start: Vec2, goal: Vec2, opt: any): Vec2[] {\n        const type = opt?.type || \"centroids\";\n\n        const startPolygon = this._getLocation(start);\n        const goalPolygon = this._getLocation(goal);\n\n        // Points are not within the navigation mesh\n        if (startPolygon === undefined || goalPolygon === undefined) {\n            return [];\n        }\n\n        // TODO: Remove non-null assertion\n        const path = this.getPath(startPolygon!.id, goalPolygon!.id);\n\n        // No path was found\n        if (!path) {\n            return [];\n        }\n\n        if (type === \"edges\") {\n            const edges = [];\n            for (let i = 1; i < path.length; i++) {\n                const p1 = this._polygons[path[i - 1]];\n                const p2 = this._polygons[path[i]];\n                const edge = this._findCommonEdge(p1, p2);\n                // TODO: Remove non-null assertion\n                edges.push(\n                    edge!.middle.add(\n                        p2.centroid.sub(edge!.middle).unit().scale(4),\n                    ),\n                );\n            }\n            return [start, ...edges, goal];\n        }\n        else { // type === \"centroids\"\n            return [\n                start,\n                ...path.slice(1, -1).map(index =>\n                    this._polygons[index].centroid\n                ),\n                goal,\n            ];\n        }\n    }\n}\n", "import { height, width } from \"../gfx\";\nimport type { GameObj } from \"../types\";\nimport { deg2rad, Mat4, Vec2, vec2 } from \"./math\";\n\nexport function calcTransform(obj: GameObj): Mat4 {\n    const tr = new Mat4();\n    if (obj.pos) tr.translate(obj.pos);\n    if (obj.scale) tr.scale(obj.scale);\n    if (obj.angle) tr.rotate(obj.angle);\n    return obj.parent ? tr.mult(obj.parent.transform) : tr;\n}\n\n// convert a screen space coordinate to webgl normalized device coordinate\nexport function screen2ndc(pt: Vec2): Vec2 {\n    return new Vec2(\n        pt.x / width() * 2 - 1,\n        -pt.y / height() * 2 + 1,\n    );\n}\n\nexport function getArcPts(\n    pos: Vec2,\n    radiusX: number,\n    radiusY: number,\n    start: number,\n    end: number,\n    res: number = 1,\n): Vec2[] {\n    // normalize and turn start and end angles to radians\n    start = deg2rad(start % 360);\n    end = deg2rad(end % 360);\n    if (end <= start) end += Math.PI * 2;\n\n    const pts: Vec2[] = [];\n    const nverts = Math.ceil((end - start) / deg2rad(8) * res);\n    const step = (end - start) / nverts;\n\n    // Rotate vector v by r nverts+1 times\n    let v = vec2(Math.cos(start), Math.sin(start));\n    const r = vec2(Math.cos(step), Math.sin(step));\n    for (let i = 0; i <= nverts; i++) {\n        pts.push(pos.add(radiusX * v.x, radiusY * v.y));\n        // cos(a + b) = cos(a)cos(b) - sin(a)sin(b)\n        // sin(a + b) = cos(a)sin(b) + sin(a)cos(b)\n        v = vec2(v.x * r.x - v.y * r.y, v.x * r.y + v.y * r.x);\n    }\n\n    return pts;\n}\n", "import { _k } from \"../kaplay\";\nimport { type ColorArgs, rgb } from \"../math\";\n\nexport function setBackground(...args: ColorArgs) {\n    const color = rgb(...args);\n    const alpha = args[3] ?? 1;\n\n    _k.gfx.bgColor = color;\n    _k.gfx.bgAlpha = alpha;\n\n    _k.gfx.ggl.gl.clearColor(\n        color.r / 255,\n        color.g / 255,\n        color.b / 255,\n        alpha,\n    );\n}\n\nexport function getBackground() {\n    return _k.gfx.bgColor?.clone?.() ?? null;\n}\n", "import { _k } from \"../kaplay\";\nimport { type Mat4, Vec2, vec2, type Vec2Args } from \"../math/math\";\n\nexport function pushTranslate(...args: Vec2Args | [undefined]) {\n    if (args[0] === undefined) return;\n\n    const p = vec2(...args);\n    if (p.x === 0 && p.y === 0) return;\n    _k.gfx.transform.translate(p);\n}\n\nexport function pushTransform() {\n    _k.gfx.transformStack.push(_k.gfx.transform.clone());\n}\n\nexport function pushMatrix(m: Mat4) {\n    _k.gfx.transform = m.clone();\n}\n\nexport function pushScale(\n    ...args: Vec2Args | [undefined] | [undefined, undefined]\n) {\n    if (args[0] === undefined) return;\n\n    const p = vec2(...args);\n    if (p.x === 1 && p.y === 1) return;\n    _k.gfx.transform.scale(p);\n}\n\nexport function pushRotate(a: number | undefined) {\n    if (!a) return;\n\n    _k.gfx.transform.rotate(a);\n}\n\nexport function popTransform() {\n    if (_k.gfx.transformStack.length > 0) {\n        // if there's more than 1 element, it will return obviously a Mat4\n        _k.gfx.transform = _k.gfx.transformStack.pop()!;\n    }\n}\n\nexport function flush() {\n    _k.gfx.renderer.flush();\n}\n\n// get game width\nexport function width(): number {\n    return _k.gfx.width;\n}\n\n// get game height\nexport function height(): number {\n    return _k.gfx.height;\n}\n\nexport function getViewportScale() {\n    return (_k.gfx.viewport.width + _k.gfx.viewport.height)\n        / (_k.gfx.width + _k.gfx.height);\n}\n\n// transform a point from content space to view space\nexport function contentToView(pt: Vec2) {\n    return new Vec2(\n        pt.x * _k.gfx.viewport.width / _k.gfx.width,\n        pt.y * _k.gfx.viewport.height / _k.gfx.height,\n    );\n}\n\n// transform a point from window space to content space\nexport function windowToContent(pt: Vec2) {\n    return new Vec2(\n        (pt.x - _k.gfx.viewport.x) * width() / _k.gfx.viewport.width,\n        (pt.y - _k.gfx.viewport.y) * height() / _k.gfx.viewport.height,\n    );\n}\n\nexport function center(): Vec2 {\n    return vec2(width() / 2, height() / 2);\n}\n", "import { type GfxCtx, Texture } from \"../gfx\";\nimport { Quad, Vec2 } from \"../math/math\";\nimport type { ImageSource } from \"../types\";\n\nexport class TexPacker {\n    private lastTextureId: number = 0;\n    private textures: Texture[] = [];\n    private bigTextures: Texture[] = [];\n    private texturesPosition: Map<number, {\n        position: Vec2;\n        size: Vec2;\n        texture: Texture;\n    }> = new Map();\n    private canvas: HTMLCanvasElement;\n    private c2d: CanvasRenderingContext2D;\n    private x: number = 0;\n    private y: number = 0;\n    private curHeight: number = 0;\n    private gfx: GfxCtx;\n    private padding: number;\n\n    constructor(gfx: GfxCtx, w: number, h: number, padding: number) {\n        this.gfx = gfx;\n        this.canvas = document.createElement(\"canvas\");\n        this.canvas.width = w;\n        this.canvas.height = h;\n        this.textures = [Texture.fromImage(gfx, this.canvas)];\n        this.bigTextures = [];\n        this.padding = padding;\n\n        const context2D = this.canvas.getContext(\"2d\");\n        if (!context2D) throw new Error(\"Failed to get 2d context\");\n\n        this.c2d = context2D;\n    }\n\n    // create a image with a single texture\n    addSingle(img: ImageSource): [Texture, Quad, number] {\n        const tex = Texture.fromImage(this.gfx, img);\n        this.bigTextures.push(tex);\n        return [tex, new Quad(0, 0, 1, 1), 0];\n    }\n\n    add(img: ImageSource): [Texture, Quad, number] {\n        const paddedWidth = img.width + this.padding * 2;\n        const paddedHeight = img.height + this.padding * 2;\n\n        if (\n            paddedWidth > this.canvas.width || paddedHeight > this.canvas.height\n        ) {\n            return this.addSingle(img);\n        }\n\n        // next row\n        if (this.x + paddedWidth > this.canvas.width) {\n            this.x = 0;\n            this.y += this.curHeight;\n            this.curHeight = 0;\n        }\n\n        // next texture\n        if (this.y + paddedHeight > this.canvas.height) {\n            this.c2d.clearRect(0, 0, this.canvas.width, this.canvas.height);\n            this.textures.push(Texture.fromImage(this.gfx, this.canvas));\n            this.x = 0;\n            this.y = 0;\n            this.curHeight = 0;\n        }\n\n        const curTex = this.textures[this.textures.length - 1];\n        const pos = new Vec2(this.x + this.padding, this.y + this.padding);\n\n        this.x += paddedWidth;\n\n        if (paddedHeight > this.curHeight) {\n            this.curHeight = paddedHeight;\n        }\n\n        if (img instanceof ImageData) {\n            this.c2d.putImageData(img, pos.x, pos.y);\n        }\n        else {\n            this.c2d.drawImage(img, pos.x, pos.y);\n        }\n\n        curTex.update(this.canvas);\n\n        this.texturesPosition.set(this.lastTextureId, {\n            position: pos,\n            size: new Vec2(img.width, img.height),\n            texture: curTex,\n        });\n\n        this.lastTextureId++;\n\n        return [\n            curTex,\n            new Quad(\n                pos.x / this.canvas.width,\n                pos.y / this.canvas.height,\n                img.width / this.canvas.width,\n                img.height / this.canvas.height,\n            ),\n            this.lastTextureId - 1,\n        ];\n    }\n    free() {\n        for (const tex of this.textures) {\n            tex.free();\n        }\n        for (const tex of this.bigTextures) {\n            tex.free();\n        }\n    }\n}\n", "import { _k } from \"../kaplay\";\nimport { isDataURL } from \"../utils\";\n\nexport function fixURL<D>(url: D): D {\n    if (typeof url !== \"string\" || isDataURL(url)) return url;\n    return _k.assets.urlPrefix + url as D;\n}\n", "import { SPRITE_ATLAS_HEIGHT, SPRITE_ATLAS_WIDTH } from \"../constants\";\nimport type { GfxCtx } from \"../gfx/gfx\";\nimport { TexPacker } from \"../gfx/texPacker\";\nimport { _k } from \"../kaplay\";\nimport { KEvent } from \"../utils\";\nimport type { BitmapFontData } from \"./bitmapFont\";\nimport type { FontData } from \"./font\";\nimport type { ShaderData } from \"./shader\";\nimport type { SoundData } from \"./sound\";\nimport type { SpriteData } from \"./sprite\";\nimport { fixURL } from \"./utils\";\n\n/**\n * An asset is a resource that is loaded asynchronously.\n */\nexport class Asset<D> {\n    loaded: boolean = false;\n    data: D | null = null;\n    error: Error | null = null;\n    private onLoadEvents: KEvent<[D]> = new KEvent();\n    private onErrorEvents: KEvent<[Error]> = new KEvent();\n    private onFinishEvents: KEvent<[]> = new KEvent();\n    constructor(loader: Promise<D>) {\n        loader.then((data) => {\n            this.loaded = true;\n            this.data = data;\n            this.onLoadEvents.trigger(data);\n        }).catch((err) => {\n            this.error = err;\n            if (this.onErrorEvents.numListeners() > 0) {\n                this.onErrorEvents.trigger(err);\n            }\n            else {\n                throw err;\n            }\n        }).finally(() => {\n            this.onFinishEvents.trigger();\n            this.loaded = true;\n        });\n    }\n    static loaded<D>(data: D): Asset<D> {\n        const asset = new Asset(Promise.resolve(data)) as Asset<D>;\n        asset.data = data;\n        asset.loaded = true;\n        return asset;\n    }\n    onLoad(action: (data: D) => void) {\n        if (this.loaded && this.data) {\n            action(this.data);\n        }\n        else {\n            this.onLoadEvents.add(action);\n        }\n        return this;\n    }\n    onError(action: (err: Error) => void) {\n        if (this.loaded && this.error) {\n            action(this.error);\n        }\n        else {\n            this.onErrorEvents.add(action);\n        }\n        return this;\n    }\n    onFinish(action: () => void) {\n        if (this.loaded) {\n            action();\n        }\n        else {\n            this.onFinishEvents.add(action);\n        }\n        return this;\n    }\n    then(action: (data: D) => void): Asset<D> {\n        return this.onLoad(action);\n    }\n    catch(action: (err: Error) => void): Asset<D> {\n        return this.onError(action);\n    }\n    finally(action: () => void): Asset<D> {\n        return this.onFinish(action);\n    }\n}\n\nexport class AssetBucket<D> {\n    assets: Map<string, Asset<D>> = new Map();\n    lastUID: number = 0;\n    add(name: string | null, loader: Promise<D>): Asset<D> {\n        // if user don't provide a name we use a generated one\n        const id = name ?? (this.lastUID++ + \"\");\n        const asset = new Asset(loader);\n        this.assets.set(id, asset);\n        return asset;\n    }\n    addLoaded(name: string | null, data: D): Asset<D> {\n        const id = name ?? (this.lastUID++ + \"\");\n        const asset = Asset.loaded(data);\n        this.assets.set(id, asset);\n        return asset;\n    }\n    // if not found return undefined\n    get(handle: string): Asset<D> | undefined {\n        return this.assets.get(handle);\n    }\n    progress(): number {\n        if (this.assets.size === 0) {\n            return 1;\n        }\n        let loaded = 0;\n        this.assets.forEach((asset) => {\n            if (asset.loaded) {\n                loaded++;\n            }\n        });\n        return loaded / this.assets.size;\n    }\n\n    getFailedAssets(): [string, Asset<D>][] {\n        return Array.from(this.assets.keys()).filter(a =>\n            this.assets.get(a)!.error !== null\n        ).map(a => [a, this.assets.get(a)!]);\n    }\n}\n\nexport function fetchURL(url: string) {\n    return fetch(url)\n        .then((res) => {\n            if (!res.ok) throw new Error(`Failed to fetch \"${url}\"`);\n            return res;\n        });\n}\n\nexport function fetchJSON(path: string) {\n    return fetchURL(path).then((res) => res.json());\n}\n\nexport function fetchText(path: string) {\n    return fetchURL(path).then((res) => res.text());\n}\n\nexport function fetchArrayBuffer(path: string) {\n    return fetchURL(path).then((res) => res.arrayBuffer());\n}\n\n// global load path prefix\nexport function loadRoot(path?: string): string {\n    if (path !== undefined) {\n        _k.assets.urlPrefix = path;\n    }\n    return _k.assets.urlPrefix;\n}\n\nexport function loadJSON(name: string, url: string) {\n    return _k.assets.custom.add(name, fetchJSON(fixURL(url)));\n}\n\n// wrapper around image loader to get a Promise\nexport function loadImg(src: string): Promise<HTMLImageElement> {\n    const img = new Image();\n    img.crossOrigin = \"anonymous\";\n    img.src = src;\n    return new Promise<HTMLImageElement>((resolve, reject) => {\n        img.onload = () => resolve(img);\n        img.onerror = () =>\n            reject(new Error(`Failed to load image from \"${src}\"`));\n    });\n}\n\nexport function loadProgress(): number {\n    const buckets = [\n        _k.assets.sprites,\n        _k.assets.sounds,\n        _k.assets.shaders,\n        _k.assets.fonts,\n        _k.assets.bitmapFonts,\n        _k.assets.custom,\n    ];\n    return buckets.reduce((n, bucket) => n + bucket.progress(), 0)\n        / buckets.length;\n}\n\nexport function getFailedAssets(): [string, Asset<any>][] {\n    const buckets = [\n        _k.assets.sprites,\n        _k.assets.sounds,\n        _k.assets.shaders,\n        _k.assets.fonts,\n        _k.assets.bitmapFonts,\n        _k.assets.custom,\n    ];\n    return buckets.reduce(\n        (fails, bucket) => fails.concat(bucket.getFailedAssets()),\n        [] as [string, Asset<any>][],\n    );\n}\nexport function getAsset(name: string): Asset<any> | null {\n    return _k.assets.custom.get(name) ?? null;\n}\n\n// wrap individual loaders with global loader counter, for stuff like progress bar\nexport function load<T>(prom: Promise<T>): Asset<T> {\n    return _k.assets.custom.add(null, prom);\n}\n\n// create assets\nexport type AssetsCtx = ReturnType<typeof initAssets>;\n\nexport const initAssets = (ggl: GfxCtx, spriteAtlasPadding: number) => {\n    const assets = {\n        urlPrefix: \"\",\n        // asset holders\n        sprites: new AssetBucket<SpriteData>(),\n        fonts: new AssetBucket<FontData>(),\n        bitmapFonts: new AssetBucket<BitmapFontData>(),\n        sounds: new AssetBucket<SoundData>(),\n        shaders: new AssetBucket<ShaderData>(),\n        custom: new AssetBucket<any>(),\n        music: {} as Record<string, string>,\n        packer: new TexPacker(\n            ggl,\n            SPRITE_ATLAS_WIDTH,\n            SPRITE_ATLAS_HEIGHT,\n            spriteAtlasPadding,\n        ),\n        // if we finished initially loading all assets\n        loaded: false,\n    };\n\n    return assets;\n};\n", "import { Asset, loadImg, loadProgress } from \"../assets\";\nimport type { DrawSpriteOpt } from \"../gfx\";\nimport type { Texture } from \"../gfx/gfx\";\nimport { _k } from \"../kaplay\";\nimport beanSpriteSrc from \"../kassets/bean.png\";\nimport { Quad } from \"../math/math\";\nimport { type ImageSource } from \"../types\";\nimport { fixURL } from \"./utils\";\n\n/**\n * Frame-based animation configuration.\n */\nexport type SpriteAnim = number | {\n    /**\n     * The starting frame.\n     */\n    from?: number;\n    /**\n     * The end frame.\n     */\n    to?: number;\n    /**\n     * If this anim should be played in loop.\n     */\n    loop?: boolean;\n    /**\n     * When looping should it move back instead of go to start frame again.\n     */\n    pingpong?: boolean;\n    /**\n     * This anim's speed in frames per second.\n     */\n    speed?: number;\n    /**\n     * List of frames for the animation.\n     *\n     * If this property exists, **from, to, and pingpong will be ignored**.\n     */\n    frames?: number[];\n};\n\n/**\n * A dict of name <-> animation.\n */\nexport type SpriteAnims = Record<string, SpriteAnim>;\n\n// TODO: support frameWidth and frameHeight as alternative to slice\n/**\n * Sprite loading configuration.\n */\nexport interface LoadSpriteOpt {\n    /**\n     * If the defined area contains multiple sprites, how many frames are in the area horizontally.\n     */\n    sliceX?: number;\n    /**\n     * If the defined area contains multiple sprites, how many frames are in the area vertically.\n     */\n    sliceY?: number;\n    /**\n     * 9 slice sprite for proportional scaling.\n     *\n     * @since v3000.0\n     */\n    slice9?: NineSlice;\n    /**\n     * Individual frames.\n     *\n     * @since v3000.0\n     */\n    frames?: Quad[];\n    /**\n     * Animation configuration.\n     */\n    anims?: SpriteAnims;\n    /**\n     * If the sprite is a single image.\n     */\n    singular?: boolean;\n}\n\nexport type NineSlice = {\n    /**\n     * The width of the 9-slice's left column.\n     */\n    left: number;\n    /**\n     * The width of the 9-slice's right column.\n     */\n    right: number;\n    /**\n     * The height of the 9-slice's top row.\n     */\n    top: number;\n    /**\n     * The height of the 9-slice's bottom row.\n     */\n    bottom: number;\n};\n\nexport type LoadSpriteSrc = string | ImageSource;\n\nexport class SpriteData {\n    tex: Texture;\n    frames: Quad[] = [new Quad(0, 0, 1, 1)];\n    anims: SpriteAnims = {};\n    slice9: NineSlice | null = null;\n\n    constructor(\n        tex: Texture,\n        frames?: Quad[],\n        anims: SpriteAnims = {},\n        slice9: NineSlice | null = null,\n    ) {\n        this.tex = tex;\n        if (frames) this.frames = frames;\n        this.anims = anims;\n        this.slice9 = slice9;\n    }\n\n    /**\n     * @since v3001.0\n     */\n    get width() {\n        return this.tex.width * this.frames[0].w;\n    }\n\n    get height() {\n        return this.tex.height * this.frames[0].h;\n    }\n\n    static from(\n        src: LoadSpriteSrc,\n        opt: LoadSpriteOpt = {},\n    ): Promise<SpriteData> {\n        return typeof src === \"string\"\n            ? SpriteData.fromURL(src, opt)\n            : Promise.resolve(SpriteData.fromImage(src, opt));\n    }\n\n    static fromImage(\n        data: ImageSource,\n        opt: LoadSpriteOpt = {},\n    ): SpriteData {\n        const [tex, quad] = opt.singular\n            ? _k.assets.packer.addSingle(data)\n            : _k.assets.packer.add(data);\n        const frames = opt.frames\n            ? opt.frames.map((f) =>\n                new Quad(\n                    quad.x + f.x * quad.w,\n                    quad.y + f.y * quad.h,\n                    f.w * quad.w,\n                    f.h * quad.h,\n                )\n            )\n            : slice(\n                opt.sliceX || 1,\n                opt.sliceY || 1,\n                quad.x,\n                quad.y,\n                quad.w,\n                quad.h,\n            );\n        return new SpriteData(tex, frames, opt.anims, opt.slice9);\n    }\n\n    static fromURL(\n        url: string,\n        opt: LoadSpriteOpt = {},\n    ): Promise<SpriteData> {\n        return loadImg(url).then((img) => SpriteData.fromImage(img, opt));\n    }\n}\n\nexport function resolveSprite(\n    src: DrawSpriteOpt[\"sprite\"],\n): Asset<SpriteData> | null {\n    if (typeof src === \"string\") {\n        const spr = getSprite(src);\n        if (spr) {\n            // if it's already loaded or being loading, return it\n            return spr;\n        }\n        else if (loadProgress() < 1) {\n            // if there's any other ongoing loading task we return empty and don't error yet\n            return null;\n        }\n        else {\n            // if all other assets are loaded and we still haven't found this sprite, throw\n            throw new Error(`Sprite not found: ${src}`);\n        }\n    }\n    else if (src instanceof SpriteData) {\n        return Asset.loaded(src);\n    }\n    else if (src instanceof Asset) {\n        return src;\n    }\n    else {\n        throw new Error(`Invalid sprite: ${src}`);\n    }\n}\n\nexport function getSprite(name: string): Asset<SpriteData> | null {\n    return _k.assets.sprites.get(name) ?? null;\n}\n\n// load a sprite to asset manager\nexport function loadSprite(\n    name: string | null,\n    src: LoadSpriteSrc | LoadSpriteSrc[],\n    opt: LoadSpriteOpt = {\n        sliceX: 1,\n        sliceY: 1,\n        anims: {},\n    },\n): Asset<SpriteData> {\n    src = fixURL(src);\n    if (Array.isArray(src)) {\n        if (src.some((s) => typeof s === \"string\")) {\n            return _k.assets.sprites.add(\n                name,\n                Promise.all(src.map((s) => {\n                    return typeof s === \"string\"\n                        ? loadImg(s)\n                        : Promise.resolve(s);\n                })).then((images) => createSpriteSheet(images, opt)),\n            );\n        }\n        else {\n            return _k.assets.sprites.addLoaded(\n                name,\n                createSpriteSheet(src as ImageSource[], opt),\n            );\n        }\n    }\n    else {\n        if (typeof src === \"string\") {\n            return _k.assets.sprites.add(name, SpriteData.from(src, opt));\n        }\n        else {\n            return _k.assets.sprites.addLoaded(\n                name,\n                SpriteData.fromImage(src, opt),\n            );\n        }\n    }\n}\n\nexport function slice(x = 1, y = 1, dx = 0, dy = 0, w = 1, h = 1): Quad[] {\n    const frames: Quad[] = [];\n    const qw = w / x;\n    const qh = h / y;\n    for (let j = 0; j < y; j++) {\n        for (let i = 0; i < x; i++) {\n            frames.push(\n                new Quad(\n                    dx + i * qw,\n                    dy + j * qh,\n                    qw,\n                    qh,\n                ),\n            );\n        }\n    }\n    return frames;\n}\n\n// TODO: load synchronously if passed ImageSource\n\nexport function createSpriteSheet(\n    images: ImageSource[],\n    opt: LoadSpriteOpt = {},\n): SpriteData {\n    const canvas = document.createElement(\"canvas\");\n    const width = images[0].width;\n    const height = images[0].height;\n    canvas.width = width * images.length;\n    canvas.height = height;\n    const c2d = canvas.getContext(\"2d\");\n    if (!c2d) throw new Error(\"Failed to create canvas context\");\n    images.forEach((img, i) => {\n        if (img instanceof ImageData) {\n            c2d.putImageData(img, i * width, 0);\n        }\n        else {\n            c2d.drawImage(img, i * width, 0);\n        }\n    });\n    const merged = c2d.getImageData(0, 0, images.length * width, height);\n    return SpriteData.fromImage(merged, {\n        ...opt,\n        sliceX: images.length,\n        sliceY: 1,\n    });\n}\n\nexport function loadBean(name: string = \"bean\"): Asset<SpriteData> {\n    return loadSprite(name, beanSpriteSrc);\n}\n", "import { _k } from \"../kaplay\";\nimport { Quad } from \"../math\";\nimport { getFileName } from \"../utils\";\nimport { type Asset, fetchJSON } from \"./asset\";\nimport { type LoadSpriteSrc, type SpriteAnim, SpriteData } from \"./sprite\";\nimport { fixURL } from \"./utils\";\n\nexport type AsepriteData = {\n    frames: Array<{\n        frame: {\n            x: number;\n            y: number;\n            w: number;\n            h: number;\n        };\n    }>;\n    meta: {\n        size: { w: number; h: number };\n        frameTags: Array<{\n            name: string;\n            from: number;\n            to: number;\n            direction: \"forward\" | \"reverse\" | \"pingpong\";\n        }>;\n    };\n};\n\nexport function loadAseprite(\n    name: string | null,\n    imgSrc: LoadSpriteSrc,\n    jsonSrc: string | AsepriteData,\n): Asset<SpriteData> {\n    imgSrc = fixURL(imgSrc);\n    jsonSrc = fixURL(jsonSrc);\n\n    if (typeof imgSrc === \"string\" && !jsonSrc) {\n        jsonSrc = getFileName(imgSrc) + \".json\";\n    }\n\n    const resolveJSON = typeof jsonSrc === \"string\"\n        ? fetchJSON(jsonSrc)\n        : Promise.resolve(jsonSrc);\n\n    return _k.assets.sprites.add(\n        name,\n        resolveJSON.then((data: AsepriteData) => {\n            const size = data.meta.size;\n            const frames = data.frames.map((f: any) => {\n                return new Quad(\n                    f.frame.x / size.w,\n                    f.frame.y / size.h,\n                    f.frame.w / size.w,\n                    f.frame.h / size.h,\n                );\n            });\n            const anims: Record<string, number | SpriteAnim> = {};\n\n            for (const anim of data.meta.frameTags) {\n                if (anim.from === anim.to) {\n                    anims[anim.name] = anim.from;\n                }\n                else {\n                    anims[anim.name] = {\n                        from: anim.from,\n                        to: anim.to,\n                        speed: 10,\n                        loop: true,\n                        pingpong: anim.direction === \"pingpong\",\n                    };\n                }\n            }\n            return SpriteData.from(imgSrc, {\n                frames: frames,\n                anims: anims,\n            });\n        }),\n    );\n}\n", "import {\n    DEF_FONT,\n    DEF_FONT_FILTER,\n    DEF_TEXT_CACHE_SIZE,\n    MAX_TEXT_CACHE_SIZE,\n} from \"../constants\";\nimport type { Texture } from \"../gfx\";\nimport type { DrawTextOpt } from \"../gfx/draw/drawText\";\nimport { _k } from \"../kaplay\";\nimport { rgb } from \"../math/color\";\nimport { Quad } from \"../math/math\";\nimport type { LoadFontOpt, Outline, TexFilter } from \"../types\";\nimport { Asset, loadProgress } from \"./asset\";\nimport { type BitmapFontData, getBitmapFont, type GfxFont } from \"./bitmapFont\";\nimport { fixURL } from \"./utils\";\n\nexport class FontData {\n    fontface: FontFace;\n    filter: TexFilter = DEF_FONT_FILTER;\n    outline: Outline | null = null;\n    size: number = DEF_TEXT_CACHE_SIZE;\n    constructor(face: FontFace, opt: LoadFontOpt = {}) {\n        this.fontface = face;\n        this.filter = opt.filter ?? DEF_FONT_FILTER;\n        this.size = opt.size ?? DEF_TEXT_CACHE_SIZE;\n        if (this.size > MAX_TEXT_CACHE_SIZE) {\n            throw new Error(`Max font size: ${MAX_TEXT_CACHE_SIZE}`);\n        }\n        if (opt.outline) {\n            this.outline = {\n                width: 1,\n                color: rgb(0, 0, 0),\n            };\n            if (typeof opt.outline === \"number\") {\n                this.outline.width = opt.outline;\n            }\n            else if (typeof opt.outline === \"object\") {\n                if (opt.outline.width) {\n                    this.outline.width = opt.outline.width;\n                }\n                if (opt.outline.color) {\n                    this.outline.color = opt.outline.color;\n                }\n            }\n        }\n    }\n}\n\nexport function resolveFont(\n    src: DrawTextOpt[\"font\"],\n):\n    | FontData\n    | Asset<FontData>\n    | BitmapFontData\n    | Asset<BitmapFontData>\n    | string\n    | null\n    | void\n{\n    if (!src) {\n        return resolveFont(_k.globalOpt.font ?? DEF_FONT);\n    }\n    if (typeof src === \"string\") {\n        const bfont = getBitmapFont(src);\n        const font = getFont(src);\n        if (bfont) {\n            return bfont.data ?? bfont;\n        }\n        else if (font) {\n            return font.data ?? font;\n        }\n        else if (\n            document.fonts.check(`${DEF_TEXT_CACHE_SIZE}px ${src}`)\n        ) {\n            return src;\n        }\n        else if (loadProgress() < 1) {\n            return null;\n        }\n        else {\n            throw new Error(`Font not found: ${src}`);\n        }\n    }\n    else if (src instanceof Asset) {\n        return src.data ? src.data : src;\n    }\n\n    return src;\n}\n\nexport function getFont(name: string): Asset<FontData> | null {\n    return _k.assets.fonts.get(name) ?? null;\n}\n\n// TODO: pass in null src to store opt for default fonts like \"monospace\"\nexport function loadFont(\n    name: string,\n    src: string | BinaryData,\n    opt: LoadFontOpt = {},\n): Asset<FontData> {\n    const fontSrc = fixURL(src);\n    const font = new FontFace(\n        name,\n        typeof src === \"string\" ? `url(${fontSrc})` : fontSrc,\n    );\n    document.fonts.add(font);\n\n    return _k.assets.fonts.add(\n        name,\n        font.load().catch((err) => {\n            throw new Error(`Failed to load font from \"${fontSrc}\": ${err}`);\n        }).then((face) => new FontData(face, opt)),\n    );\n}\n\nexport function makeFont(\n    tex: Texture,\n    gw: number,\n    gh: number,\n    chars: string,\n): GfxFont {\n    const cols = tex.width / gw;\n    const map: Record<string, Quad> = {};\n    const charMap = chars.split(\"\").entries();\n\n    for (const [i, ch] of charMap) {\n        map[ch] = new Quad(\n            (i % cols) * gw,\n            Math.floor(i / cols) * gh,\n            gw,\n            gh,\n        );\n    }\n\n    return {\n        tex: tex,\n        map: map,\n        size: gh,\n    };\n}\n", "import { ASCII_CHARS } from \"../constants\";\nimport { Texture } from \"../gfx\";\nimport { _k } from \"../kaplay\";\nimport type { Quad } from \"../math/math\";\nimport type { TexFilter } from \"../types\";\nimport { type Asset, loadImg } from \"./asset\";\nimport { makeFont } from \"./font\";\nimport { fixURL } from \"./utils\";\n\nexport interface GfxFont {\n    tex: Texture;\n    map: Record<string, Quad>;\n    size: number;\n}\n\nexport type BitmapFontData = GfxFont;\n\nexport function getBitmapFont(name: string): Asset<BitmapFontData> | null {\n    return _k.assets.bitmapFonts.get(name) ?? null;\n}\n\nexport interface LoadBitmapFontOpt {\n    chars?: string;\n    filter?: TexFilter;\n    outline?: number;\n}\n\n// TODO: support outline\n// TODO: support LoadSpriteSrc\nexport function loadBitmapFont(\n    name: string | null,\n    src: string,\n    gw: number,\n    gh: number,\n    opt: LoadBitmapFontOpt = {},\n): Asset<BitmapFontData> {\n    const fontSrc = fixURL(src);\n\n    return _k.assets.bitmapFonts.add(\n        name,\n        loadImg(fontSrc)\n            .then((img) => {\n                return makeFont(\n                    Texture.fromImage(_k.gfx.ggl, img, opt),\n                    gw,\n                    gh,\n                    opt.chars ?? ASCII_CHARS,\n                );\n            }),\n    );\n}\n", "import { _k } from \"../kaplay\";\nimport { type Asset, fetchJSON, loadImg } from \"./asset\";\nimport { loadSprite, type SpriteAnims, type SpriteData } from \"./sprite\";\nimport { fixURL } from \"./utils\";\n\nexport interface PeditFile {\n    width: number;\n    height: number;\n    frames: string[];\n    anims: SpriteAnims;\n}\n\nexport function loadPedit(\n    name: string | null,\n    src: string | PeditFile,\n): Asset<SpriteData> {\n    src = fixURL(src);\n\n    return _k.assets.sprites.add(\n        name,\n        new Promise(async (resolve) => {\n            const data = typeof src === \"string\"\n                ? await fetchJSON(src)\n                : src;\n            const images = await Promise.all(data.frames.map(loadImg));\n            const canvas = document.createElement(\"canvas\");\n            canvas.width = data.width;\n            canvas.height = data.height * data.frames.length;\n\n            const c2d = canvas.getContext(\"2d\");\n            if (!c2d) throw new Error(\"Failed to create canvas context\");\n\n            images.forEach((img: HTMLImageElement, i) => {\n                c2d.drawImage(img, 0, i * data.height);\n            });\n\n            const spr = await loadSprite(null, canvas, {\n                sliceY: data.frames.length,\n                anims: data.anims,\n            });\n\n            resolve(spr);\n        }),\n    );\n}\n", "import {\n    DEF_FRAG,\n    DEF_VERT,\n    FRAG_TEMPLATE,\n    VERT_TEMPLATE,\n    VERTEX_FORMAT,\n} from \"../constants\";\nimport { type GfxCtx } from \"../gfx\";\nimport { _k } from \"../kaplay\";\nimport { Color } from \"../math/color\";\nimport { Mat4, Vec2 } from \"../math/math\";\nimport type { RenderProps } from \"../types\";\nimport {\n    arrayIsColor,\n    arrayIsNumber,\n    arrayIsVec2,\n    getErrorMessage,\n} from \"../utils\";\nimport { fetchText, loadProgress } from \"./asset\";\nimport { Asset } from \"./asset\";\nimport { fixURL } from \"./utils\";\n\nexport type ShaderData = Shader;\n\n/**\n * @group Math\n */\nexport type UniformValue =\n    | number\n    | Vec2\n    | Color\n    | Mat4\n    | number[]\n    | Vec2[]\n    | Color[];\n\n/**\n * @group Math\n */\nexport type UniformKey = Exclude<string, \"u_tex\">;\n/**\n * @group Math\n */\nexport type Uniform = Record<UniformKey, UniformValue>;\n\n/**\n * @group GFX\n */\nexport class Shader {\n    ctx: GfxCtx;\n    glProgram: WebGLProgram;\n\n    constructor(ctx: GfxCtx, vert: string, frag: string, attribs: string[]) {\n        this.ctx = ctx;\n        ctx.onDestroy(() => this.free());\n\n        const gl = ctx.gl;\n        const vertShader = gl.createShader(gl.VERTEX_SHADER);\n        const fragShader = gl.createShader(gl.FRAGMENT_SHADER);\n\n        if (!vertShader || !fragShader) {\n            throw new Error(\"Failed to create shader\");\n        }\n\n        // What we should do if vert or frag are null?\n\n        gl.shaderSource(vertShader, vert);\n        gl.shaderSource(fragShader, frag);\n        gl.compileShader(vertShader);\n        gl.compileShader(fragShader);\n\n        const prog = gl.createProgram();\n        this.glProgram = prog!;\n\n        gl.attachShader(prog!, vertShader!);\n        gl.attachShader(prog!, fragShader!);\n\n        attribs.forEach((attrib, i) => gl.bindAttribLocation(prog!, i, attrib));\n\n        gl.linkProgram(prog!);\n\n        if (!gl.getProgramParameter(prog!, gl.LINK_STATUS)) {\n            const vertError = gl.getShaderInfoLog(vertShader!);\n            if (vertError) throw new Error(\"VERTEX SHADER \" + vertError);\n            const fragError = gl.getShaderInfoLog(fragShader!);\n            if (fragError) throw new Error(\"FRAGMENT SHADER \" + fragError);\n        }\n\n        gl.deleteShader(vertShader);\n        gl.deleteShader(fragShader);\n    }\n\n    bind() {\n        this.ctx.pushProgram(this.glProgram);\n    }\n\n    unbind() {\n        this.ctx.popProgram();\n    }\n\n    send(uniform: Uniform) {\n        const gl = this.ctx.gl;\n        for (const name in uniform) {\n            const val = uniform[name];\n            const loc = gl.getUniformLocation(this.glProgram, name);\n            if (typeof val === \"number\") {\n                gl.uniform1f(loc, val);\n            }\n            else if (val instanceof Mat4) {\n                gl.uniformMatrix4fv(loc, false, new Float32Array(val.m));\n            }\n            else if (val instanceof Color) {\n                gl.uniform3f(loc, val.r, val.g, val.b);\n            }\n            else if (val instanceof Vec2) {\n                gl.uniform2f(loc, val.x, val.y);\n            }\n            else if (Array.isArray(val)) {\n                const first = val[0];\n\n                if (arrayIsNumber(val)) {\n                    gl.uniform1fv(loc, val as number[]);\n                }\n                else if (arrayIsVec2(val)) {\n                    gl.uniform2fv(loc, val.map((v) => [v.x, v.y]).flat());\n                }\n                else if (arrayIsColor(val)) {\n                    gl.uniform3fv(loc, val.map(v => [v.r, v.g, v.b]).flat());\n                }\n            }\n            else {\n                throw new Error(\"Unsupported uniform data type\");\n            }\n        }\n    }\n\n    free() {\n        this.ctx.gl.deleteProgram(this.glProgram);\n    }\n}\n\nexport function makeShader(\n    ggl: GfxCtx,\n    vertSrc: string | null = DEF_VERT,\n    fragSrc: string | null = DEF_FRAG,\n): Shader {\n    const vcode = VERT_TEMPLATE.replace(\"{{user}}\", vertSrc ?? DEF_VERT);\n    const fcode = FRAG_TEMPLATE.replace(\"{{user}}\", fragSrc ?? DEF_FRAG);\n\n    try {\n        return new Shader(\n            ggl,\n            vcode,\n            fcode,\n            VERTEX_FORMAT.map((vert) => vert.name),\n        );\n    } catch (e) {\n        const lineOffset = 14;\n        const fmt = /(?<type>^\\w+) SHADER ERROR: 0:(?<line>\\d+): (?<msg>.+)/;\n        const match = getErrorMessage(e).match(fmt);\n        if (!match?.groups) throw e;\n        const line = Number(match.groups.line) - lineOffset;\n        const msg = match.groups.msg.trim();\n        const ty = match.groups.type.toLowerCase();\n        throw new Error(`${ty} shader line ${line}: ${msg}`);\n    }\n}\n\nexport function resolveShader(\n    src: RenderProps[\"shader\"],\n): ShaderData | Asset<ShaderData> | null {\n    if (!src) {\n        return _k.gfx.defShader;\n    }\n    if (typeof src === \"string\") {\n        const shader = getShader(src);\n        if (shader) {\n            return shader.data ?? shader;\n        }\n        else if (loadProgress() < 1) {\n            return null;\n        }\n        else {\n            throw new Error(`Shader not found: ${src}`);\n        }\n    }\n    else if (src instanceof Asset) {\n        return src.data ? src.data : src;\n    }\n\n    return src;\n}\n\nexport function getShader(name: string): Asset<ShaderData> | null {\n    return _k.assets.shaders.get(name) ?? null;\n}\n\nexport function loadShader(\n    name: string | null,\n    vert?: string,\n    frag?: string,\n) {\n    return _k.assets.shaders.addLoaded(\n        name,\n        makeShader(_k.gfx.ggl, vert, frag),\n    );\n}\n\nexport function loadShaderURL(\n    name: string | null,\n    vert?: string,\n    frag?: string,\n): Asset<ShaderData> {\n    vert = fixURL(vert);\n    frag = fixURL(frag);\n    const resolveUrl = (url?: string) =>\n        url\n            ? fetchText(url)\n            : Promise.resolve(null);\n    const load = Promise.all([resolveUrl(vert), resolveUrl(frag)])\n        .then(([vcode, fcode]: [string | null, string | null]) => {\n            return makeShader(_k.gfx.ggl, vcode, fcode);\n        });\n    return _k.assets.shaders.add(name, load);\n}\n", "import { _k } from \"../kaplay\";\nimport { dataURLToArrayBuffer, isDataURL } from \"../utils\";\nimport { Asset, fetchArrayBuffer, loadProgress } from \"./asset\";\nimport { fixURL } from \"./utils\";\n\nexport class SoundData {\n    buf: AudioBuffer;\n\n    constructor(buf: AudioBuffer) {\n        this.buf = buf;\n    }\n\n    static fromArrayBuffer(buf: ArrayBuffer): Promise<SoundData> {\n        return new Promise((resolve, reject) =>\n            _k.audio.ctx.decodeAudioData(buf, resolve, reject)\n        ).then((buf) => new SoundData(buf as AudioBuffer));\n    }\n\n    static fromURL(url: string): Promise<SoundData> {\n        if (isDataURL(url)) {\n            return SoundData.fromArrayBuffer(dataURLToArrayBuffer(url));\n        }\n        else {\n            return fetchArrayBuffer(url).then((buf) =>\n                SoundData.fromArrayBuffer(buf)\n            );\n        }\n    }\n}\n\nexport function resolveSound(\n    src: string | SoundData | Asset<SoundData>,\n): Asset<SoundData> | null {\n    if (typeof src === \"string\") {\n        const snd = getSound(src);\n        if (snd) {\n            return snd;\n        }\n        else if (loadProgress() < 1) {\n            return null;\n        }\n        else {\n            throw new Error(`Sound not found: ${src}`);\n        }\n    }\n    else if (src instanceof SoundData) {\n        return Asset.loaded(src);\n    }\n    else if (src instanceof Asset) {\n        return src;\n    }\n    else {\n        throw new Error(`Invalid sound: ${src}`);\n    }\n}\n\nexport function getSound(name: string): Asset<SoundData> | null {\n    return _k.assets.sounds.get(name) ?? null;\n}\n\n// load a sound to asset manager\nexport function loadSound(\n    name: string | null,\n    src: string | ArrayBuffer,\n): Asset<SoundData> {\n    src = fixURL(src);\n    return _k.assets.sounds.add(\n        name,\n        typeof src === \"string\"\n            ? SoundData.fromURL(src)\n            : SoundData.fromArrayBuffer(src),\n    );\n}\n\nexport function loadMusic(\n    name: string | null,\n    url: string,\n) {\n    const musicUrl = fixURL(url);\n    const a = new Audio(musicUrl);\n    a.preload = \"auto\";\n\n    return _k.assets.music[name as string] = musicUrl;\n}\n", "import { SPRITE_ATLAS_HEIGHT, SPRITE_ATLAS_WIDTH } from \"../constants\";\nimport { _k } from \"../kaplay\";\nimport { Quad } from \"../math\";\nimport { type Asset, fetchJSON, load } from \"./asset\";\nimport {\n    type LoadSpriteOpt,\n    type LoadSpriteSrc,\n    slice,\n    SpriteData,\n} from \"./sprite\";\nimport { fixURL } from \"./utils\";\n\nexport type SpriteAtlasData = Record<string, SpriteAtlasEntry>;\n\n/**\n * A sprite in a sprite atlas.\n */\nexport type SpriteAtlasEntry = LoadSpriteOpt & {\n    /**\n     * X position of the top left corner.\n     */\n    x: number;\n    /**\n     * Y position of the top left corner.\n     */\n    y: number;\n    /**\n     * Sprite area width.\n     */\n    width: number;\n    /**\n     * Sprite area height.\n     */\n    height: number;\n};\n\nexport function loadSpriteAtlas(\n    src: LoadSpriteSrc,\n    data: SpriteAtlasData | string,\n): Asset<Record<string, SpriteData>> {\n    src = fixURL(src);\n    if (typeof data === \"string\") {\n        return load(\n            new Promise((res, rej) => {\n                fetchJSON(data).then((json) => {\n                    loadSpriteAtlas(src, json).then(res).catch(rej);\n                });\n            }),\n        );\n    }\n    return load(\n        SpriteData.from(src).then((atlas) => {\n            const map: Record<string, SpriteData> = {};\n\n            for (const name in data) {\n                const info = data[name];\n                const quad = atlas.frames[0];\n                const w = SPRITE_ATLAS_WIDTH * quad.w;\n                const h = SPRITE_ATLAS_HEIGHT * quad.h;\n                const frames = info.frames\n                    ? info.frames.map((f) =>\n                        new Quad(\n                            quad.x + (info.x + f.x) / w * quad.w,\n                            quad.y + (info.y + f.y) / h * quad.h,\n                            f.w / w * quad.w,\n                            f.h / h * quad.h,\n                        )\n                    )\n                    : slice(\n                        info.sliceX || 1,\n                        info.sliceY || 1,\n                        quad.x + info.x / w * quad.w,\n                        quad.y + info.y / h * quad.h,\n                        info.width / w * quad.w,\n                        info.height / h * quad.h,\n                    );\n                const spr = new SpriteData(atlas.tex, frames, info.anims);\n                _k.assets.sprites.addLoaded(name, spr);\n                map[name] = spr;\n            }\n            return map;\n        }),\n    );\n}\n", "import { Asset, resolveShader, type Uniform } from \"../../assets\";\nimport { _k } from \"../../kaplay\";\nimport { screen2ndc } from \"../../math/various\";\nimport type { RenderProps, Vertex } from \"../../types\";\nimport type { Texture } from \"../gfx\";\n\nexport function drawRaw(\n    verts: Vertex[],\n    indices: number[],\n    fixed: boolean = false,\n    tex?: Texture,\n    shaderSrc?: RenderProps[\"shader\"],\n    uniform: Uniform = {},\n) {\n    const parsedTex = tex ?? _k.gfx.defTex;\n    const parsedShader = shaderSrc ?? _k.gfx.defShader;\n    const shader = resolveShader(parsedShader);\n\n    if (!shader || shader instanceof Asset) {\n        return;\n    }\n\n    const transform = (_k.gfx.fixed || fixed)\n        ? _k.gfx.transform\n        : _k.game.cam.transform.mult(_k.gfx.transform);\n\n    const vv: number[] = [];\n\n    for (const v of verts) {\n        // normalized world space coordinate [-1.0 ~ 1.0]\n        const pt = screen2ndc(transform.multVec2(v.pos));\n\n        vv.push(\n            pt.x,\n            pt.y,\n            v.uv.x,\n            v.uv.y,\n            v.color.r / 255,\n            v.color.g / 255,\n            v.color.b / 255,\n            v.opacity,\n        );\n    }\n\n    _k.gfx.renderer.push(\n        _k.gfx.ggl.gl.TRIANGLES,\n        vv,\n        indices,\n        shader,\n        parsedTex,\n        uniform,\n    );\n}\n", "import { _k } from \"../../kaplay\";\nimport { Color } from \"../../math/color\";\nimport { triangulate, Vec2 } from \"../../math/math\";\nimport type { DrawPolygonOpt } from \"../../types\";\nimport {\n    popTransform,\n    pushRotate,\n    pushScale,\n    pushTransform,\n    pushTranslate,\n} from \"../stack\";\nimport { drawLines } from \"./drawLine\";\nimport { drawRaw } from \"./drawRaw\";\n\nexport function drawPolygon(opt: DrawPolygonOpt) {\n    if (!opt.pts) {\n        throw new Error(\"drawPolygon() requires property \\\"pts\\\".\");\n    }\n\n    const npts = opt.pts.length;\n\n    if (npts < 3) {\n        return;\n    }\n\n    pushTransform();\n    pushTranslate(opt.pos!);\n    pushScale(opt.scale);\n    pushRotate(opt.angle);\n    pushTranslate(opt.offset!);\n\n    if (opt.fill !== false) {\n        const color = opt.color ?? Color.WHITE;\n\n        const verts = opt.pts.map((pt, i) => ({\n            pos: new Vec2(pt.x, pt.y),\n            uv: opt.uv\n                ? opt.uv[i]\n                : new Vec2(0, 0),\n            color: opt.colors\n                ? (opt.colors[i] ? opt.colors[i].mult(color) : color)\n                : color,\n            opacity: opt.opacity ?? 1,\n        }));\n\n        let indices;\n\n        if (opt.triangulate /* && !isConvex(opt.pts)*/) {\n            const triangles = triangulate(opt.pts);\n            // TODO rewrite triangulate to just return new indices\n            indices = triangles.map(t => t.map(p => opt.pts.indexOf(p)))\n                .flat();\n        }\n        else {\n            indices = [...Array(npts - 2).keys()]\n                .map((n) => [0, n + 1, n + 2])\n                .flat();\n        }\n\n        drawRaw(\n            verts,\n            opt.indices ?? indices,\n            opt.fixed,\n            opt.uv ? opt.tex : _k.gfx.defTex,\n            opt.shader,\n            opt.uniform ?? undefined,\n        );\n    }\n\n    if (opt.outline) {\n        drawLines({\n            pts: [...opt.pts, opt.pts[0]],\n            radius: opt.radius,\n            width: opt.outline.width,\n            color: opt.outline.color,\n            join: opt.outline.join,\n            uniform: opt.uniform,\n            fixed: opt.fixed,\n            opacity: opt.opacity ?? opt.outline.opacity,\n        });\n    }\n\n    popTransform();\n}\n", "import { Vec2 } from \"../../math/math\";\nimport { getArcPts } from \"../../math/various\";\nimport type { DrawEllipseOpt } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport { drawPolygon } from \"./drawPolygon\";\n\nexport function drawEllipse(opt: DrawEllipseOpt) {\n    if (opt.radiusX === undefined || opt.radiusY === undefined) {\n        throw new Error(\n            \"drawEllipse() requires properties \\\"radiusX\\\" and \\\"radiusY\\\".\",\n        );\n    }\n\n    if (opt.radiusX === 0 || opt.radiusY === 0) {\n        return;\n    }\n\n    const start = opt.start ?? 0;\n    const end = opt.end ?? 360;\n    const offset = anchorPt(opt.anchor ?? \"center\").scale(\n        new Vec2(-opt.radiusX, -opt.radiusY),\n    );\n\n    const pts = getArcPts(\n        offset,\n        opt.radiusX,\n        opt.radiusY,\n        start,\n        end,\n        opt.resolution,\n    );\n\n    // center\n    pts.unshift(offset);\n\n    const polyOpt = Object.assign({}, opt, {\n        pts,\n        radius: 0,\n        ...(opt.gradient\n            ? {\n                colors: [\n                    opt.gradient[0],\n                    ...Array(pts.length - 1).fill(opt.gradient[1]),\n                ],\n            }\n            : {}),\n    });\n\n    // full circle with outline shouldn't have the center point\n    if (end - start >= 360 && opt.outline) {\n        if (opt.fill !== false) {\n            drawPolygon(Object.assign({}, polyOpt, {\n                outline: null,\n            }));\n        }\n        drawPolygon(Object.assign({}, polyOpt, {\n            pts: pts.slice(1),\n            fill: false,\n        }));\n        return;\n    }\n\n    drawPolygon(polyOpt);\n}\n", "import type { Color } from \"../../math/color\";\nimport type { Vec2 } from \"../../math/math\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { drawEllipse } from \"./drawEllipse\";\n\n/**\n * How the circle should look like.\n */\nexport type DrawCircleOpt = Omit<RenderProps, \"angle\"> & {\n    /**\n     * Radius of the circle.\n     */\n    radius: number;\n    /**\n     * Starting angle.\n     */\n    start?: number;\n    /**\n     * Ending angle.\n     */\n    end?: number;\n    /**\n     * If fill the shape with color (set this to false if you only want an outline).\n     */\n    fill?: boolean;\n    /**\n     * Use gradient instead of solid color.\n     *\n     * @since v3000.0\n     */\n    gradient?: [Color, Color];\n    /**\n     * Multiplier for circle vertices resolution (default 1)\n     */\n    resolution?: number;\n    /**\n     * The anchor point, or the pivot point. Default to \"topleft\".\n     */\n    anchor?: Anchor | Vec2;\n};\n\nexport function drawCircle(opt: DrawCircleOpt) {\n    if (typeof opt.radius !== \"number\") {\n        throw new Error(\"drawCircle() requires property \\\"radius\\\".\");\n    }\n\n    if (opt.radius === 0) {\n        return;\n    }\n\n    drawEllipse(Object.assign({}, opt, {\n        radiusX: opt.radius,\n        radiusY: opt.radius,\n        angle: 0,\n    }));\n}\n", "import { _k } from \"../../kaplay\";\nimport { Color } from \"../../math/color\";\nimport { deg2rad, Vec2, vec2 } from \"../../math/math\";\nimport type { RenderProps } from \"../../types\";\nimport { drawCircle } from \"./drawCircle\";\nimport { drawRaw } from \"./drawRaw\";\n\n/**\n * How the line should look like.\n */\nexport type DrawLineOpt = Omit<RenderProps, \"angle\" | \"scale\"> & {\n    /**\n     * Starting point of the line.\n     */\n    p1: Vec2;\n    /**\n     * Ending point of the line.\n     */\n    p2: Vec2;\n    /**\n     * The width, or thickness of the line,\n     */\n    width?: number;\n};\n\nexport function drawLine(opt: DrawLineOpt) {\n    const { p1, p2 } = opt;\n\n    if (!p1 || !p2) {\n        throw new Error(\n            \"drawLine() requires properties \\\"p1\\\" and \\\"p2\\\".\",\n        );\n    }\n\n    const w = opt.width || 1;\n\n    // the displacement from the line end point to the corner point\n    const dis = p2.sub(p1).unit().normal().scale(w * 0.5);\n\n    // calculate the 4 corner points of the line polygon\n    const verts = [\n        p1.sub(dis),\n        p1.add(dis),\n        p2.add(dis),\n        p2.sub(dis),\n    ].map((p) => ({\n        pos: new Vec2(p.x, p.y),\n        uv: new Vec2(0),\n        color: opt.color ?? Color.WHITE,\n        opacity: opt.opacity ?? 1,\n    }));\n\n    drawRaw(\n        verts,\n        [0, 1, 3, 1, 2, 3],\n        opt.fixed,\n        _k.gfx.defTex,\n        opt.shader,\n        opt.uniform ?? undefined,\n    );\n}\n\nexport type LineJoin =\n    | \"none\"\n    | \"round\"\n    | \"bevel\"\n    | \"miter\";\n\nexport type LineCap =\n    | \"butt\"\n    | \"round\"\n    | \"square\";\n\n/**\n * How the lines should look like.\n */\nexport type DrawLinesOpt = Omit<RenderProps, \"angle\" | \"scale\"> & {\n    /**\n     * The points that should be connected with a line.\n     */\n    pts: Vec2[];\n    /**\n     * The width, or thickness of the lines,\n     */\n    width?: number;\n    /**\n     * The radius of each corner.\n     */\n    radius?: number | number[];\n    /**\n     * Line join style (default \"none\").\n     */\n    join?: LineJoin;\n    /**\n     * Line cap style (default \"none\").\n     */\n    cap?: LineCap;\n    /**\n     * Maximum miter length, anything longer becomes bevel.\n     */\n    miterLimit?: number;\n};\n\nexport function _drawLinesBevel(opt: DrawLinesOpt) {\n    const pts = opt.pts;\n    const vertices = [];\n    const halfWidth = (opt.width || 1) * 0.5;\n    const isLoop = pts[0] === pts[pts.length - 1]\n        || pts[0].eq(pts[pts.length - 1]);\n    const offset = opt.pos || vec2(0, 0);\n    let segment;\n\n    if (isLoop) {\n        segment = pts[0].sub(pts[pts.length - 2]);\n    }\n    else {\n        segment = pts[1].sub(pts[0]);\n    }\n\n    let length = segment.len();\n    let normal = segment.normal().scale(-halfWidth / length);\n\n    let pt1;\n    let pt2 = pts[0];\n\n    if (!isLoop) {\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(-halfWidth / length);\n                vertices.push(pt2.add(dir).add(normal));\n                vertices.push(pt2.add(dir).sub(normal));\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(-1);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                for (let j = 0; j < n; j++) {\n                    vertices.push(pt2);\n                    vertices.push(pt2.sub(vector));\n                    vector = vec2(\n                        vector.x * cs - vector.y * sn,\n                        vector.x * sn + vector.y * cs,\n                    );\n                }\n            }\n        }\n    }\n\n    for (let i = 1; i < pts.length; i++) {\n        if (pt2 === pts[i] || pt2.eq(pts[i])) continue;\n        pt1 = pt2;\n        pt2 = pts[i];\n\n        const nextSegment = pt2.sub(pt1);\n        const nextLength = nextSegment.len();\n        const nextNormal = nextSegment.normal().scale(\n            -halfWidth / nextLength,\n        );\n\n        const det = segment.cross(nextSegment);\n\n        if (Math.abs(det) / (length * nextLength) < 0.05) {\n            // Parallel\n            vertices.push(pt1.add(normal));\n            vertices.push(pt1.sub(normal));\n\n            if (segment.dot(nextSegment) < 0) {\n                vertices.push(pt1.sub(normal));\n                vertices.push(pt1.add(normal));\n            }\n\n            segment = nextSegment;\n            length = nextLength;\n            normal = nextNormal;\n            continue;\n        }\n\n        const lambda = (nextNormal.sub(normal)).cross(nextSegment) / det;\n        const d = normal.add(segment.scale(lambda));\n\n        if (det > 0) {\n            vertices.push(pt1.add(d));\n            vertices.push(pt1.sub(normal));\n            vertices.push(pt1.add(d));\n            vertices.push(pt1.sub(nextNormal));\n        }\n        else {\n            vertices.push(pt1.add(normal));\n            vertices.push(pt1.sub(d));\n            vertices.push(pt1.add(nextNormal));\n            vertices.push(pt1.sub(d));\n        }\n\n        segment = nextSegment;\n        length = nextLength;\n        normal = nextNormal;\n    }\n\n    if (!isLoop) {\n        vertices.push(pt2.add(normal));\n        vertices.push(pt2.sub(normal));\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(halfWidth / length);\n                vertices.push(pt2.add(dir).add(normal));\n                vertices.push(pt2.add(dir).sub(normal));\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(1);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                for (let j = 0; j < n; j++) {\n                    vector = vec2(\n                        vector.x * cs - vector.y * sn,\n                        vector.x * sn + vector.y * cs,\n                    );\n                    vertices.push(pt2);\n                    vertices.push(pt2.sub(vector));\n                }\n            }\n        }\n    }\n\n    if (vertices.length < 4) return;\n\n    const verts = vertices.map(v => ({\n        pos: offset.add(v),\n        uv: vec2(),\n        color: opt.color || Color.WHITE,\n        opacity: opt.opacity ?? 1,\n    }));\n\n    const indices = [];\n    let index = 0;\n    for (let i = 0; i < vertices.length - 2; i += 2) {\n        indices[index++] = i + 1;\n        indices[index++] = i;\n        indices[index++] = i + 2;\n        indices[index++] = i + 2;\n        indices[index++] = i + 3;\n        indices[index++] = i + 1;\n    }\n\n    if (isLoop) {\n        indices[index++] = vertices.length - 1;\n        indices[index++] = vertices.length - 2;\n        indices[index++] = 0;\n        indices[index++] = 0;\n        indices[index++] = 1;\n        indices[index++] = vertices.length - 1;\n    }\n\n    drawRaw(\n        verts,\n        indices,\n        opt.fixed,\n        _k.gfx.defTex,\n        opt.shader,\n        opt.uniform ?? undefined,\n    );\n}\n\nexport function _drawLinesRound(opt: DrawLinesOpt) {\n    const pts = opt.pts;\n    const vertices = [];\n    const halfWidth = (opt.width || 1) * 0.5;\n    const isLoop = pts[0] === pts[pts.length - 1]\n        || pts[0].eq(pts[pts.length - 1]);\n    const offset = opt.pos || vec2(0, 0);\n    let segment;\n\n    if (isLoop) {\n        segment = pts[0].sub(pts[pts.length - 2]);\n    }\n    else {\n        segment = pts[1].sub(pts[0]);\n    }\n\n    let length = segment.len();\n    let normal = segment.normal().scale(-halfWidth / length);\n\n    let pt1;\n    let pt2 = pts[0];\n\n    if (!isLoop) {\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(-halfWidth / length);\n                vertices.push(pt2.add(dir).add(normal));\n                vertices.push(pt2.add(dir).sub(normal));\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(-1);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                for (let j = 0; j < n; j++) {\n                    vertices.push(pt2);\n                    vertices.push(pt2.sub(vector));\n                    vector = vec2(\n                        vector.x * cs - vector.y * sn,\n                        vector.x * sn + vector.y * cs,\n                    );\n                }\n            }\n        }\n    }\n\n    for (let i = 1; i < pts.length; i++) {\n        if (pt2 === pts[i] || pt2.eq(pts[i])) continue;\n        pt1 = pt2;\n        pt2 = pts[i];\n\n        const nextSegment = pt2.sub(pt1);\n        const nextLength = nextSegment.len();\n        const nextNormal = nextSegment.normal().scale(\n            -halfWidth / nextLength,\n        );\n\n        const det = segment.cross(nextSegment);\n\n        if (Math.abs(det) / (length * nextLength) < 0.05) {\n            // Parallel\n            vertices.push(pt1.add(normal));\n            vertices.push(pt1.sub(normal));\n\n            if (segment.dot(nextSegment) < 0) {\n                vertices.push(pt1.sub(normal));\n                vertices.push(pt1.add(normal));\n            }\n\n            segment = nextSegment;\n            length = nextLength;\n            normal = nextNormal;\n            continue;\n        }\n\n        const lambda = (nextNormal.sub(normal)).cross(nextSegment) / det;\n        const d = normal.add(segment.scale(lambda));\n\n        if (det > 0) {\n            const fixedPoint = pt1.add(d);\n            const n = Math.max(halfWidth, 10);\n            const angle = deg2rad(normal.angleBetween(nextNormal) / n);\n            let vector = normal;\n            const cs = Math.cos(angle);\n            const sn = Math.sin(angle);\n            for (let j = 0; j < n; j++) {\n                vertices.push(fixedPoint);\n                vertices.push(pt1.sub(vector));\n                vector = vec2(\n                    vector.x * cs - vector.y * sn,\n                    vector.x * sn + vector.y * cs,\n                );\n            }\n        }\n        else {\n            const fixedPoint = pt1.sub(d);\n            const n = Math.max(halfWidth, 10);\n            const angle = deg2rad(normal.angleBetween(nextNormal) / n);\n            let vector = normal;\n            const cs = Math.cos(angle);\n            const sn = Math.sin(angle);\n            for (let j = 0; j < n; j++) {\n                vertices.push(pt1.add(vector));\n                vertices.push(fixedPoint);\n                vector = vec2(\n                    vector.x * cs - vector.y * sn,\n                    vector.x * sn + vector.y * cs,\n                );\n            }\n        }\n\n        segment = nextSegment;\n        length = nextLength;\n        normal = nextNormal;\n    }\n\n    if (!isLoop) {\n        vertices.push(pt2.add(normal));\n        vertices.push(pt2.sub(normal));\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(halfWidth / length);\n                vertices.push(pt2.add(dir).add(normal));\n                vertices.push(pt2.add(dir).sub(normal));\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(1);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                for (let j = 0; j < n; j++) {\n                    vector = vec2(\n                        vector.x * cs - vector.y * sn,\n                        vector.x * sn + vector.y * cs,\n                    );\n                    vertices.push(pt2);\n                    vertices.push(pt2.sub(vector));\n                }\n            }\n        }\n    }\n\n    if (vertices.length < 4) return;\n\n    const verts = vertices.map(v => ({\n        pos: offset.add(v),\n        uv: vec2(),\n        color: opt.color || Color.WHITE,\n        opacity: opt.opacity ?? 1,\n    }));\n\n    const indices = [];\n    let index = 0;\n    for (let i = 0; i < vertices.length - 2; i += 2) {\n        indices[index++] = i + 1;\n        indices[index++] = i;\n        indices[index++] = i + 2;\n        indices[index++] = i + 2;\n        indices[index++] = i + 3;\n        indices[index++] = i + 1;\n    }\n\n    if (isLoop) {\n        indices[index++] = vertices.length - 1;\n        indices[index++] = vertices.length - 2;\n        indices[index++] = 0;\n        indices[index++] = 0;\n        indices[index++] = 1;\n        indices[index++] = vertices.length - 1;\n    }\n\n    drawRaw(\n        verts,\n        indices,\n        opt.fixed,\n        _k.gfx.defTex,\n        opt.shader,\n        opt.uniform ?? undefined,\n    );\n}\n\nexport function _drawLinesMiter(opt: DrawLinesOpt) {\n    const pts = opt.pts;\n    const vertices = [];\n    const halfWidth = (opt.width || 1) * 0.5;\n    const isLoop = pts[0] === pts[pts.length - 1]\n        || pts[0].eq(pts[pts.length - 1]);\n    const offset = opt.pos || vec2(0, 0);\n    let segment;\n\n    if (isLoop) {\n        segment = pts[0].sub(pts[pts.length - 2]);\n    }\n    else {\n        segment = pts[1].sub(pts[0]);\n    }\n\n    let length = segment.len();\n    let normal = segment.normal().scale(-halfWidth / length);\n\n    let pt1;\n    let pt2 = pts[0];\n\n    if (!isLoop) {\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(-halfWidth / length);\n                vertices.push(pt2.add(dir).add(normal));\n                vertices.push(pt2.add(dir).sub(normal));\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(-1);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                for (let j = 0; j < n; j++) {\n                    vertices.push(pt2);\n                    vertices.push(pt2.sub(vector));\n                    vector = vec2(\n                        vector.x * cs - vector.y * sn,\n                        vector.x * sn + vector.y * cs,\n                    );\n                }\n            }\n        }\n    }\n\n    for (let i = 1; i < pts.length; i++) {\n        if (pt2 === pts[i] || pt2.eq(pts[i])) continue;\n        pt1 = pt2;\n        pt2 = pts[i];\n\n        const nextSegment = pt2.sub(pt1);\n        const nextLength = nextSegment.len();\n        const nextNormal = nextSegment.normal().scale(\n            -halfWidth / nextLength,\n        );\n\n        const det = segment.cross(nextSegment);\n\n        if (Math.abs(det) / (length * nextLength) < 0.05) {\n            // Parallel\n            vertices.push(pt1.add(normal));\n            vertices.push(pt1.sub(normal));\n\n            if (segment.dot(nextSegment) < 0) {\n                vertices.push(pt1.sub(normal));\n                vertices.push(pt1.add(normal));\n            }\n\n            segment = nextSegment;\n            length = nextLength;\n            normal = nextNormal;\n            continue;\n        }\n\n        const lambda = (nextNormal.sub(normal)).cross(nextSegment) / det;\n        const d = normal.add(segment.scale(lambda));\n\n        vertices.push(pt1.add(d));\n        vertices.push(pt1.sub(d));\n\n        segment = nextSegment;\n        length = nextLength;\n        normal = nextNormal;\n    }\n\n    if (!isLoop) {\n        vertices.push(pt2.add(normal));\n        vertices.push(pt2.sub(normal));\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(halfWidth / length);\n                vertices.push(pt2.add(dir).add(normal));\n                vertices.push(pt2.add(dir).sub(normal));\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(1);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                for (let j = 0; j < n; j++) {\n                    vector = vec2(\n                        vector.x * cs - vector.y * sn,\n                        vector.x * sn + vector.y * cs,\n                    );\n                    vertices.push(pt2);\n                    vertices.push(pt2.sub(vector));\n                }\n            }\n        }\n    }\n\n    if (vertices.length < 4) return;\n\n    const verts = vertices.map(v => ({\n        pos: offset.add(v),\n        uv: vec2(),\n        color: opt.color || Color.WHITE,\n        opacity: opt.opacity ?? 1,\n    }));\n\n    const indices = [];\n    let index = 0;\n    for (let i = 0; i < vertices.length - 2; i += 2) {\n        indices[index++] = i + 1;\n        indices[index++] = i;\n        indices[index++] = i + 2;\n        indices[index++] = i + 2;\n        indices[index++] = i + 3;\n        indices[index++] = i + 1;\n    }\n\n    if (isLoop) {\n        indices[index++] = vertices.length - 1;\n        indices[index++] = vertices.length - 2;\n        indices[index++] = 0;\n        indices[index++] = 0;\n        indices[index++] = 1;\n        indices[index++] = vertices.length - 1;\n    }\n\n    drawRaw(\n        verts,\n        indices,\n        opt.fixed,\n        _k.gfx.defTex,\n        opt.shader,\n        opt.uniform ?? undefined,\n    );\n}\n\nexport function drawLines(opt: DrawLinesOpt) {\n    const pts = opt.pts;\n    const width = opt.width ?? 1;\n\n    if (!pts) {\n        throw new Error(\"drawLines() requires property \\\"pts\\\".\");\n    }\n\n    if (pts.length < 2) {\n        return;\n    }\n\n    if (pts.length > 2) {\n        switch (opt.join) {\n            case \"bevel\":\n                return _drawLinesBevel(opt);\n            case \"round\":\n                return _drawLinesRound(opt);\n            case \"miter\":\n                return _drawLinesMiter(opt);\n        }\n    }\n\n    if (opt.radius && pts.length >= 3) {\n        // TODO: line joines\n        // TODO: rounded vertices for arbitrary polygonic shape\n        drawLine(Object.assign({}, opt, { p1: pts[0], p2: pts[1] }));\n\n        for (let i = 1; i < pts.length - 2; i++) {\n            const p1 = pts[i];\n            const p2 = pts[i + 1];\n            drawLine(Object.assign({}, opt, {\n                p1: p1,\n                p2: p2,\n            }));\n        }\n\n        drawLine(Object.assign({}, opt, {\n            p1: pts[pts.length - 2],\n            p2: pts[pts.length - 1],\n        }));\n    }\n    else {\n        for (let i = 0; i < pts.length - 1; i++) {\n            drawLine(Object.assign({}, opt, {\n                p1: pts[i],\n                p2: pts[i + 1],\n            }));\n            // TODO: other line join types\n            if (opt.join !== \"none\") {\n                drawCircle(Object.assign({}, opt, {\n                    pos: pts[i],\n                    radius: width / 2,\n                }));\n            }\n        }\n    }\n}\n", "import type { Vec2 } from \"../../math/math\";\nimport type { RenderProps } from \"../../types\";\nimport { drawLines } from \"./drawLine\";\n\nexport type DrawCurveOpt = RenderProps & {\n    /**\n     * The amount of line segments to draw.\n     */\n    segments?: number;\n    /**\n     * The width of the line.\n     */\n    width?: number;\n};\n\nexport function drawCurve(curve: (t: number) => Vec2, opt: DrawCurveOpt) {\n    const segments = opt.segments ?? 16;\n    const p: Vec2[] = [];\n\n    for (let i = 0; i <= segments; i++) {\n        p.push(curve(i / segments));\n    }\n\n    drawLines({\n        pts: p,\n        width: opt.width || 1,\n        pos: opt.pos,\n        color: opt.color,\n        opacity: opt.opacity,\n    });\n}\n", "import { evaluateBezier, type Vec2 } from \"../../math/math\";\nimport { drawCurve, type DrawCurveOpt } from \"./drawCurve\";\n\nexport type DrawBezierOpt = DrawCurveOpt & {\n    /**\n     * The first point.\n     */\n    pt1: Vec2;\n    /**\n     * The the first control point.\n     */\n    pt2: Vec2;\n    /**\n     * The the second control point.\n     */\n    pt3: Vec2;\n    /**\n     * The second point.\n     */\n    pt4: Vec2;\n};\n\nexport function drawBezier(opt: DrawBezierOpt) {\n    drawCurve(\n        t => evaluateBezier(opt.pt1, opt.pt2, opt.pt3, opt.pt4, t),\n        opt,\n    );\n}\n", "import type { Shader, Uniform } from \"../assets\";\nimport type { ImageSource, TexFilter, TextureOpt } from \"../types\";\nimport { deepEq } from \"../utils/\";\n\nexport type GfxCtx = ReturnType<typeof initGfx>;\n\nexport class Texture {\n    ctx: GfxCtx;\n    src: null | ImageSource = null;\n    glTex: WebGLTexture;\n    width: number;\n    height: number;\n\n    constructor(ctx: GfxCtx, w: number, h: number, opt: TextureOpt = {}) {\n        this.ctx = ctx;\n        const gl = ctx.gl;\n        const glText = ctx.gl.createTexture();\n\n        if (!glText) {\n            throw new Error(\"Failed to create texture\");\n        }\n\n        this.glTex = glText;\n        ctx.onDestroy(() => this.free());\n\n        this.width = w;\n        this.height = h;\n\n        const filter = {\n            \"linear\": gl.LINEAR,\n            \"nearest\": gl.NEAREST,\n        }[opt.filter ?? ctx.opts.texFilter ?? \"nearest\"];\n\n        const wrap = {\n            \"repeat\": gl.REPEAT,\n            \"clampToEdge\": gl.CLAMP_TO_EDGE,\n        }[opt.wrap ?? \"clampToEdge\"];\n\n        this.bind();\n\n        if (w && h) {\n            gl.texImage2D(\n                gl.TEXTURE_2D,\n                0,\n                gl.RGBA,\n                w,\n                h,\n                0,\n                gl.RGBA,\n                gl.UNSIGNED_BYTE,\n                null,\n            );\n        }\n\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n        this.unbind();\n    }\n\n    static fromImage(\n        ctx: GfxCtx,\n        img: ImageSource,\n        opt: TextureOpt = {},\n    ): Texture {\n        const tex = new Texture(ctx, img.width, img.height, opt);\n        tex.update(img);\n        tex.src = img;\n        return tex;\n    }\n\n    update(img: ImageSource, x = 0, y = 0) {\n        const gl = this.ctx.gl;\n        this.bind();\n        gl.texSubImage2D(\n            gl.TEXTURE_2D,\n            0,\n            x,\n            y,\n            gl.RGBA,\n            gl.UNSIGNED_BYTE,\n            img,\n        );\n        this.unbind();\n    }\n\n    bind() {\n        this.ctx.pushTexture2D(this.glTex);\n    }\n\n    unbind() {\n        this.ctx.popTexture2D();\n    }\n\n    /** Frees up texture memory. Call this once the texture is no longer being used to avoid memory leaks. */\n    free() {\n        this.ctx.gl.deleteTexture(this.glTex);\n    }\n}\n\n/**\n * @group GFX\n */\nexport class FrameBuffer {\n    ctx: GfxCtx;\n    tex: Texture;\n    glFramebuffer: WebGLFramebuffer;\n    glRenderbuffer: WebGLRenderbuffer;\n\n    constructor(ctx: GfxCtx, w: number, h: number, opt: TextureOpt = {}) {\n        this.ctx = ctx;\n        const gl = ctx.gl;\n        ctx.onDestroy(() => this.free());\n        this.tex = new Texture(ctx, w, h, opt);\n\n        const frameBuffer = gl.createFramebuffer();\n        const renderBuffer = gl.createRenderbuffer();\n\n        if (!frameBuffer || !renderBuffer) {\n            throw new Error(\"Failed to create framebuffer\");\n        }\n\n        this.glFramebuffer = frameBuffer;\n        this.glRenderbuffer = renderBuffer;\n\n        this.bind();\n        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, w, h);\n        gl.framebufferTexture2D(\n            gl.FRAMEBUFFER,\n            gl.COLOR_ATTACHMENT0,\n            gl.TEXTURE_2D,\n            this.tex.glTex,\n            0,\n        );\n        gl.framebufferRenderbuffer(\n            gl.FRAMEBUFFER,\n            gl.DEPTH_STENCIL_ATTACHMENT,\n            gl.RENDERBUFFER,\n            this.glRenderbuffer,\n        );\n        this.unbind();\n    }\n\n    get width() {\n        return this.tex.width;\n    }\n\n    get height() {\n        return this.tex.height;\n    }\n\n    toImageData() {\n        const gl = this.ctx.gl;\n        const data = new Uint8ClampedArray(this.width * this.height * 4);\n        this.bind();\n        gl.readPixels(\n            0,\n            0,\n            this.width,\n            this.height,\n            gl.RGBA,\n            gl.UNSIGNED_BYTE,\n            data,\n        );\n        this.unbind();\n        // flip vertically\n        const bytesPerRow = this.width * 4;\n        const temp = new Uint8Array(bytesPerRow);\n        for (let y = 0; y < (this.height / 2 | 0); y++) {\n            const topOffset = y * bytesPerRow;\n            const bottomOffset = (this.height - y - 1) * bytesPerRow;\n            temp.set(data.subarray(topOffset, topOffset + bytesPerRow));\n            data.copyWithin(\n                topOffset,\n                bottomOffset,\n                bottomOffset + bytesPerRow,\n            );\n            data.set(temp, bottomOffset);\n        }\n        return new ImageData(data, this.width, this.height);\n    }\n\n    toDataURL() {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        canvas.width = this.width;\n        canvas.height = this.height;\n\n        if (!ctx) throw new Error(\"Failed to get 2d context\");\n\n        ctx.putImageData(this.toImageData(), 0, 0);\n        return canvas.toDataURL();\n    }\n\n    clear() {\n        const gl = this.ctx.gl;\n        gl.clear(gl.COLOR_BUFFER_BIT);\n    }\n\n    draw(action: () => void) {\n        this.bind();\n        action();\n        this.unbind();\n    }\n\n    bind() {\n        this.ctx.pushFramebuffer(this.glFramebuffer);\n        this.ctx.pushRenderbuffer(this.glRenderbuffer);\n        this.ctx.pushViewport({ x: 0, y: 0, w: this.width, h: this.height });\n    }\n\n    unbind() {\n        this.ctx.popFramebuffer();\n        this.ctx.popRenderbuffer();\n        this.ctx.popViewport();\n    }\n\n    free() {\n        const gl = this.ctx.gl;\n        gl.deleteFramebuffer(this.glFramebuffer);\n        gl.deleteRenderbuffer(this.glRenderbuffer);\n        this.tex.free();\n    }\n}\n\nexport type VertexFormat = {\n    name: string;\n    size: number;\n}[];\n\nexport class BatchRenderer {\n    ctx: GfxCtx;\n\n    glVBuf: WebGLBuffer;\n    glIBuf: WebGLBuffer;\n    vqueue: number[] = [];\n    iqueue: number[] = [];\n    stride: number;\n    maxVertices: number;\n    maxIndices: number;\n\n    vertexFormat: VertexFormat;\n    numDraws: number = 0;\n\n    curPrimitive: GLenum | null = null;\n    curTex: Texture | null = null;\n    curShader: Shader | null = null;\n    curUniform: Uniform = {};\n\n    constructor(\n        ctx: GfxCtx,\n        format: VertexFormat,\n        maxVertices: number,\n        maxIndices: number,\n    ) {\n        const gl = ctx.gl;\n\n        this.vertexFormat = format;\n        this.ctx = ctx;\n        this.stride = format.reduce((sum, f) => sum + f.size, 0);\n        this.maxVertices = maxVertices;\n        this.maxIndices = maxIndices;\n\n        const glVBuf = gl.createBuffer();\n\n        if (!glVBuf) {\n            throw new Error(\"Failed to create vertex buffer\");\n        }\n\n        this.glVBuf = glVBuf;\n\n        ctx.pushArrayBuffer(this.glVBuf);\n        gl.bufferData(gl.ARRAY_BUFFER, maxVertices * 4, gl.DYNAMIC_DRAW);\n        ctx.popArrayBuffer();\n\n        this.glIBuf = gl.createBuffer()!;\n        ctx.pushElementArrayBuffer(this.glIBuf);\n        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, maxIndices * 4, gl.DYNAMIC_DRAW);\n        ctx.popElementArrayBuffer();\n    }\n\n    push(\n        primitive: GLenum,\n        verts: number[],\n        indices: number[],\n        shader: Shader,\n        tex: Texture | null = null,\n        uniform: Uniform = {},\n    ) {\n        if (\n            primitive !== this.curPrimitive\n            || tex !== this.curTex\n            || shader !== this.curShader\n            || !deepEq(this.curUniform, uniform)\n            || this.vqueue.length + verts.length * this.stride\n                > this.maxVertices\n            || this.iqueue.length + indices.length > this.maxIndices\n        ) {\n            this.flush();\n        }\n        const indexOffset = this.vqueue.length / this.stride;\n        for (const v of verts) {\n            this.vqueue.push(v);\n        }\n        for (const i of indices) {\n            this.iqueue.push(i + indexOffset);\n        }\n        this.curPrimitive = primitive;\n        this.curShader = shader;\n        this.curTex = tex;\n        this.curUniform = uniform;\n    }\n\n    flush() {\n        if (\n            !this.curPrimitive\n            || !this.curShader\n            || this.vqueue.length === 0\n            || this.iqueue.length === 0\n        ) {\n            return;\n        }\n\n        const gl = this.ctx.gl;\n\n        this.ctx.pushArrayBuffer(this.glVBuf);\n        gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.vqueue));\n        this.ctx.pushElementArrayBuffer(this.glIBuf);\n        gl.bufferSubData(\n            gl.ELEMENT_ARRAY_BUFFER,\n            0,\n            new Uint16Array(this.iqueue),\n        );\n        this.ctx.setVertexFormat(this.vertexFormat);\n        this.curShader.bind();\n        this.curShader.send(this.curUniform);\n        this.curTex?.bind();\n        gl.drawElements(\n            this.curPrimitive,\n            this.iqueue.length,\n            gl.UNSIGNED_SHORT,\n            0,\n        );\n        this.curTex?.unbind();\n        this.curShader.unbind();\n\n        this.ctx.popArrayBuffer();\n        this.ctx.popElementArrayBuffer();\n\n        this.vqueue = [];\n        this.iqueue = [];\n        this.numDraws++;\n    }\n\n    free() {\n        const gl = this.ctx.gl;\n        gl.deleteBuffer(this.glVBuf);\n        gl.deleteBuffer(this.glIBuf);\n    }\n}\n\nexport class Mesh {\n    ctx: GfxCtx;\n    glVBuf: WebGLBuffer;\n    glIBuf: WebGLBuffer;\n    vertexFormat: VertexFormat;\n    count: number;\n\n    constructor(\n        ctx: GfxCtx,\n        format: VertexFormat,\n        verts: number[],\n        indices: number[],\n    ) {\n        const gl = ctx.gl;\n        this.vertexFormat = format;\n        this.ctx = ctx;\n        const glVBuf = gl.createBuffer();\n\n        if (!glVBuf) throw new Error(\"Failed to create vertex buffer\");\n\n        this.glVBuf = glVBuf;\n\n        ctx.pushArrayBuffer(this.glVBuf);\n        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);\n        ctx.popArrayBuffer();\n\n        this.glIBuf = gl.createBuffer()!;\n        ctx.pushElementArrayBuffer(this.glIBuf);\n        gl.bufferData(\n            gl.ELEMENT_ARRAY_BUFFER,\n            new Uint16Array(indices),\n            gl.STATIC_DRAW,\n        );\n        ctx.popElementArrayBuffer();\n\n        this.count = indices.length;\n    }\n\n    draw(primitive?: GLenum) {\n        const gl = this.ctx.gl;\n        this.ctx.pushArrayBuffer(this.glVBuf);\n        this.ctx.pushElementArrayBuffer(this.glIBuf);\n        this.ctx.setVertexFormat(this.vertexFormat);\n        gl.drawElements(\n            primitive ?? gl.TRIANGLES,\n            this.count,\n            gl.UNSIGNED_SHORT,\n            0,\n        );\n        this.ctx.popArrayBuffer();\n        this.ctx.popElementArrayBuffer();\n    }\n\n    free() {\n        const gl = this.ctx.gl;\n        gl.deleteBuffer(this.glVBuf);\n        gl.deleteBuffer(this.glIBuf);\n    }\n}\n\nfunction genStack<T>(setFunc: (item: T | null) => void) {\n    const stack: T[] = [];\n    // TODO: don't do anything if pushed item is the same as the one on top?\n    const push = (item: T) => {\n        stack.push(item);\n        setFunc(item);\n    };\n    const pop = () => {\n        stack.pop();\n        setFunc(cur() ?? null);\n    };\n    const cur = () => stack[stack.length - 1];\n    return [push, pop, cur] as const;\n}\n\nexport function initGfx(gl: WebGLRenderingContext, opts: {\n    texFilter?: TexFilter;\n} = {}) {\n    const gc: Array<() => void> = [];\n\n    function onDestroy(action: () => unknown) {\n        gc.push(action);\n    }\n\n    function destroy() {\n        gc.forEach((action) => action());\n        const extension = gl.getExtension(\"WEBGL_lose_context\");\n        if (extension) extension.loseContext();\n    }\n\n    let curVertexFormat: object | null = null;\n\n    function setVertexFormat(fmt: VertexFormat) {\n        if (deepEq(fmt, curVertexFormat)) return;\n        curVertexFormat = fmt;\n        const stride = fmt.reduce((sum, f) => sum + f.size, 0);\n        fmt.reduce((offset, f, i) => {\n            gl.vertexAttribPointer(\n                i,\n                f.size,\n                gl.FLOAT,\n                false,\n                stride * 4,\n                offset,\n            );\n            gl.enableVertexAttribArray(i);\n            return offset + f.size * 4;\n        }, 0);\n    }\n\n    const [pushTexture2D, popTexture2D] = genStack<WebGLTexture>((t) =>\n        gl.bindTexture(gl.TEXTURE_2D, t)\n    );\n\n    const [pushArrayBuffer, popArrayBuffer] = genStack<WebGLBuffer>((b) =>\n        gl.bindBuffer(gl.ARRAY_BUFFER, b)\n    );\n\n    const [pushElementArrayBuffer, popElementArrayBuffer] = genStack<\n        WebGLBuffer\n    >((b) => gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, b));\n\n    const [pushFramebuffer, popFramebuffer] = genStack<WebGLFramebuffer>((b) =>\n        gl.bindFramebuffer(gl.FRAMEBUFFER, b)\n    );\n\n    const [pushRenderbuffer, popRenderbuffer] = genStack<WebGLRenderbuffer>((\n        b,\n    ) => gl.bindRenderbuffer(gl.RENDERBUFFER, b));\n\n    const [pushViewport, popViewport] = genStack<\n        { x: number; y: number; w: number; h: number }\n    >((stack) => {\n        if (!stack) return;\n        const { x, y, w, h } = stack;\n\n        gl.viewport(x, y, w, h);\n    });\n\n    const [pushProgram, popProgram] = genStack<WebGLProgram>((p) =>\n        gl.useProgram(p)\n    );\n\n    pushViewport({\n        x: 0,\n        y: 0,\n        w: gl.drawingBufferWidth,\n        h: gl.drawingBufferHeight,\n    });\n\n    return {\n        gl,\n        opts,\n        onDestroy,\n        destroy,\n        pushTexture2D,\n        popTexture2D,\n        pushArrayBuffer,\n        popArrayBuffer,\n        pushElementArrayBuffer,\n        popElementArrayBuffer,\n        pushFramebuffer,\n        popFramebuffer,\n        pushRenderbuffer,\n        popRenderbuffer,\n        pushViewport,\n        popViewport,\n        pushProgram,\n        popProgram,\n        setVertexFormat,\n    };\n}\n", "import { Asset, type BitmapFontData, FontData, resolveFont } from \"../assets\";\nimport {\n    DEF_FONT_FILTER,\n    DEF_TEXT_CACHE_SIZE,\n    FONT_ATLAS_HEIGHT,\n    FONT_ATLAS_WIDTH,\n} from \"../constants\";\nimport { _k } from \"../kaplay\";\nimport { Color } from \"../math/color\";\nimport { Quad, Vec2, vec2 } from \"../math/math\";\nimport { type Outline, type TexFilter } from \"../types\";\nimport { runes } from \"../utils\";\nimport { alignPt } from \"./anchor\";\nimport {\n    type CharTransform,\n    type DrawTextOpt,\n    drawUVQuad,\n    type FormattedChar,\n    type FormattedText,\n} from \"./draw\";\nimport { Texture } from \"./gfx\";\nimport { center } from \"./stack\";\n\ntype FontAtlas = {\n    font: BitmapFontData;\n    cursor: Vec2;\n    maxHeight: number;\n    outline: Outline | null;\n};\n\nconst fontAtlases: Record<string, FontAtlas> = {};\n\nfunction applyCharTransform(fchar: FormattedChar, tr: CharTransform) {\n    if (tr.override) {\n        Object.assign(fchar, tr);\n        return;\n    }\n    if (tr.pos) fchar.pos = fchar.pos.add(tr.pos);\n    if (tr.scale) fchar.scale = fchar.scale.scale(vec2(tr.scale));\n    if (tr.angle) fchar.angle += tr.angle;\n    if (tr.color && fchar.ch.length === 1) {\n        fchar.color = fchar.color.mult(tr.color);\n    }\n    // attention to type coercion, 0 is a valid value, only null & undefined are not\n    if (tr.opacity != null) fchar.opacity *= tr.opacity;\n}\n\nexport function compileStyledText(txt: string): {\n    charStyleMap: Record<number, string[]>;\n    text: string;\n} {\n    const charStyleMap = {} as Record<number, string[]>;\n    let renderText = \"\";\n    let styleStack: string[] = [];\n\n    let text = String(txt);\n\n    const emit = (ch: string) => {\n        if (styleStack.length > 0) {\n            charStyleMap[renderText.length] = styleStack.slice();\n        }\n        renderText += ch;\n    };\n\n    while (text !== \"\") {\n        if (text[0] === \"\\\\\") {\n            if (text.length === 1) {\n                throw new Error(\"Styled text error: \\\\ at end of string\");\n            }\n            emit(text[1]);\n            text = text.slice(2);\n            continue;\n        }\n        if (text[0] === \"[\") {\n            const execResult = /^\\[(\\/)?(\\w+?)\\]/.exec(text);\n            if (!execResult) {\n                // xxx: should throw an error here?\n                emit(text[0]);\n                text = text.slice(1);\n                continue;\n            }\n            const [m, e, gn] = execResult;\n            if (e !== undefined) {\n                const x = styleStack.pop();\n                if (x !== gn) {\n                    if (x !== undefined) {\n                        throw new Error(\n                            \"Styled text error: mismatched tags. \"\n                                + `Expected [/${x}], got [/${gn}]`,\n                        );\n                    }\n                    else {\n                        throw new Error(\n                            `Styled text error: stray end tag [/${gn}]`,\n                        );\n                    }\n                }\n            }\n            else styleStack.push(gn);\n            text = text.slice(m.length);\n            continue;\n        }\n        emit(text[0]);\n        text = text.slice(1);\n    }\n\n    if (styleStack.length > 0) {\n        throw new Error(\n            `Styled text error: unclosed tags ${styleStack}`,\n        );\n    }\n\n    return {\n        charStyleMap,\n        text: renderText,\n    };\n}\n\nexport function formatText(opt: DrawTextOpt): FormattedText {\n    if (opt.text === undefined) {\n        throw new Error(\"formatText() requires property \\\"text\\\".\");\n    }\n\n    let font = resolveFont(opt.font);\n\n    // if it's still loading\n    if (!opt.text || opt.text === \"\" || font instanceof Asset || !font) {\n        return {\n            width: 0,\n            height: 0,\n            chars: [],\n            opt: opt,\n            renderedText: \"\",\n        };\n    }\n\n    const { charStyleMap, text } = compileStyledText(opt.text + \"\");\n    const chars = runes(text);\n\n    // if it's not bitmap font, we draw it with 2d canvas or use cached image\n    if (font instanceof FontData || typeof font === \"string\") {\n        const fontName = font instanceof FontData\n            ? font.fontface.family\n            : font;\n        const opts: {\n            outline: Outline | null;\n            filter: TexFilter;\n        } = font instanceof FontData\n            ? {\n                outline: font.outline,\n                filter: font.filter,\n            }\n            : {\n                outline: null,\n                filter: DEF_FONT_FILTER,\n            };\n\n        // TODO: customizable font tex filter\n        const atlas: FontAtlas = fontAtlases[fontName] ?? {\n            font: {\n                tex: new Texture(\n                    _k.gfx.ggl,\n                    FONT_ATLAS_WIDTH,\n                    FONT_ATLAS_HEIGHT,\n                    {\n                        filter: opts.filter,\n                    },\n                ),\n                map: {},\n                size: DEF_TEXT_CACHE_SIZE,\n            },\n            cursor: new Vec2(0),\n            maxHeight: 0,\n            outline: opts.outline,\n        };\n\n        if (!fontAtlases[fontName]) {\n            fontAtlases[fontName] = atlas;\n        }\n\n        font = atlas.font;\n\n        for (const ch of chars) {\n            if (!atlas.font.map[ch]) {\n                // TODO: use assets.packer to pack font texture\n                const c2d = _k.fontCacheC2d;\n                if (!c2d) throw new Error(\"fontCacheC2d is not defined.\");\n\n                if (!_k.fontCacheCanvas) {\n                    throw new Error(\"fontCacheCanvas is not defined.\");\n                }\n\n                c2d.clearRect(\n                    0,\n                    0,\n                    _k.fontCacheCanvas.width,\n                    _k.fontCacheCanvas.height,\n                );\n\n                c2d.font = `${font.size}px ${fontName}`;\n                c2d.textBaseline = \"top\";\n                c2d.textAlign = \"left\";\n                c2d.fillStyle = \"#ffffff\";\n                const m = c2d.measureText(ch);\n                let w = Math.ceil(m.width);\n                if (!w) continue;\n                let h = Math.ceil(Math.abs(m.actualBoundingBoxAscent))\n                    + Math.ceil(Math.abs(m.actualBoundingBoxDescent));\n\n                // TODO: Test if this works with the verification of width and color\n                if (\n                    atlas.outline && atlas.outline.width\n                    && atlas.outline.color\n                ) {\n                    c2d.lineJoin = \"round\";\n                    c2d.lineWidth = atlas.outline.width * 2;\n                    c2d.strokeStyle = atlas.outline.color.toHex();\n                    c2d.strokeText(\n                        ch,\n                        atlas.outline.width,\n                        atlas.outline.width,\n                    );\n\n                    w += atlas.outline.width * 2;\n                    h += atlas.outline.width * 3;\n                }\n\n                c2d.fillText(\n                    ch,\n                    atlas.outline?.width ?? 0,\n                    atlas.outline?.width ?? 0,\n                );\n\n                const img = c2d.getImageData(\n                    0,\n                    0,\n                    w,\n                    h,\n                );\n\n                // if we are about to exceed the X axis of the texture, go to another line\n                if (atlas.cursor.x + w > FONT_ATLAS_WIDTH) {\n                    atlas.cursor.x = 0;\n                    atlas.cursor.y += atlas.maxHeight;\n                    atlas.maxHeight = 0;\n                    if (atlas.cursor.y > FONT_ATLAS_HEIGHT) {\n                        // TODO: create another atlas\n                        throw new Error(\n                            \"Font atlas exceeds character limit\",\n                        );\n                    }\n                }\n\n                font.tex.update(img, atlas.cursor.x, atlas.cursor.y);\n\n                font.map[ch] = new Quad(\n                    atlas.cursor.x,\n                    atlas.cursor.y,\n                    w,\n                    h,\n                );\n\n                atlas.cursor.x += w + 1;\n                atlas.maxHeight = Math.max(atlas.maxHeight, h);\n            }\n        }\n    }\n\n    const size = opt.size || font.size;\n    const scale = vec2(opt.scale ?? 1).scale(size / font.size);\n    const lineSpacing = opt.lineSpacing ?? 0;\n    const letterSpacing = opt.letterSpacing ?? 0;\n    let curX: number = 0;\n    let tw = 0;\n    let th = 0;\n    const lines: Array<{\n        width: number;\n        chars: FormattedChar[];\n    }> = [];\n    let curLine: FormattedChar[] = [];\n    let cursor = 0;\n    let lastSpace: number | null = null;\n    let lastSpaceWidth: number = 0;\n    let paraIndentX: number | undefined = undefined;\n\n    // TODO: word break\n    while (cursor < chars.length) {\n        let ch = chars[cursor];\n\n        // always new line on '\\n'\n        if (ch === \"\\n\") {\n            th += size + lineSpacing;\n\n            lines.push({\n                width: curX - letterSpacing,\n                chars: curLine,\n            });\n\n            lastSpace = null;\n            lastSpaceWidth = 0;\n            curX = 0;\n            curLine = [];\n            paraIndentX = undefined;\n        }\n        else {\n            let q = font.map[ch];\n\n            // TODO: leave space if character not found?\n            if (q) {\n                let gw = q.w * scale.x;\n\n                if (opt.width && curX + gw > opt.width) {\n                    // new line on last word if width exceeds\n                    th += size + lineSpacing;\n                    if (lastSpace != null) {\n                        cursor -= curLine.length - lastSpace;\n                        ch = chars[cursor];\n                        q = font.map[ch];\n                        gw = q.w * scale.x;\n                        // omit trailing space\n                        curLine = curLine.slice(0, lastSpace - 1);\n                        curX = lastSpaceWidth;\n                    }\n                    lastSpace = null;\n                    lastSpaceWidth = 0;\n\n                    lines.push({\n                        width: curX - letterSpacing,\n                        chars: curLine,\n                    });\n\n                    curX = paraIndentX ?? 0;\n                    curLine = [];\n                }\n\n                // push char\n                curLine.push({\n                    tex: font.tex,\n                    width: q.w,\n                    height: q.h,\n                    // without some padding there'll be visual artifacts on edges\n                    quad: new Quad(\n                        q.x / font.tex.width,\n                        q.y / font.tex.height,\n                        q.w / font.tex.width,\n                        q.h / font.tex.height,\n                    ),\n                    ch: ch,\n                    pos: new Vec2(curX, th),\n                    opacity: opt.opacity ?? 1,\n                    color: opt.color ?? Color.WHITE,\n                    scale: vec2(scale),\n                    angle: 0,\n                });\n\n                if (ch === \" \") {\n                    lastSpace = curLine.length;\n                    lastSpaceWidth = curX;\n                }\n                if (\n                    opt.indentAll && paraIndentX === undefined && /\\S/.test(ch)\n                ) {\n                    paraIndentX = curX;\n                }\n\n                curX += gw;\n                tw = Math.max(tw, curX);\n                curX += letterSpacing;\n            }\n        }\n\n        cursor++;\n    }\n\n    lines.push({\n        width: curX - letterSpacing,\n        chars: curLine,\n    });\n\n    th += size;\n\n    if (opt.width) {\n        tw = opt.width;\n    }\n\n    const fchars: FormattedChar[] = [];\n\n    for (let i = 0; i < lines.length; i++) {\n        const ox = (tw - lines[i].width) * alignPt(opt.align ?? \"left\");\n\n        for (const fchar of lines[i].chars) {\n            const q = font.map[fchar.ch];\n            const idx = fchars.length + i;\n\n            fchar.pos = fchar.pos.add(ox, 0).add(\n                q.w * scale.x * 0.5,\n                q.h * scale.y * 0.5,\n            );\n\n            if (opt.transform) {\n                const tr = typeof opt.transform === \"function\"\n                    ? opt.transform(idx, fchar.ch)\n                    : opt.transform;\n                if (tr) {\n                    applyCharTransform(fchar, tr);\n                }\n            }\n\n            if (charStyleMap[idx]) {\n                const styles = charStyleMap[idx];\n                for (const name of styles) {\n                    const style = opt.styles?.[name];\n                    const tr = typeof style === \"function\"\n                        ? style(idx, fchar.ch)\n                        : style;\n\n                    if (tr) {\n                        applyCharTransform(fchar, tr);\n                    }\n                }\n            }\n\n            fchars.push(fchar);\n        }\n    }\n\n    return {\n        width: tw,\n        height: th,\n        chars: fchars,\n        opt: opt,\n        renderedText: text,\n    };\n}\n", "import { DEF_ANCHOR, UV_PAD } from \"../../constants\";\nimport { rgb } from \"../../math/color\";\nimport { Quad, Vec2 } from \"../../math/math\";\nimport type { DrawUVQuadOpt } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport {\n    popTransform,\n    pushRotate,\n    pushScale,\n    pushTransform,\n    pushTranslate,\n} from \"../stack\";\nimport { drawRaw } from \"./drawRaw\";\n\nexport function drawUVQuad(opt: DrawUVQuadOpt) {\n    if (opt.width === undefined || opt.height === undefined) {\n        throw new Error(\n            \"drawUVQuad() requires property \\\"width\\\" and \\\"height\\\".\",\n        );\n    }\n\n    if (opt.width <= 0 || opt.height <= 0) {\n        return;\n    }\n\n    const w = opt.width;\n    const h = opt.height;\n    const anchor = anchorPt(opt.anchor || DEF_ANCHOR);\n    const offset = anchor.scale(new Vec2(w, h).scale(-0.5));\n    const q = opt.quad || new Quad(0, 0, 1, 1);\n    const color = opt.color || rgb(255, 255, 255);\n    const opacity = opt.opacity ?? 1;\n\n    // apply uv padding to avoid artifacts\n    const uvPadX = opt.tex ? UV_PAD / opt.tex.width : 0;\n    const uvPadY = opt.tex ? UV_PAD / opt.tex.height : 0;\n    const qx = q.x + uvPadX;\n    const qy = q.y + uvPadY;\n    const qw = q.w - uvPadX * 2;\n    const qh = q.h - uvPadY * 2;\n\n    pushTransform();\n    pushTranslate(opt.pos);\n    pushRotate(opt.angle);\n    pushScale(opt.scale);\n    pushTranslate(offset);\n\n    drawRaw(\n        [\n            {\n                pos: new Vec2(-w / 2, h / 2),\n                uv: new Vec2(\n                    opt.flipX ? qx + qw : qx,\n                    opt.flipY ? qy : qy + qh,\n                ),\n                color: color,\n                opacity: opacity,\n            },\n            {\n                pos: new Vec2(-w / 2, -h / 2),\n                uv: new Vec2(\n                    opt.flipX ? qx + qw : qx,\n                    opt.flipY ? qy + qh : qy,\n                ),\n                color: color,\n                opacity: opacity,\n            },\n            {\n                pos: new Vec2(w / 2, -h / 2),\n                uv: new Vec2(\n                    opt.flipX ? qx : qx + qw,\n                    opt.flipY ? qy + qh : qy,\n                ),\n                color: color,\n                opacity: opacity,\n            },\n            {\n                pos: new Vec2(w / 2, h / 2),\n                uv: new Vec2(\n                    opt.flipX ? qx : qx + qw,\n                    opt.flipY ? qy : qy + qh,\n                ),\n                color: color,\n                opacity: opacity,\n            },\n        ],\n        [0, 1, 3, 1, 2, 3],\n        opt.fixed,\n        opt.tex,\n        opt.shader,\n        opt.uniform ?? undefined,\n    );\n\n    popTransform();\n}\n", "import type { Color } from \"../../math/color\";\nimport type { Quad, Vec2 } from \"../../math/math\";\nimport { anchorPt } from \"../anchor\";\nimport type { Texture } from \"../gfx\";\nimport {\n    popTransform,\n    pushRotate,\n    pushTransform,\n    pushTranslate,\n} from \"../stack\";\nimport type { DrawTextOpt } from \"./drawText\";\nimport { drawUVQuad } from \"./drawUVQuad\";\n\n/**\n * Formatted text with info on how and where to render each character.\n */\nexport type FormattedText = {\n    width: number;\n    height: number;\n    chars: FormattedChar[];\n    opt: DrawTextOpt;\n    renderedText: string;\n};\n\n/**\n * One formated character.\n */\nexport interface FormattedChar {\n    ch: string;\n    tex: Texture;\n    width: number;\n    height: number;\n    quad: Quad;\n    pos: Vec2;\n    scale: Vec2;\n    angle: number;\n    color: Color;\n    opacity: number;\n}\n\nexport function drawFormattedText(ftext: FormattedText) {\n    pushTransform();\n    pushTranslate(ftext.opt.pos!);\n    pushRotate(ftext.opt.angle!);\n    pushTranslate(\n        anchorPt(ftext.opt.anchor ?? \"topleft\").add(1, 1).scale(\n            ftext.width,\n            ftext.height,\n        ).scale(-0.5),\n    );\n\n    ftext.chars.forEach((ch) => {\n        drawUVQuad({\n            tex: ch.tex,\n            width: ch.width,\n            height: ch.height,\n            pos: ch.pos,\n            scale: ch.scale,\n            angle: ch.angle,\n            color: ch.color,\n            opacity: ch.opacity,\n            quad: ch.quad,\n            anchor: \"center\",\n            uniform: ftext.opt.uniform,\n            shader: ftext.opt.shader,\n            fixed: ftext.opt.fixed,\n        });\n    });\n\n    popTransform();\n}\n", "import { DEF_ANCHOR } from \"../../constants\";\nimport type { Color } from \"../../math/color\";\nimport { Vec2, vec2 } from \"../../math/math\";\nimport { getArcPts } from \"../../math/various\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport { drawPolygon } from \"./drawPolygon\";\n\n/**\n * How the rectangle should look like.\n */\nexport type DrawRectOpt = RenderProps & {\n    /**\n     * Width of the rectangle.\n     */\n    width: number;\n    /**\n     * Height of the rectangle.\n     */\n    height: number;\n    /**\n     * Use gradient instead of solid color.\n     *\n     * @since v3000.0\n     */\n    gradient?: [Color, Color];\n    /**\n     * If the gradient should be horizontal.\n     *\n     * @since v3000.0\n     */\n    horizontal?: boolean;\n    /**\n     * If fill the shape with color (set this to false if you only want an outline).\n     */\n    fill?: boolean;\n    /**\n     * The radius of each corner.\n     */\n    radius?: number | number[];\n    /**\n     * The anchor point, or the pivot point. Default to \"topleft\".\n     */\n    anchor?: Anchor | Vec2;\n};\n\nexport function drawRect(opt: DrawRectOpt) {\n    if (opt.width === undefined || opt.height === undefined) {\n        throw new Error(\n            \"drawRect() requires property \\\"width\\\" and \\\"height\\\".\",\n        );\n    }\n\n    if (opt.width <= 0 || opt.height <= 0) {\n        return;\n    }\n\n    const w = opt.width;\n    const h = opt.height;\n    const anchor = anchorPt(opt.anchor || DEF_ANCHOR).add(1, 1);\n    const offset = anchor.scale(new Vec2(w, h).scale(-0.5));\n\n    let pts = [\n        new Vec2(0, 0),\n        new Vec2(w, 0),\n        new Vec2(w, h),\n        new Vec2(0, h),\n    ];\n\n    // TODO: gradient for rounded rect\n    // TODO: drawPolygon should handle generic rounded corners\n    if (opt.radius) {\n        // maximum radius is half the shortest side\n        const maxRadius = Math.min(w, h) / 2;\n        const r = Array.isArray(opt.radius)\n            ? opt.radius.map(r => Math.min(maxRadius, r))\n            : new Array(4).fill(Math.min(maxRadius, opt.radius));\n\n        pts = [\n            new Vec2(r[0], 0),\n            ...(r[1]\n                ? getArcPts(new Vec2(w - r[1], r[1]), r[1], r[1], 270, 360)\n                : [vec2(w, 0)]),\n            ...(r[2]\n                ? getArcPts(new Vec2(w - r[2], h - r[2]), r[2], r[2], 0, 90)\n                : [vec2(w, h)]),\n            ...(r[3]\n                ? getArcPts(new Vec2(r[3], h - r[3]), r[3], r[3], 90, 180)\n                : [vec2(0, h)]),\n            ...(r[0]\n                ? getArcPts(new Vec2(r[0], r[0]), r[0], r[0], 180, 270)\n                : []),\n        ];\n    }\n\n    drawPolygon(Object.assign({}, opt, {\n        offset,\n        pts,\n        ...(opt.gradient\n            ? {\n                colors: opt.horizontal\n                    ? [\n                        opt.gradient[0],\n                        opt.gradient[1],\n                        opt.gradient[1],\n                        opt.gradient[0],\n                    ]\n                    : [\n                        opt.gradient[0],\n                        opt.gradient[0],\n                        opt.gradient[1],\n                        opt.gradient[1],\n                    ],\n            }\n            : {}),\n    }));\n}\n", "import { _k } from \"../../kaplay\";\nimport { flush } from \"../stack\";\n\nexport function drawUnscaled(content: () => void) {\n    flush();\n    const ow = _k.gfx.width;\n    const oh = _k.gfx.height;\n    _k.gfx.width = _k.gfx.viewport.width;\n    _k.gfx.height = _k.gfx.viewport.height;\n    content();\n    flush();\n    _k.gfx.width = ow;\n    _k.gfx.height = oh;\n}\n", "import { DBG_FONT } from \"../../constants\";\nimport { rgb } from \"../../math/color\";\nimport { type Vec2, vec2 } from \"../../math/math\";\nimport { formatText } from \"../formatText\";\nimport {\n    height,\n    popTransform,\n    pushTransform,\n    pushTranslate,\n    width,\n} from \"../stack\";\nimport { drawFormattedText } from \"./drawFormattedText\";\nimport { drawRect } from \"./drawRect\";\nimport { drawUnscaled } from \"./drawUnscaled\";\n\nexport function drawInspectText(pos: Vec2, txt: string) {\n    drawUnscaled(() => {\n        const pad = vec2(8);\n\n        pushTransform();\n        pushTranslate(pos);\n\n        const ftxt = formatText({\n            text: txt,\n            font: DBG_FONT,\n            size: 16,\n            pos: pad,\n            color: rgb(255, 255, 255),\n            fixed: true,\n        });\n\n        const bw = ftxt.width + pad.x * 2;\n        const bh = ftxt.height + pad.x * 2;\n\n        if (pos.x + bw >= width()) {\n            pushTranslate(vec2(-bw, 0));\n        }\n\n        if (pos.y + bh >= height()) {\n            pushTranslate(vec2(0, -bh));\n        }\n\n        drawRect({\n            width: bw,\n            height: bh,\n            color: rgb(0, 0, 0),\n            radius: 4,\n            opacity: 0.8,\n            fixed: true,\n        });\n\n        drawFormattedText(ftxt);\n        popTransform();\n    });\n}\n", "import type { Vec2 } from \"../../math/math\";\nimport type { RenderProps } from \"../../types\";\nimport { drawPolygon } from \"./drawPolygon\";\n\n/**\n * How the triangle should look like.\n */\nexport type DrawTriangleOpt = RenderProps & {\n    /**\n     * First point of triangle.\n     */\n    p1: Vec2;\n    /**\n     * Second point of triangle.\n     */\n    p2: Vec2;\n    /**\n     * Third point of triangle.\n     */\n    p3: Vec2;\n    /**\n     * If fill the shape with color (set this to false if you only want an outline).\n     */\n    fill?: boolean;\n    /**\n     * The radius of each corner.\n     */\n    radius?: number;\n};\n\nexport function drawTriangle(opt: DrawTriangleOpt) {\n    if (!opt.p1 || !opt.p2 || !opt.p3) {\n        throw new Error(\n            \"drawTriangle() requires properties \\\"p1\\\", \\\"p2\\\" and \\\"p3\\\".\",\n        );\n    }\n\n    return drawPolygon(Object.assign({}, opt, {\n        pts: [opt.p1, opt.p2, opt.p3],\n    }));\n}\n", "import { DBG_FONT, LOG_TIME } from \"../../constants\";\nimport { _k } from \"../../kaplay\";\nimport { rgb } from \"../../math/color\";\nimport { vec2, wave } from \"../../math/math\";\nimport { formatText } from \"../formatText\";\nimport {\n    height,\n    popTransform,\n    pushTransform,\n    pushTranslate,\n    width,\n} from \"../stack\";\nimport { viewportToCanvas } from \"../viewport.js\";\nimport { drawCircle } from \"./drawCircle\";\nimport { drawFormattedText } from \"./drawFormattedText\";\nimport { drawInspectText } from \"./drawInspectText\";\nimport { drawRect } from \"./drawRect\";\nimport { drawTriangle } from \"./drawTriangle\";\nimport { drawUnscaled } from \"./drawUnscaled\";\n\nexport function drawDebug() {\n    if (_k.debug.inspect) {\n        let inspecting = null;\n\n        for (const obj of _k.game.root.get(\"*\", { recursive: true })) {\n            if (obj.has(\"area\") && obj.isHovering()) {\n                inspecting = obj;\n                break;\n            }\n        }\n\n        _k.game.root.drawInspect();\n\n        if (inspecting) {\n            const lines = [];\n            const data = inspecting.inspect();\n\n            for (const tag in data) {\n                if (data[tag]) {\n                    // pushes the inspect function (eg: `sprite: \"bean\"`)\n                    lines.push(`${data[tag]}`);\n                }\n                else {\n                    // pushes only the tag (name of the component)\n                    lines.push(`${tag}`);\n                }\n            }\n\n            drawInspectText(\n                viewportToCanvas(_k.k.mousePos()),\n                lines.join(\"\\n\"),\n            );\n        }\n\n        drawInspectText(vec2(8), `FPS: ${_k.debug.fps()}`);\n    }\n\n    if (_k.debug.paused) {\n        drawUnscaled(() => {\n            // top right corner\n            pushTransform();\n            pushTranslate(width(), 0);\n            pushTranslate(-8, 8);\n\n            const size = 32;\n\n            // bg\n            drawRect({\n                width: size,\n                height: size,\n                anchor: \"topright\",\n                color: rgb(0, 0, 0),\n                opacity: 0.8,\n                radius: 4,\n                fixed: true,\n            });\n\n            // pause icon\n            for (let i = 1; i <= 2; i++) {\n                drawRect({\n                    width: 4,\n                    height: size * 0.6,\n                    anchor: \"center\",\n                    pos: vec2(-size / 3 * i, size * 0.5),\n                    color: rgb(255, 255, 255),\n                    radius: 2,\n                    fixed: true,\n                });\n            }\n\n            popTransform();\n        });\n    }\n\n    if (_k.debug.timeScale !== 1) {\n        drawUnscaled(() => {\n            // bottom right corner\n            pushTransform();\n            pushTranslate(width(), height());\n            pushTranslate(-8, -8);\n\n            const pad = 8;\n\n            // format text first to get text size\n            const ftxt = formatText({\n                text: _k.debug.timeScale.toFixed(1),\n                font: DBG_FONT,\n                size: 16,\n                color: rgb(255, 255, 255),\n                pos: vec2(-pad),\n                anchor: \"botright\",\n                fixed: true,\n            });\n\n            // bg\n            drawRect({\n                width: ftxt.width + pad * 2 + pad * 4,\n                height: ftxt.height + pad * 2,\n                anchor: \"botright\",\n                color: rgb(0, 0, 0),\n                opacity: 0.8,\n                radius: 4,\n                fixed: true,\n            });\n\n            // fast forward / slow down icon\n            for (let i = 0; i < 2; i++) {\n                const flipped = _k.debug.timeScale < 1;\n                drawTriangle({\n                    p1: vec2(-ftxt.width - pad * (flipped ? 2 : 3.5), -pad),\n                    p2: vec2(\n                        -ftxt.width - pad * (flipped ? 2 : 3.5),\n                        -pad - ftxt.height,\n                    ),\n                    p3: vec2(\n                        -ftxt.width - pad * (flipped ? 3.5 : 2),\n                        -pad - ftxt.height / 2,\n                    ),\n                    pos: vec2(-i * pad * 1 + (flipped ? -pad * 0.5 : 0), 0),\n                    color: rgb(255, 255, 255),\n                    fixed: true,\n                });\n            }\n\n            // text\n            drawFormattedText(ftxt);\n\n            popTransform();\n        });\n    }\n\n    if (_k.debug.curRecording) {\n        drawUnscaled(() => {\n            pushTransform();\n            pushTranslate(0, height());\n            pushTranslate(24, -24);\n\n            drawCircle({\n                radius: 12,\n                color: rgb(255, 0, 0),\n                opacity: wave(0, 1, _k.app.time() * 4),\n                fixed: true,\n            });\n\n            popTransform();\n        });\n    }\n\n    if (_k.debug.showLog && _k.game.logs.length > 0) {\n        drawUnscaled(() => {\n            pushTransform();\n            pushTranslate(0, height());\n            pushTranslate(8, -8);\n\n            const pad = 8;\n            const logs = [];\n\n            for (const log of _k.game.logs) {\n                let str = \"\";\n                const style = log.msg instanceof Error ? \"error\" : \"info\";\n                str += `[time]${log.time.toFixed(2)}[/time]`;\n                str += \" \";\n                str += `[${style}]${prettyDebug(log.msg)}[/${style}]`;\n                logs.push(str);\n            }\n\n            _k.game.logs = _k.game.logs\n                .filter((log) =>\n                    _k.app.time() - log.time\n                        < (_k.globalOpt.logTime || LOG_TIME)\n                );\n\n            const ftext = formatText({\n                text: logs.join(\"\\n\"),\n                font: DBG_FONT,\n                pos: vec2(pad, -pad),\n                anchor: \"botleft\",\n                size: 16,\n                width: width() * 0.6,\n                lineSpacing: pad / 2,\n                fixed: true,\n                styles: {\n                    \"time\": { color: rgb(127, 127, 127) },\n                    \"info\": { color: rgb(255, 255, 255) },\n                    \"error\": { color: rgb(255, 0, 127) },\n                },\n            });\n\n            drawRect({\n                width: ftext.width + pad * 2,\n                height: ftext.height + pad * 2,\n                anchor: \"botleft\",\n                color: rgb(0, 0, 0),\n                radius: 4,\n                opacity: 0.8,\n                fixed: true,\n            });\n\n            drawFormattedText(ftext);\n            popTransform();\n        });\n    }\n}\n\nfunction prettyDebug(\n    object: any | undefined,\n    inside: boolean = false,\n    seen: Set<any> = new Set(),\n): string {\n    if (seen.has(object)) return \"<recursive>\";\n    var outStr = \"\", tmp;\n    if (inside && typeof object === \"string\") {\n        object = JSON.stringify(object);\n    }\n    if (Array.isArray(object)) {\n        outStr = [\n            \"[\",\n            object.map(e => prettyDebug(e, true, seen.union(new Set([object]))))\n                .join(\", \"),\n            \"]\",\n        ].join(\"\");\n        object = outStr;\n    }\n    if (object === null) return \"null\";\n    if (\n        typeof object === \"object\"\n        && object.toString === Object.prototype.toString\n    ) {\n        if (object.constructor !== Object) {\n            outStr += object.constructor.name + \" \";\n        }\n        outStr += [\n            \"{\",\n            (tmp = Object.getOwnPropertyNames(object)\n                    .map(p =>\n                        `${/^\\w+$/.test(p) ? p : JSON.stringify(p)}: ${\n                            prettyDebug(\n                                object[p],\n                                true,\n                                seen.union(new Set([object])),\n                            )\n                        }`\n                    )\n                    .join(\", \"))\n                ? ` ${tmp} `\n                : \"\",\n            \"}\",\n        ].join(\"\");\n        object = outStr;\n    }\n    return String(object).replaceAll(/(?<!\\\\)\\[/g, \"\\\\[\");\n}\n", "import { dt } from \"../../app/frame\";\nimport { _k } from \"../../kaplay\";\nimport { lerp, Mat4, rand, Vec2 } from \"../../math/math\";\nimport { center, flush } from \"../stack\";\n\nexport function drawFrame() {\n    // calculate camera matrix\n    const cam = _k.game.cam;\n    const shake = Vec2.fromAngle(rand(0, 360)).scale(cam.shake);\n\n    cam.shake = lerp(cam.shake, 0, 5 * dt());\n    cam.transform = new Mat4()\n        .translate(center())\n        .scale(cam.scale)\n        .rotate(cam.angle)\n        .translate((cam.pos ?? center()).scale(-1).add(shake));\n\n    _k.game.root.draw();\n    flush();\n}\n", "import { loadProgress } from \"../../assets\";\nimport { _k } from \"../../kaplay\";\nimport { rgb } from \"../../math/color\";\nimport { vec2 } from \"../../math/math\";\nimport { height, width } from \"../stack\";\nimport { drawRect } from \"./drawRect\";\nimport { drawUnscaled } from \"./drawUnscaled\";\n\nexport function drawLoadScreen() {\n    const progress = loadProgress();\n\n    if (_k.game.events.numListeners(\"loading\") > 0) {\n        _k.game.events.trigger(\"loading\", progress);\n    }\n    else {\n        drawUnscaled(() => {\n            const w = width() / 2;\n            const h = 24;\n            const pos = vec2(width() / 2, height() / 2).sub(\n                vec2(w / 2, h / 2),\n            );\n            drawRect({\n                pos: vec2(0),\n                width: width(),\n                height: height(),\n                color: rgb(0, 0, 0),\n            });\n            drawRect({\n                pos: pos,\n                width: w,\n                height: h,\n                fill: false,\n                outline: {\n                    width: 4,\n                },\n            });\n            drawRect({\n                pos: pos,\n                width: w * progress,\n                height: h,\n            });\n        });\n    }\n}\n", "import { _k } from \"../../kaplay\";\nimport { flush } from \"../stack\";\n\nexport function drawStenciled(\n    content: () => void,\n    mask: () => void,\n    test: number,\n) {\n    const gl = _k.gfx.ggl.gl;\n\n    flush();\n    gl.clear(gl.STENCIL_BUFFER_BIT);\n    gl.enable(gl.STENCIL_TEST);\n\n    // don't perform test, pure write\n    gl.stencilFunc(\n        gl.NEVER,\n        1,\n        0xFF,\n    );\n\n    // always replace since we're writing to the buffer\n    gl.stencilOp(\n        gl.REPLACE,\n        gl.REPLACE,\n        gl.REPLACE,\n    );\n\n    mask();\n    flush();\n\n    // perform test\n    gl.stencilFunc(\n        test,\n        1,\n        0xFF,\n    );\n\n    // don't write since we're only testing\n    gl.stencilOp(\n        gl.KEEP,\n        gl.KEEP,\n        gl.KEEP,\n    );\n\n    content();\n    flush();\n    gl.disable(gl.STENCIL_TEST);\n}\n", "import { _k } from \"../../kaplay\";\nimport { drawStenciled } from \"./drawStenciled\";\n\nexport function drawMasked(content: () => void, mask: () => void) {\n    const gl = _k.gfx.ggl.gl;\n\n    drawStenciled(content, mask, gl.EQUAL);\n}\n", "import { DEF_ANCHOR } from \"../../constants\";\nimport { Color } from \"../../math/color\";\nimport { Quad, Vec2 } from \"../../math/math\";\nimport type { DrawTextureOpt, Vertex } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport { drawRaw } from \"./drawRaw\";\nimport { drawUVQuad } from \"./drawUVQuad\";\n\nexport function drawTexture(opt: DrawTextureOpt) {\n    if (!opt.tex) {\n        throw new Error(\"drawTexture() requires property \\\"tex\\\".\");\n    }\n\n    const q = opt.quad ?? new Quad(0, 0, 1, 1);\n    const w = opt.tex.width * q.w;\n    const h = opt.tex.height * q.h;\n    const scale = new Vec2(1);\n\n    if (opt.tiled) {\n        const offset = anchorPt(opt.anchor || DEF_ANCHOR);\n        const offsetX = (opt.pos?.x || 0)\n            - (offset.x + 1) * 0.5 * (opt.width || w);\n        const offsetY = (opt.pos?.y || 0)\n            - (offset.y + 1) * 0.5 * (opt.height || h);\n\n        const fcols = (opt.width || w) / w;\n        const frows = (opt.height || h) / h;\n        const cols = Math.floor(fcols);\n        const rows = Math.floor(frows);\n        const fracX = fcols - cols;\n        const fracY = frows - rows;\n        const n = (cols + fracX ? 1 : 0) * (rows + fracY ? 1 : 0);\n        const indices = new Array<number>(n * 6);\n        const vertices = new Array<Vertex>(n * 4);\n        let index = 0;\n\n        /*drawUVQuad(Object.assign({}, opt, {\n            scale: scale.scale(opt.scale || new Vec2(1)),\n        }));*/\n\n        const addQuad = (\n            x: number,\n            y: number,\n            w: number,\n            h: number,\n            q: Quad,\n        ) => {\n            indices[index * 6 + 0] = index * 4 + 0;\n            indices[index * 6 + 1] = index * 4 + 1;\n            indices[index * 6 + 2] = index * 4 + 3;\n            indices[index * 6 + 3] = index * 4 + 1;\n            indices[index * 6 + 4] = index * 4 + 2;\n            indices[index * 6 + 5] = index * 4 + 3;\n\n            vertices[index * 4 + 0] = {\n                pos: new Vec2(x - offset.x, y - offset.y),\n                uv: new Vec2(q.x, q.y),\n                color: opt.color || Color.WHITE,\n                opacity: opt.opacity || 1,\n            };\n            vertices[index * 4 + 1] = {\n                pos: new Vec2(x + w - offset.x, y - offset.y),\n                uv: new Vec2(q.x + q.w, q.y),\n                color: opt.color || Color.WHITE,\n                opacity: opt.opacity || 1,\n            };\n            vertices[index * 4 + 2] = {\n                pos: new Vec2(x + w - offset.x, y + h - offset.y),\n                uv: new Vec2(q.x + q.w, q.y + q.h),\n                color: opt.color || Color.WHITE,\n                opacity: opt.opacity || 1,\n            };\n            vertices[index * 4 + 3] = {\n                pos: new Vec2(x - offset.x, y + h - offset.y),\n                uv: new Vec2(q.x, q.y + q.h),\n                color: opt.color || Color.WHITE,\n                opacity: opt.opacity || 1,\n            };\n            index++;\n        };\n\n        for (let j = 0; j < rows; j++) {\n            for (let i = 0; i < cols; i++) {\n                addQuad(i * w, j * h, w, h, q);\n            }\n\n            if (fracX) {\n                addQuad(\n                    cols * w,\n                    j * h,\n                    w * fracX,\n                    h,\n                    new Quad(q.x, q.y, q.w * fracX, q.h),\n                );\n            }\n        }\n\n        if (fracY) {\n            for (let i = 0; i < cols; i++) {\n                addQuad(\n                    i * w,\n                    rows * h,\n                    w,\n                    h * fracY,\n                    new Quad(q.x, q.y, q.w, q.h * fracY),\n                );\n            }\n\n            if (fracX) {\n                addQuad(\n                    cols * w,\n                    rows * h,\n                    w * fracX,\n                    h * fracY,\n                    new Quad(q.x, q.y, q.w * fracX, q.h * fracY),\n                );\n            }\n        }\n\n        drawRaw(\n            vertices,\n            indices,\n            opt.fixed,\n            opt.tex,\n            opt.shader,\n            opt.uniform ?? undefined,\n        );\n    }\n    else {\n        // TODO: should this ignore scale?\n        if (opt.width && opt.height) {\n            scale.x = opt.width / w;\n            scale.y = opt.height / h;\n        }\n        else if (opt.width) {\n            scale.x = opt.width / w;\n            scale.y = scale.x;\n        }\n        else if (opt.height) {\n            scale.y = opt.height / h;\n            scale.x = scale.y;\n        }\n\n        drawUVQuad(Object.assign({}, opt, {\n            scale: scale.scale(opt.scale || new Vec2(1)),\n            tex: opt.tex,\n            quad: q,\n            width: w,\n            height: h,\n        }));\n    }\n}\n", "import { type Asset, resolveSprite, type SpriteData } from \"../../assets\";\nimport { Quad, type Vec2 } from \"../../math\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { drawTexture } from \"./drawTexture\";\n\n/**\n * How the sprite should look like.\n */\nexport type DrawSpriteOpt = RenderProps & {\n    /**\n     * The sprite name in the asset manager, or the raw sprite data.\n     */\n    sprite: string | SpriteData | Asset<SpriteData>;\n    /**\n     * If the sprite is loaded with multiple frames, or sliced, use the frame option to specify which frame to draw.\n     */\n    frame?: number;\n    /**\n     * Width of sprite. If `height` is not specified it'll stretch with aspect ratio. If `tiled` is set to true it'll tiled to the specified width horizontally.\n     */\n    width?: number;\n    /**\n     * Height of sprite. If `width` is not specified it'll stretch with aspect ratio. If `tiled` is set to true it'll tiled to the specified width vertically.\n     */\n    height?: number;\n    /**\n     * When set to true, `width` and `height` will not scale the sprite but instead render multiple tiled copies of them until the specified width and height. Useful for background texture pattern etc.\n     */\n    tiled?: boolean;\n    /**\n     * If flip the texture horizontally.\n     */\n    flipX?: boolean;\n    /**\n     * If flip the texture vertically.\n     */\n    flipY?: boolean;\n    /**\n     * The sub-area to render from the texture, by default it'll render the whole `quad(0, 0, 1, 1)`\n     */\n    quad?: Quad;\n    /**\n     * The anchor point, or the pivot point. Default to \"topleft\".\n     */\n    anchor?: Anchor | Vec2;\n    /**\n     * The position\n     */\n    pos?: Vec2;\n};\n\nexport function drawSprite(opt: DrawSpriteOpt) {\n    if (!opt.sprite) {\n        throw new Error(\"drawSprite() requires property \\\"sprite\\\"\");\n    }\n\n    // TODO: slow\n    const spr = resolveSprite(opt.sprite);\n\n    if (!spr || !spr.data) {\n        return;\n    }\n\n    const q = spr.data.frames[opt.frame ?? 0];\n\n    if (!q) {\n        throw new Error(`Frame not found: ${opt.frame ?? 0}`);\n    }\n\n    drawTexture(Object.assign({}, opt, {\n        tex: spr.data.tex,\n        quad: q.scale(opt.quad ?? new Quad(0, 0, 1, 1)),\n    }));\n}\n", "import { _k } from \"../../kaplay\";\nimport { drawStenciled } from \"./drawStenciled\";\n\nexport function drawSubtracted(content: () => void, mask: () => void) {\n    const gl = _k.gfx.ggl.gl;\n\n    drawStenciled(content, mask, gl.NOTEQUAL);\n}\n", "import type { Asset, BitmapFontData } from \"../../assets\";\nimport type { FontData } from \"../../assets/font\";\nimport type { Color } from \"../../math/color\";\nimport type { Vec2 } from \"../../math/math\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { formatText } from \"../formatText\";\nimport { drawFormattedText } from \"./drawFormattedText\";\n\n/**\n * How the text should look like.\n *\n * @group Draw\n */\nexport type DrawTextOpt = RenderProps & {\n    /**\n     * The text to render.\n     */\n    text: string;\n    /**\n     * The name of font to use.\n     */\n    font?:\n        | string\n        | FontData\n        | Asset<FontData>\n        | BitmapFontData\n        | Asset<BitmapFontData>;\n    /**\n     * The size of text (the height of each character).\n     */\n    size?: number;\n    /**\n     * Text alignment (default \"left\")\n     *\n     * @since v3000.0\n     */\n    align?: TextAlign;\n    /**\n     * The maximum width. Will wrap word around if exceed.\n     */\n    width?: number;\n    /**\n     * The gap between each line (only available for bitmap fonts).\n     *\n     * @since v2000.2\n     */\n    lineSpacing?: number;\n    /**\n     * The gap between each character (only available for bitmap fonts).\n     *\n     * @since v2000.2\n     */\n    letterSpacing?: number;\n    /**\n     * The anchor point, or the pivot point. Default to \"topleft\".\n     */\n    anchor?: Anchor | Vec2;\n    /**\n     * Transform the pos, scale, rotation or color for each character based on the index or char (only available for bitmap fonts).\n     *\n     * @since v2000.1\n     */\n    transform?: CharTransform | CharTransformFunc;\n    /**\n     * Stylesheet for styled chunks, in the syntax of \"this is a [stylename]styled[/stylename] word\" (only available for bitmap fonts).\n     *\n     * @since v2000.2\n     */\n    styles?: Record<string, CharTransform | CharTransformFunc>;\n    /**\n     * If true, any (whitespace) indent on the first line of the paragraph\n     * will be copied to all of the lines for those parts that text-wrap.\n     */\n    indentAll?: boolean;\n};\n\n/**\n * A function that returns a character transform config. Useful if you're generating dynamic styles.\n */\nexport type CharTransformFunc = (idx: number, ch: string) => CharTransform;\n\n/**\n * Describes how to transform each character.\n *\n * @group Options\n */\nexport interface CharTransform {\n    /**\n     * Offset to apply to the position of the text character.\n     * Shifts the character's position by the specified 2D vector.\n     */\n    pos?: Vec2;\n\n    /**\n     * Scale transformation to apply to the text character's current scale.\n     * When a number, it is scaled uniformly.\n     * Given a 2D vector, it is scaled independently along the X and Y axis.\n     */\n    scale?: Vec2 | number;\n\n    /**\n     * Increases the amount of degrees to rotate the text character.\n     */\n    angle?: number;\n\n    /**\n     * Color transformation applied to the text character.\n     * Multiplies the current color with this color.\n     */\n    color?: Color;\n\n    /**\n     * Opacity multiplication applied to the text character.\n     * For example, an opacity of 0.4 with 2 set in the transformation, the resulting opacity will be 0.8 (0.4 \u00D7 2).\n     */\n    opacity?: number;\n\n    /**\n     * If true, the styles applied by this specific {@link DrawTextOpt.styles} entry transform\n     * will override, rather than compose with, the default styles given in {@link DrawTextOpt.transform} and by other\n     * components' styles.\n     */\n    override?: boolean;\n}\n\n/**\n * How the text should be aligned.\n *\n * @group Draw\n */\nexport type TextAlign =\n    | \"center\"\n    | \"left\"\n    | \"right\";\n\nexport function drawText(opt: DrawTextOpt) {\n    drawFormattedText(formatText(opt));\n}\n", "import { makeShader, type Uniform } from \"../assets/shader\";\nimport {\n    DEF_FRAG,\n    DEF_VERT,\n    MAX_BATCHED_INDICES,\n    MAX_BATCHED_VERTS,\n    VERTEX_FORMAT,\n} from \"../constants\";\nimport { BatchRenderer, FrameBuffer, type GfxCtx, Texture } from \"../gfx\";\nimport { type Color, rgb } from \"../math/color\";\nimport { Mat4 } from \"../math/math\";\nimport type { KAPLAYOpt } from \"../types\";\n\nexport type AppGfxCtx = ReturnType<typeof initAppGfx>;\n\nexport const initAppGfx = (gopt: KAPLAYOpt, ggl: GfxCtx) => {\n    const defShader = makeShader(ggl, DEF_VERT, DEF_FRAG);\n    const pixelDensity = gopt.pixelDensity ?? 1;\n    const gscale = gopt.scale ?? 1;\n    const { gl } = ggl;\n\n    // a 1x1 white texture to draw raw shapes like rectangles and polygons\n    // we use a texture for those so we can use only 1 pipeline for drawing sprites + shapes\n    const emptyTex = Texture.fromImage(\n        ggl,\n        new ImageData(new Uint8ClampedArray([255, 255, 255, 255]), 1, 1),\n    );\n\n    const frameBuffer = (gopt.width && gopt.height)\n        ? new FrameBuffer(\n            ggl,\n            gopt.width * pixelDensity * gscale,\n            gopt.height * pixelDensity * gscale,\n        )\n        : new FrameBuffer(\n            ggl,\n            gl.drawingBufferWidth,\n            gl.drawingBufferHeight,\n        );\n\n    let bgColor: null | Color = null;\n    let bgAlpha = 1;\n\n    if (gopt.background) {\n        if (typeof gopt.background === \"string\") {\n            bgColor = rgb(gopt.background);\n        }\n        else {\n            bgColor = rgb(...gopt.background);\n            bgAlpha = gopt.background[3] ?? 1;\n        }\n\n        gl.clearColor(\n            bgColor.r / 255,\n            bgColor.g / 255,\n            bgColor.b / 255,\n            bgAlpha ?? 1,\n        );\n    }\n\n    gl.enable(gl.BLEND);\n    gl.blendFuncSeparate(\n        gl.ONE,\n        gl.ONE_MINUS_SRC_ALPHA,\n        gl.ONE,\n        gl.ONE_MINUS_SRC_ALPHA,\n    );\n\n    const renderer = new BatchRenderer(\n        ggl,\n        VERTEX_FORMAT,\n        MAX_BATCHED_VERTS,\n        MAX_BATCHED_INDICES,\n    );\n\n    // a checkerboard texture used for the default background\n    const bgTex = Texture.fromImage(\n        ggl,\n        new ImageData(\n            new Uint8ClampedArray([\n                128,\n                128,\n                128,\n                255,\n                190,\n                190,\n                190,\n                255,\n                190,\n                190,\n                190,\n                255,\n                128,\n                128,\n                128,\n                255,\n            ]),\n            2,\n            2,\n        ),\n        {\n            wrap: \"repeat\",\n            filter: \"nearest\",\n        },\n    );\n\n    return {\n        // how many draw calls we're doing last frame, this is the number we give to users\n        lastDrawCalls: 0,\n        ggl,\n\n        // gfx states\n        defShader: defShader,\n        defTex: emptyTex,\n        frameBuffer: frameBuffer,\n        postShader: null as string | null,\n        postShaderUniform: null as Uniform | (() => Uniform) | null,\n        renderer: renderer,\n\n        transform: new Mat4(),\n        transformStack: [] as Mat4[],\n\n        bgTex: bgTex,\n        bgColor: bgColor,\n        bgAlpha: bgAlpha,\n\n        width: gopt.width\n            ?? gl.drawingBufferWidth / pixelDensity / gscale,\n        height: gopt.height\n            ?? gl.drawingBufferHeight / pixelDensity / gscale,\n\n        viewport: {\n            x: 0,\n            y: 0,\n            width: gl.drawingBufferWidth,\n            height: gl.drawingBufferHeight,\n            scale: 1,\n        },\n\n        fixed: false,\n    };\n};\n", "import type { GameObj } from \"../types\";\n\nexport function isFixed(obj: GameObj): boolean {\n    if (obj.fixed) return true;\n    return obj.parent ? isFixed(obj.parent) : false;\n}\n\nexport function getRenderProps(obj: GameObj<any>) {\n    return {\n        color: obj.color,\n        opacity: obj.opacity,\n        anchor: obj.anchor,\n        outline: obj.outline,\n        shader: obj.shader,\n        uniform: obj.uniform,\n    };\n}\n", "import { getRenderProps } from \"../../game/utils\";\nimport { drawCircle } from \"../../gfx\";\nimport { Rect, Vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { AnchorComp } from \"../transform/anchor\";\nimport type { outline } from \"./outline\";\n\n/**\n * The {@link circle `circle()`} component.\n *\n * @group Component Types\n */\nexport interface CircleComp extends Comp {\n    draw: Comp[\"draw\"];\n    /** Radius of circle. */\n    radius: number;\n    /**\n     * Render area of the circle.\n     *\n     * @since v3000.0\n     */\n    renderArea(): Rect;\n}\n\n/**\n * Options for the {@link circle `circle()``} component.\n *\n * @group Component Types\n */\nexport interface CircleCompOpt {\n    /**\n     * If fill the circle (useful if you only want to render outline with\n     * {@link outline `outline()`} component).\n     */\n    fill?: boolean;\n}\n\nexport function circle(radius: number, opt: CircleCompOpt = {}): CircleComp {\n    return {\n        id: \"circle\",\n        radius: radius,\n        draw(this: GameObj<CircleComp>) {\n            drawCircle(Object.assign(getRenderProps(this), {\n                radius: this.radius,\n                fill: opt.fill,\n            }));\n        },\n        renderArea(this: GameObj<AnchorComp | CircleComp>) {\n            return new Rect(\n                new Vec2(this.anchor ? 0 : -this.radius),\n                this.radius * 2,\n                this.radius * 2,\n            );\n        },\n        inspect() {\n            return `radius: ${Math.ceil(this.radius)}`;\n        },\n    };\n}\n", "import { type Color, type ColorArgs, rgb } from \"../../math/color\";\nimport type { Comp } from \"../../types\";\n\n/**\n * The {@link color `color()`} component.\n *\n * @group Component Types\n */\nexport interface ColorComp extends Comp {\n    color: Color;\n}\n\nexport function color(...args: ColorArgs): ColorComp {\n    return {\n        id: \"color\",\n        color: rgb(...args),\n        inspect() {\n            return `color: ${this.color.toString()}`;\n        },\n    };\n}\n", "import type { FrameBuffer } from \"../../gfx\";\nimport type { GameObj } from \"../../types\";\n\nexport function drawon(c: FrameBuffer) {\n    return {\n        add(this: GameObj) {\n            this.canvas = c;\n        },\n    };\n}\n", "import { dt } from \"../../app\";\nimport { map } from \"../../math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { OpacityComp } from \"./opacity\";\n\nexport function fadeIn(time: number = 1): Comp {\n    let finalOpacity: number;\n    let t = 0;\n    let done = false;\n\n    return {\n        require: [\"opacity\"],\n        add(this: GameObj<OpacityComp>) {\n            finalOpacity = this.opacity;\n            this.opacity = 0;\n        },\n        update(this: GameObj<OpacityComp>) {\n            if (done) return;\n            t += dt();\n            this.opacity = map(t, 0, time, 0, finalOpacity);\n\n            if (t >= time) {\n                this.opacity = finalOpacity;\n                done = true;\n            }\n        },\n    };\n}\n", "import type { Comp, Mask } from \"../../types\";\n\n/**\n * The {@link mask `mask()`} component.\n *\n * @group Component Types\n */\nexport interface MaskComp extends Comp {\n    mask: Mask;\n}\n\nexport function mask(m: Mask = \"intersect\"): MaskComp {\n    return {\n        id: \"mask\",\n        mask: m,\n    };\n}\n", "import { _k } from \"../../kaplay\";\nimport type { Comp, EaseFunc, TweenController } from \"../../types\";\nimport { toFixed } from \"../../utils\";\n\n/**\n * The {@link opacity `opacity()`} component.\n *\n * @group Component Types\n */\nexport interface OpacityComp extends Comp {\n    /** Opacity of the current object. */\n    opacity: number;\n    /** Fade in at the start. */\n    fadeIn(time?: number, easeFunc?: EaseFunc): TweenController;\n    /** Fade out at the start. */\n    fadeOut(time?: number, easeFunc?: EaseFunc): TweenController;\n}\n\nexport function opacity(a: number): OpacityComp {\n    return {\n        id: \"opacity\",\n        opacity: a ?? 1,\n        fadeIn(time = 1, easeFunc = _k.k.easings.linear): TweenController {\n            return _k.game.root.tween(\n                0,\n                this.opacity,\n                time,\n                (a) => this.opacity = a,\n                easeFunc,\n            );\n        },\n        fadeOut(time = 1, easeFunc = _k.k.easings.linear): TweenController {\n            return _k.game.root.tween(\n                this.opacity,\n                0,\n                time,\n                (a) => this.opacity = a,\n                easeFunc,\n            );\n        },\n        inspect() {\n            return `opacity: ${toFixed(this.opacity, 1)}`;\n        },\n    };\n}\n", "import type { LineCap, LineJoin } from \"../../gfx\";\nimport { Color, rgb } from \"../../math/color\";\nimport type { Comp, Outline } from \"../../types\";\n\n/**\n * The {@link outline `outline()`} component.\n *\n * @group Component Types\n */\nexport interface OutlineComp extends Comp {\n    outline: Outline;\n}\n\nexport function outline(\n    width: number = 1,\n    color: Color = rgb(0, 0, 0),\n    opacity: number = 1,\n    join: LineJoin = \"miter\",\n    miterLimit: number = 10,\n    cap: LineCap = \"butt\",\n): OutlineComp {\n    return {\n        id: \"outline\",\n        outline: {\n            width,\n            color,\n            opacity,\n            join,\n            miterLimit,\n            cap,\n        },\n        inspect() {\n            return `outline: ${this.outline.width}px, ${this.outline.color}`;\n        },\n    };\n}\n", "import { dt } from \"../../app\";\nimport { drawRaw, type Texture } from \"../../gfx\";\nimport {\n    Color,\n    lerp,\n    map,\n    Quad,\n    rand,\n    rgb,\n    type ShapeType,\n    Vec2,\n    vec2,\n} from \"../../math\";\nimport type { Comp, Vertex } from \"../../types\";\nimport { KEvent } from \"../../utils/\";\n\n/**\n * A particle. Used on the {@link particles `particles()`} component.\n */\nclass Particle {\n    pos: Vec2 = vec2(0);\n    vel: Vec2 = vec2(0);\n    acc: Vec2 = vec2(0);\n    angle: number = 0;\n    angularVelocity: number = 0;\n    damping: number = 0;\n    t: number;\n    lt: number | null = null;\n    gc: boolean;\n\n    constructor() {\n        this.t = 0;\n        this.gc = true;\n    }\n\n    get progress() {\n        return this.lt ? this.t / this.lt : this.t;\n    }\n}\n\n/**\n * Options for the {@link particles `particles()`}'s component\n */\nexport type EmitterOpt = {\n    /*\n     * Shape of the emitter. If given, particles spwan within this shape.\n     */\n    shape?: ShapeType;\n    /*\n     * Lifetime of the emitter.\n     */\n    lifetime?: number;\n    /*\n     * Rate of emission in particles per second if the emitter should emit out of itself.\n     */\n    rate?: number;\n    /*\n     * Direction of emission.\n     */\n    direction: number;\n    /*\n     * Spread (cone) of emission around the direction.\n     */\n    spread: number;\n};\n\n/**\n * Options for the {@link particles `particles()`}'s component\n *\n * @group Component Types\n */\nexport type ParticlesOpt = {\n    /*\n     * Maximum number of simultaneously rendered particles.\n     */\n    max: number;\n    /*\n     * Minimum and maximum lifetime of a particle in seconds.\n     */\n    lifeTime?: [number, number];\n    /*\n     * Minimum and maximum speed of a particle in pixels per second.\n     */\n    speed?: [number, number];\n    /*\n     * Minimum and maximum acceleration of a particle in pixels per second^2.\n     */\n    acceleration?: [Vec2, Vec2];\n    /*\n     * Minimum and maximum damping of a particle.\n     */\n    damping?: [number, number];\n    /*\n     * Minimum and maximum start angle of a particle.\n     */\n    angle?: [number, number];\n    /*\n     * Minimum and maximum angular velocity of a particle.\n     */\n    angularVelocity?: [number, number];\n    /*\n     * Scale from start to end for a particle.\n     */\n    scales?: number[];\n    /*\n     * Colors from start to end for a particle.\n     */\n    colors?: Color[];\n    /*\n     * Opacity from start to end for a particle.\n     */\n    opacities?: number[];\n    /*\n     * Quads from start to end for a particle.\n     */\n    quads?: Quad[];\n    /*\n     * Texture used for the particle.\n     */\n    texture: Texture;\n};\n\n/**\n * The {@link particles `particles()`} component.\n *\n * @group Component Types\n */\nexport interface ParticlesComp extends Comp {\n    /*\n     * Emit a number of particles\n     */\n    emit(n: number): void;\n    /*\n     * Called when the emitter expires\n     */\n    onEnd(cb: () => void): void;\n}\n\nexport function particles(popt: ParticlesOpt, eopt: EmitterOpt): ParticlesComp {\n    let emitterLifetime = eopt.lifetime;\n\n    const particles: Particle[] = [];\n    const colors = popt.colors || [Color.WHITE];\n    const opacities = popt.opacities || [1];\n    const quads = popt.quads || [new Quad(0, 0, 1, 1)];\n    const scales = popt.scales || [1];\n    const lifetime = popt.lifeTime;\n    const direction = eopt.direction;\n    const spread = eopt.spread;\n    const speed = popt.speed || [0, 0];\n    const angleRange = popt.angle || [0, 0];\n    const angularVelocityRange = popt.angularVelocity || [0, 0];\n    const accelerationRange = popt.acceleration || [vec2(0), vec2(0)];\n    const dampingRange = popt.damping || [0, 0];\n\n    const indices: number[] = [];\n    const vertices: Vertex[] = new Array<Vertex>(popt.max);\n    let count = 0;\n    let time = 0;\n\n    for (let i = 0; i < popt.max; i++) {\n        indices[i * 6 + 0] = i * 4 + 0;\n        indices[i * 6 + 1] = i * 4 + 1;\n        indices[i * 6 + 2] = i * 4 + 3;\n        indices[i * 6 + 3] = i * 4 + 1;\n        indices[i * 6 + 4] = i * 4 + 2;\n        indices[i * 6 + 5] = i * 4 + 3;\n\n        for (let j = 0; j < 4; j++) {\n            vertices[i * 4 + j] = {\n                pos: new Vec2(0, 0),\n                uv: new Vec2(0, 0),\n                color: rgb(255, 255, 255),\n                opacity: 1,\n            };\n        }\n        particles[i] = new Particle();\n    }\n\n    const onEndEvents = new KEvent();\n\n    function nextFree(index: number = 0): number | null {\n        while (index < popt.max) {\n            if (particles[index].gc) {\n                return index;\n            }\n            index++;\n        }\n        return null;\n    }\n\n    return {\n        id: \"particles\",\n        emit(n: number) {\n            let index: number | null = 0;\n            for (let i = 0; i < n; i++) {\n                index = nextFree(index);\n                if (index == null) return;\n\n                const velocityAngle = rand(\n                    direction - spread,\n                    direction + spread,\n                );\n                const vel = Vec2.fromAngle(velocityAngle).scale(\n                    rand(speed[0], speed[1]),\n                );\n                const angle = rand(angleRange[0], angleRange[1]);\n                const angularVelocity = rand(\n                    angularVelocityRange[0],\n                    angularVelocityRange[1],\n                );\n                const acceleration = vec2(\n                    rand(accelerationRange[0].x, accelerationRange[1].x),\n                    rand(accelerationRange[0].y, accelerationRange[1].y),\n                );\n                const damping = rand(\n                    dampingRange[0],\n                    dampingRange[1],\n                );\n                const lt = lifetime ? rand(lifetime[0], lifetime[1]) : null;\n                const pos = eopt.shape\n                    ? eopt.shape.random()\n                    : vec2();\n\n                const p = particles[index];\n                p.lt = lt;\n                p.pos = pos;\n                p.vel = vel;\n                p.acc = acceleration;\n                p.angle = angle;\n                p.angularVelocity = angularVelocity;\n                p.damping = damping;\n                p.angularVelocity = angularVelocity;\n                p.gc = false;\n            }\n            count += n;\n        },\n        update() {\n            if (emitterLifetime !== undefined && emitterLifetime <= 0) {\n                return;\n            }\n            const DT = dt();\n            // Update all particles\n            for (const p of particles) {\n                if (p.gc) {\n                    continue;\n                }\n                p.t += DT;\n                if (p.lt && p.t >= p.lt) {\n                    p.gc = true;\n                    count--;\n                    continue;\n                }\n                p.vel = p.vel.add(p.acc.scale(DT)).scale(1 - p.damping * DT);\n                p.pos = p.pos.add(p.vel.scale(DT));\n                p.angle += p.angularVelocity * DT;\n            }\n            // Check if the emitter has a limited lifetime\n            if (emitterLifetime !== undefined) {\n                emitterLifetime -= DT;\n                if (emitterLifetime <= 0) {\n                    onEndEvents.trigger();\n                }\n            }\n            // Create new particles according to accumulated time\n            time += DT;\n            while (\n                count < popt.max && eopt.rate\n                && time > eopt.rate\n            ) {\n                this.emit(1);\n                count++;\n                time -= eopt.rate;\n            }\n        },\n        draw() {\n            if (emitterLifetime !== undefined && emitterLifetime <= 0) {\n                return;\n            }\n\n            // Draw active particles\n            for (let i = 0; i < particles.length; i++) {\n                const p = particles[i];\n                if (p.gc) {\n                    continue;\n                }\n                const progress = p.progress;\n                const colorIndex = Math.floor(p.progress * colors.length);\n                const color = colorIndex < colors.length - 1\n                    ? lerp(\n                        colors[colorIndex],\n                        colors[colorIndex + 1],\n                        map(\n                            progress,\n                            colorIndex / colors.length,\n                            (colorIndex + 1) / colors.length,\n                            0,\n                            1,\n                        ),\n                    )\n                    : colors[colorIndex];\n                const opacityIndex = Math.floor(p.progress * opacities.length);\n                const opacity = opacityIndex < opacities.length - 1\n                    ? lerp(\n                        opacities[opacityIndex],\n                        opacities[opacityIndex + 1],\n                        map(\n                            progress,\n                            opacityIndex / opacities.length,\n                            (opacityIndex + 1) / opacities.length,\n                            0,\n                            1,\n                        ),\n                    )\n                    : opacities[opacityIndex];\n\n                const quadIndex = Math.floor(p.progress * quads.length);\n                const quad = quads[quadIndex];\n                const scaleIndex = Math.floor(p.progress * scales.length);\n                const scale = scales[scaleIndex];\n                const c = Math.cos(p.angle * Math.PI / 180);\n                const s = Math.sin(p.angle * Math.PI / 180);\n\n                const hw = (popt.texture ? popt.texture.width : 10) * quad.w\n                    / 2;\n                const hh = (popt.texture ? popt.texture.height : 10) * quad.h\n                    / 2;\n\n                let j = i * 4;\n                // Left top\n                let v = vertices[j];\n                v.pos.x = p.pos.x + (-hw) * scale * c - (-hh) * scale * s;\n                v.pos.y = p.pos.y + (-hw) * scale * s + (-hh) * scale * c;\n                v.uv.x = quad.x;\n                v.uv.y = quad.y;\n                v.color.r = color.r;\n                v.color.g = color.g;\n                v.color.b = color.b;\n                v.opacity = opacity;\n                // Right top\n                v = vertices[j + 1];\n                v.pos.x = p.pos.x + hw * scale * c - (-hh) * scale * s;\n                v.pos.y = p.pos.y + hw * scale * s + (-hh) * scale * c;\n                v.uv.x = quad.x + quad.w;\n                v.uv.y = quad.y;\n                v.color.r = color.r;\n                v.color.g = color.g;\n                v.color.b = color.b;\n                v.opacity = opacity;\n                // Right bottom\n                v = vertices[j + 2];\n                v.pos.x = p.pos.x + hw * scale * c - hh * scale * s;\n                v.pos.y = p.pos.y + hw * scale * s + hh * scale * c;\n                v.uv.x = quad.x + quad.w;\n                v.uv.y = quad.y + quad.h;\n                v.color.r = color.r;\n                v.color.g = color.g;\n                v.color.b = color.b;\n                v.opacity = opacity;\n                // Left bottom\n                v = vertices[j + 3];\n                v.pos.x = p.pos.x + (-hw) * scale * c - hh * scale * s;\n                v.pos.y = p.pos.y + (-hw) * scale * s + hh * scale * c;\n                v.uv.x = quad.x;\n                v.uv.y = quad.y + quad.h;\n                v.color.r = color.r;\n                v.color.g = color.g;\n                v.color.b = color.b;\n                v.opacity = opacity;\n            }\n\n            drawRaw(\n                vertices,\n                indices,\n                (this as any).fixed,\n                popt.texture,\n                (this as any).shader,\n                (this as any).uniform,\n            );\n        },\n        onEnd(action: () => void) {\n            return onEndEvents.add(action);\n        },\n        inspect() {\n            return `count: ${count}/${popt.max}`;\n        },\n    };\n}\n", "import { getRenderProps } from \"../../game/utils\";\nimport { drawPolygon, type Texture } from \"../../gfx\";\nimport { type Color } from \"../../math/color\";\nimport { Polygon, type Vec2 } from \"../../math/math\";\nimport type { Comp, DrawPolygonOpt, GameObj } from \"../../types\";\n\n/**\n * The {@link polygon `polygon()`} component.\n *\n * @since v3001.0\n * @group Component Types\n */\nexport interface PolygonComp extends Comp {\n    draw: Comp[\"draw\"];\n    /**\n     * Points in the polygon.\n     */\n    pts: Vec2[];\n    /**\n     * The radius of each corner.\n     */\n    radius?: number | number[];\n    /**\n     * The color of each vertex.\n     */\n    colors?: Color[];\n    /**\n     * The uv of each vertex.\n     *\n     * @since v3001.0\n     */\n    uv?: Vec2[];\n    /**\n     * The texture used when uv coordinates are present.\n     *\n     * @since v3001.0\n     */\n    tex?: Texture;\n    renderArea(): Polygon;\n}\n\n/**\n * Options for the {@link polygon `polygon()`} component.\n *\n * @group Component Types\n */\nexport type PolygonCompOpt = Omit<DrawPolygonOpt, \"pts\">;\n\nexport function polygon(pts: Vec2[], opt: PolygonCompOpt = {}): PolygonComp {\n    if (pts.length < 3) {\n        throw new Error(\n            `Polygon's need more than two points, ${pts.length} points provided`,\n        );\n    }\n    return {\n        id: \"polygon\",\n        pts,\n        colors: opt.colors,\n        uv: opt.uv,\n        tex: opt.tex,\n        radius: opt.radius,\n        draw(this: GameObj<PolygonComp>) {\n            drawPolygon(Object.assign(getRenderProps(this), {\n                pts: this.pts,\n                colors: this.colors,\n                uv: this.uv,\n                tex: this.tex,\n                radius: this.radius,\n                fill: opt.fill,\n                triangulate: opt.triangulate,\n            }));\n        },\n        renderArea(this: GameObj<PolygonComp>) {\n            return new Polygon(this.pts);\n        },\n        inspect() {\n            return `polygon: ${this.pts.map(p => `[${p.x},${p.y}]`).join(\",\")}`;\n        },\n    };\n}\n", "import { _k } from \"../../kaplay\";\nimport type { RaycastResult, Vec2 } from \"../../math/math\";\n\n// this is not a component lol\nexport function raycast(\n    origin: Vec2,\n    direction: Vec2,\n    exclude?: string[],\n) {\n    let minHit: RaycastResult;\n\n    const shapes = _k.game.root.get(\"area\");\n\n    shapes.forEach(s => {\n        if (exclude && exclude.some(tag => s.is(tag))) return;\n        const shape = s.worldArea();\n        const hit = shape.raycast(origin, direction);\n        if (hit) {\n            if (minHit) {\n                if (hit.fraction < minHit.fraction) {\n                    minHit = hit;\n                    minHit!.object = s;\n                }\n            }\n            else {\n                minHit = hit;\n                minHit!.object = s;\n            }\n        }\n    });\n\n    return minHit!;\n}\n", "import { getRenderProps } from \"../../game/utils\";\nimport { drawRect } from \"../../gfx\";\nimport { Rect, vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\n\n/**\n * The {@link rect `rect()`} component.\n *\n * @group Component Types\n */\nexport interface RectComp extends Comp {\n    draw: Comp[\"draw\"];\n    /**\n     * Width of rectangle.\n     */\n    width: number;\n    /**\n     * Height of rectangle.\n     */\n    height: number;\n    /**\n     * The radius of each corner.\n     */\n    radius?: number | [number, number, number, number];\n    /**\n     * @since v3000.0\n     */\n    renderArea(): Rect;\n}\n\n/**\n * Options for the {@link rect `rect()`} component.\n *\n * @group Component Types\n */\nexport interface RectCompOpt {\n    /**\n     * Radius of the rectangle corners.\n     */\n    radius?: number | [number, number, number, number];\n    /**\n     * If fill the rectangle (useful if you only want to render outline with outline() component).\n     */\n    fill?: boolean;\n}\n\nexport function rect(w: number, h: number, opt: RectCompOpt = {}): RectComp {\n    return {\n        id: \"rect\",\n        width: w,\n        height: h,\n        radius: opt.radius || 0,\n        draw(this: GameObj<RectComp>) {\n            drawRect(Object.assign(getRenderProps(this), {\n                width: this.width,\n                height: this.height,\n                radius: this.radius,\n                fill: opt.fill,\n            }));\n        },\n        renderArea() {\n            return new Rect(vec2(0), this.width, this.height);\n        },\n        inspect() {\n            return `rect: (${Math.ceil(this.width)}w, ${\n                Math.ceil(this.height)\n            }h)`;\n        },\n    };\n}\n", "import type { Uniform } from \"../../assets\";\nimport type { Comp } from \"../../types\";\n\n/**\n * The {@link shader `shader()`} component.\n *\n * @group Component Types\n */\nexport interface ShaderComp extends Comp {\n    /**\n     * Uniform values to pass to the shader.\n     */\n    uniform?: Uniform;\n    /**\n     * The shader ID.\n     */\n    shader: string;\n}\n\nexport function shader(\n    id: string,\n    uniform?: Uniform | (() => Uniform),\n): ShaderComp {\n    return {\n        id: \"shader\",\n        shader: id,\n        ...(typeof uniform === \"function\"\n            ? {\n                uniform: uniform(),\n                update() {\n                    this.uniform = uniform();\n                },\n            }\n            : {\n                uniform: uniform,\n            }),\n        inspect() {\n            return `shader: ${id}`;\n        },\n    };\n}\n", "import { pos, type PosComp, tile } from \"../components\";\nimport { _k } from \"../kaplay\";\nimport {\n    raycastGrid,\n    type RaycastResult,\n    type Vec2,\n    vec2,\n    type Vec2Args,\n} from \"../math/math\";\nimport { calcTransform } from \"../math/various\";\nimport type { CompList, GameObj, LevelComp, PathFindOpt } from \"../types\";\nimport { BinaryHeap } from \"../utils\";\n\nenum EdgeMask {\n    None = 0,\n    Left = 1,\n    Top = 2,\n    LeftTop = 3,\n    Right = 4,\n    Horizontal = 5,\n    RightTop = 6,\n    HorizontalTop = 7,\n    Bottom = 8,\n    LeftBottom = 9,\n    Vertical = 10,\n    LeftVertical = 11,\n    RightBottom = 12,\n    HorizontalBottom = 13,\n    RightVertical = 14,\n    All = 15,\n}\n\n/**\n * @group Options\n */\nexport interface LevelOpt {\n    /**\n     * Width of each block.\n     */\n    tileWidth: number;\n    /**\n     * Height of each block.\n     */\n    tileHeight: number;\n    /**\n     * Position of the first block.\n     */\n    pos?: Vec2;\n    /**\n     * Definition of each tile.\n     */\n    tiles: {\n        [sym: string]: (pos: Vec2) => CompList<any>;\n    };\n    /**\n     * Called when encountered a symbol not defined in \"tiles\".\n     */\n    wildcardTile?: (sym: string, pos: Vec2) => CompList<any> | null | undefined;\n}\n\nexport function addLevel(\n    map: string[],\n    opt: LevelOpt,\n): GameObj<PosComp | LevelComp> {\n    if (!opt.tileWidth || !opt.tileHeight) {\n        throw new Error(\"Must provide tileWidth and tileHeight.\");\n    }\n\n    // TODO: custom parent\n    const level = _k.game.root.add([\n        pos(opt.pos ?? vec2(0)),\n    ]) as GameObj<PosComp | LevelComp>;\n\n    const numRows = map.length;\n    let numColumns = 0;\n\n    // The spatial map keeps track of the objects at each location\n    let spatialMap: GameObj[][] | null = null;\n    let costMap: number[] | null = null;\n    let edgeMap: number[] | null = null;\n    let connectivityMap: number[] | null = null;\n\n    const tile2Hash = (tilePos: Vec2) => tilePos.x + tilePos.y * numColumns;\n    const hash2Tile = (hash: number) =>\n        vec2(\n            Math.floor(hash % numColumns),\n            Math.floor(hash / numColumns),\n        );\n\n    const createSpatialMap = () => {\n        spatialMap = [];\n        for (const child of level.children) {\n            insertIntoSpatialMap(child);\n        }\n    };\n\n    const insertIntoSpatialMap = (obj: GameObj) => {\n        const i = tile2Hash(obj.tilePos);\n        if (spatialMap![i]) {\n            spatialMap![i].push(obj);\n        }\n        else {\n            spatialMap![i] = [obj];\n        }\n    };\n\n    const removeFromSpatialMap = (obj: GameObj) => {\n        const i = tile2Hash(obj.tilePos);\n        if (spatialMap![i]) {\n            const index = spatialMap![i].indexOf(obj);\n            if (index >= 0) {\n                spatialMap![i].splice(index, 1);\n            }\n        }\n    };\n\n    const updateSpatialMap = () => {\n        let spatialMapChanged = false;\n        for (const child of level.children) {\n            const tilePos = level.pos2Tile(child.pos);\n            if (\n                child.tilePos.x != tilePos.x || child.tilePos.y != tilePos.y\n            ) {\n                spatialMapChanged = true;\n                removeFromSpatialMap(child);\n                child.tilePos.x = tilePos.x;\n                child.tilePos.y = tilePos.y;\n                insertIntoSpatialMap(child);\n            }\n        }\n        if (spatialMapChanged) {\n            level.trigger(\"spatialMapChanged\");\n        }\n    };\n\n    // The obstacle map tells which tiles are accessible\n    // Cost: accessible with cost\n    // Infinite: inaccessible\n    const createCostMap = () => {\n        const spatialMap = level.getSpatialMap();\n        const size = level.numRows() * level.numColumns();\n        if (!costMap) {\n            costMap = new Array<number>(size);\n        }\n        else {\n            costMap.length = size;\n        }\n        costMap.fill(1, 0, size);\n        for (let i = 0; i < spatialMap.length; i++) {\n            const objects = spatialMap[i];\n            if (objects) {\n                let cost = 0;\n                for (const obj of objects) {\n                    if (obj.isObstacle) {\n                        cost = Infinity;\n                        break;\n                    }\n                    else {\n                        cost += obj.cost;\n                    }\n                }\n                costMap[i] = cost || 1;\n            }\n        }\n    };\n\n    // The edge map tells which edges between nodes are walkable\n    const createEdgeMap = () => {\n        const spatialMap = level.getSpatialMap();\n        const size = level.numRows() * level.numColumns();\n        if (!edgeMap) {\n            edgeMap = new Array<number>(size);\n        }\n        else {\n            edgeMap.length = size;\n        }\n        edgeMap.fill(EdgeMask.All, 0, size);\n        for (let i = 0; i < spatialMap.length; i++) {\n            const objects = spatialMap[i];\n            if (objects) {\n                const len = objects.length;\n                let mask = EdgeMask.All;\n                for (let j = 0; j < len; j++) {\n                    mask |= objects[j].edgeMask;\n                }\n                edgeMap[i] = mask;\n            }\n        }\n    };\n\n    // The connectivity map is used to see whether two locations are connected\n    // -1: inaccesible n: connectivity group\n    const createConnectivityMap = () => {\n        const size = level.numRows() * level.numColumns();\n        const traverse = (i: number, index: number) => {\n            const frontier: number[] = [];\n            frontier.push(i);\n            while (frontier.length > 0) {\n                // TODO: Remove non-null assertion\n                const i = frontier.pop()!;\n\n                getNeighbours(i).forEach((i) => {\n                    if (connectivityMap![i] < 0) {\n                        connectivityMap![i] = index;\n                        frontier.push(i);\n                    }\n                });\n            }\n        };\n        if (!connectivityMap) {\n            connectivityMap = new Array<number>(size);\n        }\n        else {\n            connectivityMap.length = size;\n        }\n        connectivityMap.fill(-1, 0, size);\n        let index = 0;\n        for (let i = 0; i < costMap!.length; i++) {\n            if (connectivityMap[i] >= 0) {\n                index++;\n                continue;\n            }\n            traverse(i, index);\n            index++;\n        }\n    };\n\n    const getCost = (node: number, neighbour: number) => {\n        // Cost of destination tile\n        return costMap![neighbour];\n    };\n\n    const getHeuristic = (node: number, goal: number) => {\n        // Euclidian distance to target\n        const p1 = hash2Tile(node);\n        const p2 = hash2Tile(goal);\n        return p1.dist(p2);\n    };\n\n    const getNeighbours = (node: number, diagonals?: boolean) => {\n        const n = [];\n        const x = Math.floor(node % numColumns);\n        const left = x > 0\n            && (edgeMap![node] & EdgeMask.Left)\n            && costMap![node - 1] !== Infinity;\n        const top = node >= numColumns\n            && (edgeMap![node] & EdgeMask.Top)\n            && costMap![node - numColumns] !== Infinity;\n        const right = x < numColumns - 1\n            && (edgeMap![node] & EdgeMask.Right)\n            && costMap![node + 1] !== Infinity;\n        const bottom = node < numColumns * numRows - numColumns - 1\n            && (edgeMap![node] & EdgeMask.Bottom)\n            && costMap![node + numColumns] !== Infinity;\n        if (diagonals) {\n            if (left) {\n                if (top) n.push(node - numColumns - 1);\n                n.push(node - 1);\n                if (bottom) n.push(node + numColumns - 1);\n            }\n            if (top) {\n                n.push(node - numColumns);\n            }\n            if (right) {\n                if (top) n.push(node - numColumns + 1);\n                n.push(node + 1);\n                if (bottom) n.push(node + numColumns + 1);\n            }\n            if (bottom) {\n                n.push(node + numColumns);\n            }\n        }\n        else {\n            if (left) {\n                n.push(node - 1);\n            }\n            if (top) {\n                n.push(node - numColumns);\n            }\n            if (right) {\n                n.push(node + 1);\n            }\n            if (bottom) {\n                n.push(node + numColumns);\n            }\n        }\n        return n;\n    };\n\n    const levelComp: LevelComp = {\n        id: \"level\",\n\n        tileWidth() {\n            return opt.tileWidth;\n        },\n\n        tileHeight() {\n            return opt.tileHeight;\n        },\n\n        spawn(\n            this: GameObj<LevelComp>,\n            key: string | CompList<any>,\n            ...args: Vec2Args\n        ) {\n            const p = vec2(...args);\n\n            const comps = (() => {\n                if (typeof key === \"string\") {\n                    if (opt.tiles[key]) {\n                        if (typeof opt.tiles[key] !== \"function\") {\n                            throw new Error(\n                                \"Level symbol def must be a function returning a component list\",\n                            );\n                        }\n                        return opt.tiles[key](p);\n                    }\n                    else if (opt.wildcardTile) {\n                        return opt.wildcardTile(key, p);\n                    }\n                }\n                else if (Array.isArray(key)) {\n                    return key;\n                }\n                else {\n                    throw new Error(\n                        \"Expected a symbol or a component list\",\n                    );\n                }\n            })();\n\n            // empty tile\n            if (!comps) {\n                return null;\n            }\n\n            let hasPos = false;\n            let hasTile = false;\n\n            for (const comp of comps) {\n                if (comp.id === \"tile\") hasTile = true;\n                if (comp.id === \"pos\") hasPos = true;\n            }\n\n            if (!hasPos) comps.push(pos(this.tile2Pos(p)));\n            if (!hasTile) comps.push(tile());\n\n            const obj = level.add(comps);\n\n            if (hasPos) {\n                obj.tilePosOffset = obj.pos.clone();\n            }\n\n            obj.tilePos = p;\n            // Stale, so recalculate\n            obj.transform = calcTransform(obj);\n\n            if (spatialMap) {\n                insertIntoSpatialMap(obj);\n                this.trigger(\"spatialMapChanged\");\n                this.trigger(\"navigationMapInvalid\");\n            }\n\n            return obj;\n        },\n\n        numColumns() {\n            return numColumns;\n        },\n\n        numRows() {\n            return numRows;\n        },\n\n        levelWidth() {\n            return numColumns * this.tileWidth();\n        },\n\n        levelHeight() {\n            return numRows * this.tileHeight();\n        },\n\n        tile2Pos(...args: Vec2Args) {\n            return vec2(...args).scale(this.tileWidth(), this.tileHeight());\n        },\n\n        pos2Tile(...args: Vec2Args) {\n            const p = vec2(...args);\n            return vec2(\n                Math.floor(p.x / this.tileWidth()),\n                Math.floor(p.y / this.tileHeight()),\n            );\n        },\n\n        getSpatialMap() {\n            if (!spatialMap) {\n                createSpatialMap();\n            }\n            return spatialMap!;\n        },\n\n        removeFromSpatialMap,\n\n        insertIntoSpatialMap,\n\n        onSpatialMapChanged(this: GameObj<LevelComp>, cb: () => void) {\n            return this.on(\"spatialMapChanged\", cb);\n        },\n\n        onNavigationMapInvalid(this: GameObj<LevelComp>, cb: () => void) {\n            return this.on(\"navigationMapInvalid\", cb);\n        },\n\n        getAt(tilePos: Vec2) {\n            if (!spatialMap) {\n                createSpatialMap();\n            }\n            const hash = tile2Hash(tilePos);\n            return spatialMap![hash] || [];\n        },\n\n        raycast(\n            this: GameObj<LevelComp | PosComp>,\n            origin: Vec2,\n            direction: Vec2,\n        ) {\n            const worldOrigin = this.toWorld(origin);\n            const worldDirection = this.toWorld(origin.add(direction)).sub(\n                worldOrigin,\n            );\n            const invTileWidth = 1 / this.tileWidth();\n            const levelOrigin = origin.scale(invTileWidth);\n            const hit = raycastGrid(levelOrigin, direction, (tilePos: Vec2) => {\n                const tiles = this.getAt(tilePos);\n                if (tiles.some(t => t.isObstacle)) {\n                    return true;\n                }\n                let minHit: RaycastResult = null;\n                for (const tile of tiles) {\n                    if (tile.has(\"area\")) {\n                        const shape = tile.worldArea();\n                        const hit = shape.raycast(\n                            worldOrigin,\n                            worldDirection,\n                        ) as RaycastResult;\n                        if (hit) {\n                            if (minHit) {\n                                if (hit.fraction < minHit.fraction) {\n                                    minHit = hit;\n                                    minHit.object = tile;\n                                }\n                            }\n                            else {\n                                minHit = hit;\n                                minHit.object = tile;\n                            }\n                        }\n                    }\n                }\n                if (minHit) {\n                    minHit.point = this.fromWorld(minHit.point).scale(\n                        invTileWidth,\n                    );\n                }\n                return minHit || false;\n            }, 64);\n            if (hit) {\n                hit.point = hit.point.scale(this.tileWidth());\n            }\n            return hit;\n        },\n\n        update() {\n            if (spatialMap) {\n                updateSpatialMap();\n            }\n        },\n\n        invalidateNavigationMap() {\n            costMap = null;\n            edgeMap = null;\n            connectivityMap = null;\n        },\n\n        onNavigationMapChanged(this: GameObj<LevelComp>, cb: () => void) {\n            return this.on(\"navigationMapChanged\", cb);\n        },\n\n        getTilePath(\n            this: GameObj<LevelComp>,\n            from: Vec2,\n            to: Vec2,\n            opts: PathFindOpt = {},\n        ) {\n            if (!costMap) {\n                createCostMap();\n            }\n            if (!edgeMap) {\n                createEdgeMap();\n            }\n            if (!connectivityMap) {\n                createConnectivityMap();\n            }\n\n            // Tiles are outside the grid\n            if (\n                from.x < 0 || from.x >= numColumns\n                || from.y < 0 || from.y >= numRows\n            ) {\n                return null;\n            }\n            if (\n                to.x < 0 || to.x >= numColumns\n                || to.y < 0 || to.y >= numRows\n            ) {\n                return null;\n            }\n\n            const start = tile2Hash(from);\n            const goal = tile2Hash(to);\n\n            // Tiles are not accessible\n            // If we test the start tile, we may get stuck\n            /*if (costMap[start] === Infinity) {\n                return null\n            }*/\n            if (costMap![goal] === Infinity) {\n                return null;\n            }\n\n            // Same Tile, no waypoints needed\n            if (start === goal) {\n                return [];\n            }\n\n            // Tiles are not within the same section\n            // If we test the start tile when invalid, we may get stuck\n            // TODO: Remove non-null assertion\n            if (\n                connectivityMap![start] != -1\n                && connectivityMap![start] !== connectivityMap![goal]\n            ) {\n                return null;\n            }\n\n            // Find a path\n            interface CostNode {\n                cost: number;\n                node: number;\n            }\n            const frontier = new BinaryHeap<CostNode>((a, b) =>\n                a.cost < b.cost\n            );\n            frontier.insert({ cost: 0, node: start });\n\n            const cameFrom = new Map<number, number>();\n            cameFrom.set(start, start);\n            const costSoFar = new Map<number, number>();\n            costSoFar.set(start, 0);\n\n            while (frontier.length !== 0) {\n                // TODO: Remove non-null assertion\n                const current = frontier.remove()?.node!;\n\n                if (current === goal) {\n                    break;\n                }\n\n                const neighbours = getNeighbours(\n                    current,\n                    opts.allowDiagonals,\n                );\n                for (const next of neighbours) {\n                    const newCost = (costSoFar.get(current) || 0)\n                        + getCost(current, next)\n                        + getHeuristic(next, goal);\n                    if (\n                        !costSoFar.has(next)\n                        // TODO: Remove non-null assertion\n                        || newCost < costSoFar.get(next)!\n                    ) {\n                        costSoFar.set(next, newCost);\n                        frontier.insert({ cost: newCost, node: next });\n                        cameFrom.set(next, current);\n                    }\n                }\n            }\n\n            const path = [];\n            let node = goal;\n            const p = hash2Tile(node);\n            path.push(p);\n\n            while (node !== start) {\n                let cameNode = cameFrom.get(node);\n\n                if (cameNode === undefined) {\n                    throw new Error(\"Bug in pathfinding algorithm\");\n                }\n\n                node = cameNode;\n\n                const p = hash2Tile(node);\n                path.push(p);\n            }\n\n            return path.reverse();\n        },\n\n        getPath(\n            this: GameObj<LevelComp>,\n            from: Vec2,\n            to: Vec2,\n            opts: PathFindOpt = {},\n        ) {\n            const tw = this.tileWidth();\n            const th = this.tileHeight();\n            const path = this.getTilePath(\n                this.pos2Tile(from),\n                this.pos2Tile(to),\n                opts,\n            );\n            if (path) {\n                return [\n                    from,\n                    ...path\n                        .slice(1, -1)\n                        .map((tilePos) =>\n                            tilePos.scale(tw, th).add(tw / 2, th / 2)\n                        ),\n                    to,\n                ];\n            }\n            else {\n                return null;\n            }\n        },\n    };\n\n    level.use(levelComp);\n\n    level.onNavigationMapInvalid(() => {\n        level.invalidateNavigationMap();\n        level.trigger(\"navigationMapChanged\");\n    });\n\n    map.forEach((row, i) => {\n        const keys = row.split(\"\");\n        numColumns = Math.max(keys.length, numColumns);\n        keys.forEach((key, j) => {\n            level.spawn(key, vec2(j, i));\n        });\n    });\n\n    return level;\n}\n", "// add an event to a tag\n\nimport { type Asset, getFailedAssets } from \"../assets\";\nimport { _k } from \"../kaplay\";\nimport type { Collision, GameObj, Tag } from \"../types\";\nimport { KEventController, overload2, Registry } from \"../utils\";\nimport type {\n    GameObjEventMap,\n    GameObjEventNames,\n    GameObjEvents,\n} from \"./eventMap\";\n\nexport type TupleWithoutFirst<T extends any[]> = T extends [infer R, ...infer E]\n    ? E\n    : never;\n\nexport function on<Ev extends GameObjEventNames>(\n    event: Ev,\n    tag: Tag,\n    cb: (obj: GameObj, ...args: TupleWithoutFirst<GameObjEvents[Ev]>) => void,\n): KEventController {\n    if (!_k.game.objEvents.registers[event]) {\n        _k.game.objEvents.registers[event] = new Registry() as any;\n    }\n\n    return _k.game.objEvents.on(\n        <keyof GameObjEventMap> event,\n        (obj, ...args) => {\n            if (obj.is(tag)) {\n                cb(obj, ...args as TupleWithoutFirst<GameObjEvents[Ev]>);\n            }\n        },\n    );\n}\n\nexport const trigger = (event: string, tag: string, ...args: any[]) => {\n    for (const obj of _k.game.root.children) {\n        if (obj.is(tag)) {\n            obj.trigger(event, args);\n        }\n    }\n};\n\nexport const onFixedUpdate = overload2(\n    (action: () => void): KEventController => {\n        const obj = _k.game.root.add([{ fixedUpdate: action }]);\n        return {\n            get paused() {\n                return obj.paused;\n            },\n            set paused(p) {\n                obj.paused = p;\n            },\n            cancel: () => obj.destroy(),\n        };\n    },\n    (tag: Tag, action: (obj: GameObj) => void) => {\n        return on(\"fixedUpdate\", tag, action);\n    },\n);\n\nexport const onUpdate = overload2((action: () => void): KEventController => {\n    const obj = _k.game.root.add([{ update: action }]);\n    return {\n        get paused() {\n            return obj.paused;\n        },\n        set paused(p) {\n            obj.paused = p;\n        },\n        cancel: () => obj.destroy(),\n    };\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"update\", tag, action);\n});\n\nexport const onDraw = overload2((action: () => void): KEventController => {\n    const obj = _k.game.root.add([{ draw: action }]);\n    return {\n        get paused() {\n            return obj.hidden;\n        },\n        set paused(p) {\n            obj.hidden = p;\n        },\n        cancel: () => obj.destroy(),\n    };\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"draw\", tag, action);\n});\n\nexport const onAdd = overload2((action: (obj: GameObj) => void) => {\n    return _k.game.events.on(\"add\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"add\", tag, action);\n});\n\nexport const onDestroy = overload2((action: (obj: GameObj) => void) => {\n    return _k.game.events.on(\"destroy\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"destroy\", tag, action);\n});\n\nexport const onUse = overload2((action: (obj: GameObj, id: string) => void) => {\n    return _k.game.events.on(\"use\", action);\n}, (tag: Tag, action: (obj: GameObj, id: string) => void) => {\n    return on(\"use\", tag, action);\n});\n\nexport const onUnuse = overload2(\n    (action: (obj: GameObj, id: string) => void) => {\n        return _k.game.events.on(\"unuse\", action);\n    },\n    (tag: Tag, action: (obj: GameObj, id: string) => void) => {\n        return on(\"unuse\", tag, action);\n    },\n);\n\nexport const onTag = overload2((action: (obj: GameObj, id: string) => void) => {\n    return _k.game.events.on(\"tag\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"tag\", tag, action);\n});\n\nexport const onUntag = overload2(\n    (action: (obj: GameObj, id: string) => void) => {\n        return _k.game.events.on(\"untag\", action);\n    },\n    (tag: Tag, action: (obj: GameObj) => void) => {\n        return on(\"untag\", tag, action);\n    },\n);\n\n// add an event that runs with objs with t1 collides with objs with t2\nexport function onCollide(\n    t1: Tag,\n    t2: Tag,\n    f: (a: GameObj, b: GameObj, col?: Collision) => void,\n): KEventController {\n    return on(\"collide\", t1, (a, b, col) => b.is(t2) && f(a, b, col));\n}\n\nexport function onCollideUpdate(\n    t1: Tag,\n    t2: Tag,\n    f: (a: GameObj, b: GameObj, col?: Collision) => void,\n): KEventController {\n    return on(\"collideUpdate\", t1, (a, b, col) => b.is(t2) && f(a, b, col));\n}\n\nexport function onCollideEnd(\n    t1: Tag,\n    t2: Tag,\n    f: (a: GameObj, b: GameObj, col?: Collision) => void,\n): KEventController {\n    return on(\"collideEnd\", t1, (a, b, col) => b.is(t2) && f(a, b, col));\n}\n\nexport function forAllCurrentAndFuture(t: Tag, action: (obj: GameObj) => void) {\n    _k.game.root.get(t, { recursive: true }).forEach(action);\n    onAdd(t, action);\n    onTag((obj, tag) => {\n        if (tag === t) {\n            action(obj);\n        }\n    });\n}\n\nexport const onClick = overload2((action: () => void) => {\n    return _k.app.onMousePress(action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    const events: KEventController[] = [];\n\n    forAllCurrentAndFuture(tag, (obj) => {\n        if (!obj.area) {\n            throw new Error(\n                \"onClick() requires the object to have area() component\",\n            );\n        }\n        events.push(obj.onClick(() => action(obj)));\n    });\n    return KEventController.join(events);\n});\n\n// add an event that runs once when objs with tag t is hovered\nexport function onHover(\n    t: Tag,\n    action: (obj: GameObj) => void,\n): KEventController {\n    const events: KEventController[] = [];\n\n    forAllCurrentAndFuture(t, (obj) => {\n        if (!obj.area) {\n            throw new Error(\n                \"onHover() requires the object to have area() component\",\n            );\n        }\n        events.push(obj.onHover(() => action(obj)));\n    });\n    return KEventController.join(events);\n}\n\n// add an event that runs once when objs with tag t is hovered\nexport function onHoverUpdate(\n    t: Tag,\n    action: (obj: GameObj) => void,\n): KEventController {\n    const events: KEventController[] = [];\n\n    forAllCurrentAndFuture(t, (obj) => {\n        if (!obj.area) {\n            throw new Error(\n                \"onHoverUpdate() requires the object to have area() component\",\n            );\n        }\n        events.push(obj.onHoverUpdate(() => action(obj)));\n    });\n    return KEventController.join(events);\n}\n\n// add an event that runs once when objs with tag t is unhovered\nexport function onHoverEnd(\n    t: Tag,\n    action: (obj: GameObj) => void,\n): KEventController {\n    const events: KEventController[] = [];\n\n    forAllCurrentAndFuture(t, (obj) => {\n        if (!obj.area) {\n            throw new Error(\n                \"onHoverEnd() requires the object to have area() component\",\n            );\n        }\n        events.push(obj.onHoverEnd(() => action(obj)));\n    });\n    return KEventController.join(events);\n}\n\nexport function onLoading(action: (progress: number) => void) {\n    _k.game.events.on(\"loading\", action);\n}\n\nexport function onResize(action: () => void) {\n    _k.app.onResize(action);\n}\n\nexport function onError(action: (err: Error) => void) {\n    _k.game.events.on(\"error\", action);\n}\n\nexport function onLoad(cb: () => void): void {\n    if (_k.assets.loaded) {\n        cb();\n    }\n    else {\n        _k.game.events.on(\"load\", cb);\n    }\n}\n\nexport function onLoadError(\n    cb: (name: string, failedAsset: Asset<any>) => void,\n) {\n    if (_k.assets.loaded) {\n        getFailedAssets().forEach(asset => cb(...asset));\n    }\n    else {\n        return _k.game.events.on(\"loadError\", cb);\n    }\n}\n", "import { color, fixed, opacity, rect } from \"../components\";\nimport { center, height, width } from \"../gfx\";\nimport { _k } from \"../kaplay\";\nimport { type Color, rgb } from \"../math/color\";\nimport { type Mat4, type Vec2, vec2, type Vec2Args } from \"../math/math\";\nimport { deprecateMsg } from \"../utils\";\nimport { destroy } from \".\";\n\nexport function setCamPos(...pos: Vec2Args) {\n    _k.game.cam.pos = vec2(...pos);\n}\n\nexport function getCamPos(): Vec2 {\n    return _k.game.cam.pos ? _k.game.cam.pos.clone() : center();\n}\n\nexport function setCamScale(...scale: Vec2Args) {\n    _k.game.cam.scale = vec2(...scale);\n}\n\nexport function getCamScale(): Vec2 {\n    return _k.game.cam.scale.clone();\n}\n\nexport function setCamRot(angle: number) {\n    _k.game.cam.angle = angle;\n}\n\nexport function getCamRot(): number {\n    return _k.game.cam.angle;\n}\n\nexport function getCamTransform(): Mat4 {\n    return _k.game.cam.transform.clone();\n}\n\nexport function flash(\n    flashColor: Color = rgb(255, 255, 255),\n    fadeOutTime: number = 1,\n) {\n    let flash = _k.game.root.add([\n        rect(width(), height()),\n        color(flashColor),\n        opacity(1),\n        fixed(),\n    ]);\n    let fade = flash.fadeOut(fadeOutTime);\n    fade.onEnd(() => destroy(flash));\n    return fade;\n}\n\nexport function camTransform(): Mat4 {\n    return _k.game.cam.transform.clone();\n}\n\nexport function shake(intensity: number = 12) {\n    _k.game.cam.shake += intensity;\n}\n\nexport function toScreen(p: Vec2): Vec2 {\n    return _k.game.cam.transform.multVec2(p);\n}\n\nexport function toWorld(p: Vec2): Vec2 {\n    return _k.game.cam.transform.invert().multVec2(p);\n}\n\nexport function camPos(...pos: Vec2Args): Vec2 {\n    deprecateMsg(\"camPos\", \"setCamPos / getCamPos\");\n\n    if (pos.length > 0) {\n        setCamPos(...pos);\n    }\n    return getCamPos();\n}\n\nexport function camScale(...scale: Vec2Args): Vec2 {\n    deprecateMsg(\"camScale\", \"setCamScale / getCamScale\");\n\n    if (scale.length > 0) {\n        setCamScale(...scale);\n    }\n    return getCamScale();\n}\n\nexport function camRot(angle: number): number {\n    deprecateMsg(\"camRot\", \"setCamRot / getCamRot\");\n\n    if (angle !== undefined) {\n        setCamRot(angle);\n    }\n    return getCamRot();\n}\n\nexport function camFlash(\n    flashColor: Color = rgb(255, 255, 255),\n    fadeOutTime: number = 1,\n) {\n    deprecateMsg(\"camFlash\", \"flash\");\n\n    return flash(flashColor, fadeOutTime);\n}\n", "import type { App } from \"../app\";\nimport type {\n    FixedComp,\n    MaskComp,\n    PosComp,\n    RotateComp,\n    ScaleComp,\n} from \"../components\";\nimport { COMP_DESC, COMP_EVENTS } from \"../constants\";\nimport {\n    flush,\n    popTransform,\n    pushRotate,\n    pushScale,\n    pushTransform,\n    pushTranslate,\n} from \"../gfx\";\nimport { _k } from \"../kaplay\";\nimport { Mat4 } from \"../math/math\";\nimport { calcTransform } from \"../math/various\";\nimport {\n    type Comp,\n    type CompList,\n    type GameObj,\n    type GameObjInspect,\n    type GetOpt,\n    type QueryOpt,\n    type Tag,\n} from \"../types\";\nimport { KEventController, KEventHandler, uid } from \"../utils\";\n\nexport function make<T>(comps: CompList<T> = []): GameObj<T> {\n    const compStates = new Map<string, Comp>();\n    const anonymousCompStates: Comp[] = [];\n    const cleanups = {} as Record<string, (() => unknown)[]>;\n    const events = new KEventHandler();\n    const inputEvents: KEventController[] = [];\n    const tags = new Set<Tag>(\"*\");\n    const treatTagsAsComponents = _k.globalOpt.tagsAsComponents;\n    let onCurCompCleanup: Function | null = null;\n    let paused = false;\n\n    // the game object without the event methods, added later\n    const obj: Omit<GameObj, keyof typeof evs> = {\n        id: uid(),\n        // TODO: a nice way to hide / pause when add()-ing\n        hidden: false,\n        transform: new Mat4(),\n        children: [],\n        parent: null,\n\n        set paused(p) {\n            if (p === paused) return;\n            paused = p;\n            for (const e of inputEvents) {\n                e.paused = p;\n            }\n        },\n\n        get paused() {\n            return paused;\n        },\n\n        get tags() {\n            return Array.from(tags);\n        },\n\n        add<T2>(this: GameObj, a: CompList<T2> | GameObj<T2>): GameObj<T2> {\n            const obj = Array.isArray(a) ? make(a) : a;\n            if (obj.parent) {\n                throw new Error(\n                    \"Cannot add a game obj that already has a parent.\",\n                );\n            }\n            obj.parent = this;\n            obj.transform = calcTransform(obj);\n            this.children.push(obj);\n            // TODO: trigger add for children\n            obj.trigger(\"add\", obj);\n            _k.game.events.trigger(\"add\", obj);\n            return obj;\n        },\n\n        readd(obj: GameObj): GameObj {\n            const idx = this.children.indexOf(obj);\n            if (idx !== -1) {\n                this.children.splice(idx, 1);\n                this.children.push(obj);\n            }\n            return obj;\n        },\n\n        remove(obj: GameObj): void {\n            const idx = this.children.indexOf(obj);\n\n            if (idx !== -1) {\n                obj.parent = null;\n                this.children.splice(idx, 1);\n\n                const trigger = (o: GameObj) => {\n                    o.trigger(\"destroy\");\n                    _k.game.events.trigger(\"destroy\", o);\n                    o.children.forEach((child) => trigger(child));\n                };\n\n                trigger(obj);\n            }\n        },\n\n        // TODO: recursive\n        removeAll(this: GameObj, tag?: Tag) {\n            if (tag) {\n                this.get(tag).forEach((obj) => this.remove(obj));\n            }\n            else {\n                for (const child of [...this.children]) this.remove(child);\n            }\n        },\n\n        fixedUpdate(this: GameObj) {\n            if (this.paused) return;\n            this.children\n                /*.sort((o1, o2) => (o1.z ?? 0) - (o2.z ?? 0))*/\n                .forEach((child) => child.fixedUpdate());\n            this.trigger(\"fixedUpdate\");\n        },\n\n        update(this: GameObj) {\n            if (this.paused) return;\n            this.children\n                /*.sort((o1, o2) => (o1.z ?? 0) - (o2.z ?? 0))*/\n                .forEach((child) => child.update());\n            this.trigger(\"update\");\n        },\n\n        draw(\n            this: GameObj<\n                PosComp | ScaleComp | RotateComp | FixedComp | MaskComp\n            >,\n        ) {\n            if (this.hidden) return;\n            if (this.canvas) {\n                flush();\n                this.canvas.bind();\n            }\n            const f = _k.gfx.fixed;\n            if (this.fixed) _k.gfx.fixed = true;\n            pushTransform();\n            pushTranslate(this.pos);\n            pushScale(this.scale);\n            pushRotate(this.angle);\n            const children = this.children.sort((o1, o2) => {\n                const l1 = o1.layerIndex ?? _k.game.defaultLayerIndex;\n                const l2 = o2.layerIndex ?? _k.game.defaultLayerIndex;\n                return (l1 - l2) || (o1.z ?? 0) - (o2.z ?? 0);\n            });\n            // TODO: automatically don't draw if offscreen\n            if (this.mask) {\n                const maskFunc = {\n                    intersect: _k.k.drawMasked,\n                    subtract: _k.k.drawSubtracted,\n                }[this.mask];\n                if (!maskFunc) {\n                    throw new Error(`Invalid mask func: \"${this.mask}\"`);\n                }\n                maskFunc(() => {\n                    children.forEach((child) => child.draw());\n                }, () => {\n                    this.trigger(\"draw\");\n                });\n            }\n            else {\n                this.trigger(\"draw\");\n                children.forEach((child) => child.draw());\n            }\n            popTransform();\n            _k.gfx.fixed = f;\n            if (this.canvas) {\n                flush();\n                this.canvas.unbind();\n            }\n        },\n\n        drawInspect(this: GameObj<PosComp | ScaleComp | RotateComp>) {\n            if (this.hidden) return;\n            pushTransform();\n            pushTranslate(this.pos);\n            pushScale(this.scale);\n            pushRotate(this.angle);\n            this.children\n                /*.sort((o1, o2) => (o1.z ?? 0) - (o2.z ?? 0))*/\n                .forEach((child) => child.drawInspect());\n            this.trigger(\"drawInspect\");\n            popTransform();\n        },\n\n        // use a comp\n        use(this: GameObj, comp: Comp) {\n            if (typeof comp == \"string\") {\n                // for use add([\"tag\"])\n                return tags.add(comp);\n            }\n            else if (!comp || typeof comp != \"object\") {\n                throw new Error(\n                    `You can only pass a component or a string to .use(), you passed a \"${typeof comp}\"`,\n                );\n            }\n\n            let gc = [];\n\n            // clear if overwrite\n            if (comp.id) {\n                this.unuse(comp.id);\n                cleanups[comp.id] = [];\n                gc = cleanups[comp.id];\n                compStates.set(comp.id, comp);\n                // supporting tagsAsComponents\n                if (treatTagsAsComponents) tags.add(comp.id);\n            }\n            else {\n                anonymousCompStates.push(comp);\n            }\n\n            for (const k in comp) {\n                if (COMP_DESC.has(k)) {\n                    continue;\n                }\n\n                const prop = Object.getOwnPropertyDescriptor(comp, k);\n                if (!prop) continue;\n\n                if (typeof prop.value === \"function\") {\n                    // @ts-ignore\n                    comp[k] = comp[k].bind(this);\n                }\n\n                if (prop.set) {\n                    Object.defineProperty(comp, k, {\n                        set: prop.set.bind(this),\n                    });\n                }\n\n                if (prop.get) {\n                    Object.defineProperty(comp, k, {\n                        get: prop.get.bind(this),\n                    });\n                }\n\n                if (COMP_EVENTS.has(k)) {\n                    // automatically clean up events created by components in add() stage\n                    const func = k === \"add\"\n                        ? () => {\n                            onCurCompCleanup = (c: any) => gc.push(c);\n                            comp[k]?.();\n                            onCurCompCleanup = null;\n                        }\n                        : comp[<keyof typeof comp> k];\n                    gc.push(this.on(k, <any> func).cancel);\n                }\n                else {\n                    if (this[k] === undefined) {\n                        // assign comp fields to game obj\n                        Object.defineProperty(this, k, {\n                            get: () => comp[<keyof typeof comp> k],\n                            set: (val) => comp[<keyof typeof comp> k] = val,\n                            configurable: true,\n                            enumerable: true,\n                        });\n                        gc.push(() => delete this[k]);\n                    }\n                    else {\n                        const originalCompId = compStates.values().find(c =>\n                            (c as any)[k] !== undefined\n                        )?.id;\n                        throw new Error(\n                            `Duplicate component property: \"${k}\" while adding component \"${comp.id}\"`\n                                + (originalCompId\n                                    ? ` (originally added by \"${originalCompId}\")`\n                                    : \"\"),\n                        );\n                    }\n                }\n            }\n\n            // check for component dependencies\n            const checkDeps = () => {\n                if (!comp.require) return;\n                for (const dep of comp.require) {\n                    if (!this.c(dep)) {\n                        throw new Error(\n                            `Component \"${comp.id}\" requires component \"${dep}\"`,\n                        );\n                    }\n                }\n            };\n\n            if (comp.destroy) {\n                gc.push(comp.destroy.bind(this));\n            }\n\n            // manually trigger add event if object already exist\n            if (this.exists()) {\n                checkDeps();\n                if (comp.add) {\n                    onCurCompCleanup = (c: any) => gc.push(c);\n                    comp.add.call(this);\n                    onCurCompCleanup = null;\n                }\n                if (comp.id) {\n                    this.trigger(\"use\", comp.id);\n                    _k.game.events.trigger(\"use\", this, comp.id);\n                }\n            }\n            else {\n                if (comp.require) {\n                    gc.push(this.on(\"add\", checkDeps).cancel);\n                }\n            }\n        },\n\n        // Remove components\n        unuse(this: GameObj, id: string) {\n            if (compStates.has(id)) {\n                // check all components for a dependent, if there's one, throw an error\n                for (const comp of compStates.values()) {\n                    if (comp.require && comp.require.includes(id)) {\n                        throw new Error(\n                            `Can't unuse. Component \"${comp.id}\" requires component \"${id}\"`,\n                        );\n                    }\n                }\n\n                compStates.delete(id);\n\n                this.trigger(\"unuse\", id);\n                _k.game.events.trigger(\"unuse\", this, id);\n            }\n            else if (treatTagsAsComponents && tags.has(id)) {\n                tags.delete(id);\n            }\n\n            if (cleanups[id]) {\n                cleanups[id].forEach((e) => e());\n\n                delete cleanups[id];\n            }\n        },\n\n        c(id: Tag): Comp | null {\n            return compStates.get(id) ?? null;\n        },\n\n        get(t: Tag | Tag[], opts: GetOpt = {}): GameObj[] {\n            const checkTagsOrComps = (child: GameObj, t: Tag | Tag[]) => {\n                if (opts.only === \"comps\") {\n                    return child.has(t);\n                }\n                else if (opts.only === \"tags\") {\n                    return child.is(t);\n                }\n                else {\n                    return child.is(t) || child.has(t);\n                }\n            };\n\n            let list: GameObj[] = opts.recursive\n                ? this.children.flatMap(\n                    function recurse(child: GameObj): GameObj[] {\n                        return [child, ...child.children.flatMap(recurse)];\n                    },\n                )\n                : this.children;\n\n            list = list.filter((child) =>\n                t ? checkTagsOrComps(child, t) : true\n            );\n\n            if (opts.liveUpdate) {\n                const isChild = (obj: GameObj) => {\n                    return opts.recursive\n                        ? this.isAncestorOf(obj)\n                        : obj.parent === this;\n                };\n\n                const events: KEventController[] = [];\n\n                // TODO: handle when object add / remove tags\n                // TODO: clean up when obj destroyed\n                events.push(_k.k.onAdd((obj) => {\n                    if (isChild(obj) && checkTagsOrComps(obj, t)) {\n                        list.push(obj);\n                    }\n                }));\n                events.push(_k.k.onDestroy((obj) => {\n                    if (isChild(obj) && checkTagsOrComps(obj, t)) {\n                        const idx = list.findIndex((o) => o.id === obj.id);\n                        if (idx !== -1) {\n                            list.splice(idx, 1);\n                        }\n                    }\n                }));\n                this.onDestroy(() => {\n                    for (const ev of events) {\n                        ev.cancel();\n                    }\n                });\n            }\n            return list;\n        },\n\n        query(opt: QueryOpt) {\n            const hierarchy = opt.hierarchy || \"children\";\n            const include = opt.include;\n            const exclude = opt.exclude;\n            let list: GameObj[] = [];\n\n            switch (hierarchy) {\n                case \"children\":\n                    list = this.children;\n                    break;\n                case \"siblings\":\n                    list = this.parent\n                        ? this.parent.children.filter((o: GameObj) =>\n                            o !== this\n                        )\n                        : [];\n                    break;\n                case \"ancestors\":\n                    let parent = this.parent;\n                    while (parent) {\n                        list.push(parent);\n                        parent = parent.parent;\n                    }\n                    break;\n                case \"descendants\":\n                    list = this.children.flatMap(\n                        function recurse(child: GameObj): GameObj[] {\n                            return [\n                                child,\n                                ...child.children.flatMap(recurse),\n                            ];\n                        },\n                    );\n                    break;\n            }\n\n            if (include) {\n                const includeOp = opt.includeOp || \"and\";\n\n                if (includeOp === \"and\" || !Array.isArray(opt.include)) {\n                    // Accept if all match\n                    list = list.filter(o => o.is(include));\n                }\n                else { // includeOp == \"or\"\n                    // Accept if some match\n                    list = list.filter(o =>\n                        (opt.include as string[]).some(t => o.is(t))\n                    );\n                }\n            }\n\n            if (exclude) {\n                const excludeOp = opt.includeOp || \"and\";\n                if (excludeOp === \"and\" || !Array.isArray(opt.include)) {\n                    // Reject if all match\n                    list = list.filter(o => !o.is(exclude));\n                }\n                else { // includeOp == \"or\"\n                    // Reject if some match\n                    list = list.filter(o =>\n                        !(opt.exclude as string[]).some(t => o.is(t))\n                    );\n                }\n            }\n\n            if (opt.visible === true) {\n                list = list.filter(o => o.visible);\n            }\n\n            if (opt.distance) {\n                if (!this.pos) {\n                    throw Error(\n                        \"Can't do a distance query from an object without pos\",\n                    );\n                }\n                const distanceOp = opt.distanceOp || \"near\";\n                const sdist = opt.distance * opt.distance;\n                if (distanceOp === \"near\") {\n                    list = list.filter(o =>\n                        o.pos && this.pos.sdist(o.pos) <= sdist\n                    );\n                }\n                else { // distanceOp === \"far\"\n                    list = list.filter(o =>\n                        o.pos && this.pos.sdist(o.pos) > sdist\n                    );\n                }\n            }\n            if (opt.name) {\n                list = list.filter(o => o.name === opt.name);\n            }\n            return list;\n        },\n\n        isAncestorOf(obj: GameObj) {\n            if (!obj.parent) {\n                return false;\n            }\n            return obj.parent === this || this.isAncestorOf(obj.parent);\n        },\n\n        exists(this: GameObj): boolean {\n            return _k.game.root.isAncestorOf(this);\n        },\n\n        // Tags related\n        // Check if gameobj has a tag\n        is(tag: Tag | Tag[], op: \"or\" | \"and\" = \"and\"): boolean {\n            if (Array.isArray(tag)) {\n                if (op === \"and\") {\n                    return tag.every(tag => tags.has(tag));\n                }\n                else {\n                    return tag.some(tag => tags.has(tag));\n                }\n            }\n            else {\n                return tags.has(tag);\n            }\n        },\n\n        // Tag a game object\n        tag(this: GameObj, tag: Tag | Tag[]): void {\n            if (Array.isArray(tag)) {\n                for (const t of tag) {\n                    tags.add(t);\n                    this.trigger(\"tag\", t);\n                    _k.game.events.trigger(\"tag\", this, t);\n                }\n            }\n            else {\n                tags.add(tag);\n                this.trigger(\"tag\", tag);\n                _k.game.events.trigger(\"tag\", this, tag);\n            }\n        },\n\n        // Untag a game object\n        untag(this: GameObj, tag: Tag | Tag[]): void {\n            if (Array.isArray(tag)) {\n                for (const t of tag) {\n                    tags.delete(t);\n                    this.trigger(\"untag\", t);\n                    _k.game.events.trigger(\"untag\", this, t);\n                }\n            }\n            else {\n                tags.delete(tag);\n                this.trigger(\"untag\", tag);\n                _k.game.events.trigger(\"untag\", this, tag);\n            }\n        },\n\n        // Check if gameobj has a component. It also checks many components with\n        has(compList: string | string[], op: \"and\" | \"or\" = \"and\"): boolean {\n            if (Array.isArray(compList)) {\n                if (op === \"and\") {\n                    return compList.every((c) => compStates.has(c));\n                }\n                else {\n                    return compList.some(c => compStates.has(c));\n                }\n            }\n            else {\n                return compStates.has(compList);\n            }\n        },\n\n        on(\n            name: string,\n            action: (...args: unknown[]) => void,\n        ): KEventController {\n            const ctrl = events.on(name, action.bind(this));\n            if (onCurCompCleanup) {\n                onCurCompCleanup(() => ctrl.cancel());\n            }\n            return ctrl;\n        },\n\n        trigger(name: string, ...args: unknown[]): void {\n            events.trigger(name, ...args);\n            _k.game.objEvents.trigger(name, this, ...args);\n        },\n\n        destroy() {\n            if (this.parent) {\n                this.parent.remove(this);\n            }\n        },\n\n        inspect() {\n            const info = {} as GameObjInspect;\n\n            for (const [tag, comp] of compStates) {\n                info[tag] = comp.inspect?.() ?? null;\n            }\n\n            for (const [i, comp] of anonymousCompStates.entries()) {\n                if (comp.inspect) {\n                    info[i] = comp.inspect();\n                    continue;\n                }\n\n                for (const [key, value] of Object.entries(comp)) {\n                    if (typeof value === \"function\") {\n                        continue;\n                    }\n                    else {\n                        info[key] = `${key}: ${value}`;\n                    }\n                }\n            }\n\n            return info;\n        },\n\n        onAdd(cb: () => void): KEventController {\n            return this.on(\"add\", cb);\n        },\n\n        onFixedUpdate(cb: () => void): KEventController {\n            return this.on(\"fixedUpdate\", cb);\n        },\n\n        onUpdate(cb: () => void): KEventController {\n            return this.on(\"update\", cb);\n        },\n\n        onDraw(cb: () => void): KEventController {\n            return this.on(\"draw\", cb);\n        },\n\n        onDestroy(action: () => void): KEventController {\n            return this.on(\"destroy\", action);\n        },\n\n        onUse(action: (id: string) => void): KEventController {\n            return this.on(\"use\", action);\n        },\n\n        onUnuse(action: (id: string) => void): KEventController {\n            return this.on(\"unuse\", action);\n        },\n\n        clearEvents() {\n            events.clear();\n        },\n    };\n\n    const evs = [\n        \"onKeyPress\",\n        \"onKeyPressRepeat\",\n        \"onKeyDown\",\n        \"onKeyRelease\",\n        \"onMousePress\",\n        \"onMouseDown\",\n        \"onMouseRelease\",\n        \"onMouseMove\",\n        \"onCharInput\",\n        \"onMouseMove\",\n        \"onTouchStart\",\n        \"onTouchMove\",\n        \"onTouchEnd\",\n        \"onScroll\",\n        \"onGamepadButtonPress\",\n        \"onGamepadButtonDown\",\n        \"onGamepadButtonRelease\",\n        \"onGamepadStick\",\n        \"onButtonPress\",\n        \"onButtonDown\",\n        \"onButtonRelease\",\n    ] as unknown as [keyof Pick<App, \"onKeyPress\">];\n\n    for (const e of evs) {\n        obj[e] = (...args: [any]) => {\n            const ev = _k.app[e]?.(...args);\n            inputEvents.push(ev);\n\n            obj.onDestroy(() => ev.cancel());\n            obj.on(\"sceneEnter\", () => {\n                // All app events are already canceled by changing the scene\n                // not neccesary -> ev.cancel();\n                inputEvents.splice(inputEvents.indexOf(ev), 1);\n                // create a new event with the same arguments\n                const newEv = _k.app[e]?.(...args);\n\n                // Replace the old event handler with the new one\n                // old KEventController.cancel() => new KEventController.cancel()\n                KEventController.replace(ev, newEv);\n                inputEvents.push(ev);\n            });\n\n            return ev;\n        };\n    }\n\n    for (const comp of comps) {\n        obj.use(comp as string | Comp);\n    }\n\n    return obj as GameObj<T>;\n}\n", "import type { Asset } from \"../assets\";\nimport type { TimerComp } from \"../components\";\nimport type { GameObjEventMap, GameObjEvents } from \"../events\";\nimport { Mat4, Vec2 } from \"../math/math\";\nimport { type GameObj, type Key, type MouseButton } from \"../types\";\nimport { KEventHandler } from \"../utils\";\nimport { make } from \"./make\";\nimport type { SceneDef, SceneName } from \"./scenes\";\n\nexport type Game = ReturnType<typeof initGame>;\n\nexport const initGame = () => {\n    const game = {\n        // general events\n        events: new KEventHandler<{\n            mouseMove: [];\n            mouseDown: [MouseButton];\n            mousePress: [MouseButton];\n            mouseRelease: [MouseButton];\n            charInput: [string];\n            keyPress: [Key];\n            keyDown: [Key];\n            keyPressRepeat: [Key];\n            keyRelease: [Key];\n            touchStart: [Vec2, Touch];\n            touchMove: [Vec2, Touch];\n            touchEnd: [Vec2, Touch];\n            gamepadButtonDown: [string];\n            gamepadButtonPress: [string];\n            gamepadButtonRelease: [string];\n            gamepadStick: [string, Vec2];\n            gamepadConnect: [Gamepad];\n            gamepadDisconnect: [Gamepad];\n            scroll: [Vec2];\n            add: [GameObj];\n            destroy: [GameObj];\n            use: [GameObj, string];\n            unuse: [GameObj, string];\n            tag: [GameObj, string];\n            untag: [GameObj, string];\n            load: [];\n            loadError: [string, Asset<any>];\n            loading: [number];\n            error: [Error];\n            input: [];\n            frameEnd: [];\n            resize: [];\n            sceneLeave: [string];\n            sceneEnter: [string];\n        }>(),\n\n        // object events\n        objEvents: new KEventHandler<GameObjEvents>(),\n\n        // root game object\n        root: make([]) as GameObj<TimerComp>,\n\n        // misc\n        gravity: null as Vec2 | null,\n        scenes: {} as Record<SceneName, SceneDef>,\n        currentScene: null as SceneName | null,\n        layers: null as string[] | null,\n        defaultLayerIndex: 0,\n\n        // on screen log\n        logs: [] as { msg: string | { toString(): string }; time: number }[],\n\n        // camera\n        cam: {\n            pos: null as Vec2 | null,\n            scale: new Vec2(1),\n            angle: 0,\n            shake: 0,\n            transform: new Mat4(),\n        },\n    };\n\n    return game;\n};\n", "import { _k } from \"../kaplay\";\nimport { type Vec2, vec2 } from \"../math\";\n\nexport function setGravity(g: number) {\n    // If g > 0 use either the current direction or use (0, 1)\n    // Else null\n    _k.game.gravity = g\n        ? (_k.game.gravity || vec2(0, 1)).unit().scale(g)\n        : null;\n}\n\nexport function getGravity() {\n    // If gravity > 0 return magnitude\n    // Else 0\n    return _k.game.gravity ? _k.game.gravity.len() : 0;\n}\n\nexport function setGravityDirection(d: Vec2) {\n    // If gravity > 0 keep magnitude, otherwise use 1\n    _k.game.gravity = d.unit().scale(\n        _k.game.gravity ? _k.game.gravity.len() : 1,\n    );\n}\n\nexport function getGravityDirection() {\n    // If gravity != null return unit vector, otherwise return (0, 1)\n    return _k.game.gravity ? _k.game.gravity.unit() : vec2(0, 1);\n}\n", "import { SoundData } from \"../assets\";\nimport { createEmptyAudioBuffer } from \"../gfx\";\nimport burpSoundSrc from \"../kassets/burp.mp3\";\n\nexport type AudioCtx = ReturnType<typeof initAudio>;\n\nexport const initAudio = () => {\n    const audio = (() => {\n        const ctx = new (\n            window.AudioContext || (window as any).webkitAudioContext\n        )() as AudioContext;\n\n        const masterNode = ctx.createGain();\n        masterNode.connect(ctx.destination);\n\n        // by default browsers can only load audio async, we don't deal with that and just start with an empty audio buffer\n        const burpSnd = new SoundData(createEmptyAudioBuffer(ctx));\n\n        // load that burp sound\n        ctx.decodeAudioData(burpSoundSrc.buffer.slice(0)).then((buf) => {\n            burpSnd.buf = buf;\n        }).catch((err) => {\n            console.error(\"Failed to load burp: \", err);\n        });\n\n        return {\n            ctx,\n            masterNode,\n            burpSnd,\n        };\n    })();\n\n    return audio;\n};\n", "import { _k } from \"../kaplay\";\nimport { clamp } from \"../math/clamp\";\nimport { KEvent } from \"../utils\";\nimport type { AudioPlay, AudioPlayOpt } from \"./play\";\n\nexport function playMusic(url: string, opt: AudioPlayOpt = {}): AudioPlay {\n    const onEndEvents = new KEvent();\n    const el = new Audio(url);\n    el.crossOrigin = \"anonymous\";\n    el.loop = Boolean(opt.loop);\n\n    const src = _k.audio.ctx.createMediaElementSource(el);\n\n    src.connect(_k.audio.masterNode);\n\n    function resumeAudioCtx() {\n        if (_k.debug.paused) return;\n        if (_k.app.isHidden() && !_k.globalOpt.backgroundAudio) return;\n        _k.audio.ctx.resume();\n    }\n\n    function play() {\n        resumeAudioCtx();\n        el.play();\n    }\n\n    if (!opt.paused) {\n        play();\n    }\n\n    el.onended = () => onEndEvents.trigger();\n\n    return {\n        play() {\n            play();\n        },\n\n        seek(time: number) {\n            el.currentTime = time;\n        },\n\n        stop() {\n            el.pause();\n            this.seek(0);\n        },\n\n        set loop(l: boolean) {\n            el.loop = l;\n        },\n\n        get loop() {\n            return el.loop;\n        },\n\n        set paused(p: boolean) {\n            if (p) {\n                el.pause();\n            }\n            else {\n                play();\n            }\n        },\n\n        get paused() {\n            return el.paused;\n        },\n\n        time() {\n            return el.currentTime;\n        },\n\n        duration() {\n            return el.duration;\n        },\n\n        set volume(val: number) {\n            el.volume = clamp(val, 0, 1);\n        },\n\n        get volume() {\n            return el.volume;\n        },\n\n        set speed(s) {\n            el.playbackRate = Math.max(s, 0);\n        },\n\n        get speed() {\n            return el.playbackRate;\n        },\n\n        set detune(d) {\n            // TODO\n        },\n\n        get detune() {\n            // TODO\n            return 0;\n        },\n\n        onEnd(action: () => void) {\n            return onEndEvents.add(action);\n        },\n\n        then(action: () => void) {\n            return this.onEnd(action);\n        },\n    };\n}\n", "import { Asset, resolveSound, type SoundData } from \"../assets\";\nimport { _k } from \"../kaplay\";\nimport type { MusicData } from \"../types\";\nimport { KEvent, type KEventController } from \"../utils\";\nimport { playMusic } from \"./playMusic\";\n\n// TODO: enable setting on load, make part of SoundData\n/**\n * Audio play configurations.\n */\nexport interface AudioPlayOpt {\n    /**\n     * If audio should start out paused.\n     *\n     * @since v3000.0\n     */\n    paused?: boolean;\n    /**\n     * If audio should be played again from start when its ended.\n     */\n    loop?: boolean;\n    /**\n     * Volume of audio. 1.0 means full volume, 0.5 means half volume.\n     */\n    volume?: number;\n    /**\n     * Playback speed. 1.0 means normal playback speed, 2.0 means twice as fast.\n     */\n    speed?: number;\n    /**\n     * Detune the sound. Every 100 means a semitone.\n     *\n     * @example\n     * ```js\n     * // play a random note in the octave\n     * play(\"noteC\", {\n     *     detune: randi(0, 12) * 100,\n     * })\n     * ```\n     */\n    detune?: number;\n    /**\n     * The start time, in seconds.\n     */\n    seek?: number;\n    /**\n     * The stereo pan of the sound.\n     * -1.0 means fully from the left channel, 0.0 means centered, 1.0 means fully right.\n     * Defaults to 0.0.\n     */\n    pan?: number;\n}\n\nexport interface AudioPlay {\n    /**\n     * Start playing audio.\n     *\n     * @since v3000.0\n     */\n    play(time?: number): void;\n    /**\n     * Seek time.\n     *\n     * @since v3000.0\n     */\n    seek(time: number): void;\n    /**\n     * Stop the sound.\n     *\n     * @since v3001.0\n     */\n    stop(): void;\n    /**\n     * If the sound is paused.\n     *\n     * @since v2000.1\n     */\n    paused: boolean;\n    /**\n     * Playback speed of the sound. 1.0 means normal playback speed, 2.0 means twice as fast.\n     */\n    speed: number;\n    /**\n     * Detune the sound. Every 100 means a semitone.\n     *\n     * @example\n     * ```js\n     * // tune down a semitone\n     * music.detune = -100\n     *\n     * // tune up an octave\n     * music.detune = 1200\n     * ```\n     */\n    detune: number;\n    /**\n     * Volume of the sound. 1.0 means full volume, 0.5 means half volume.\n     */\n    volume: number;\n    /**\n     * The stereo pan of the sound.\n     * -1.0 means fully from the left channel, 0.0 means centered, 1.0 means fully right.\n     * Defaults to 0.0.\n     */\n    pan?: number;\n    /**\n     * If the audio should start again when it ends.\n     */\n    loop: boolean;\n    /**\n     * The current playing time (not accurate if speed is changed).\n     */\n    time(): number;\n    /**\n     * The total duration.\n     */\n    duration(): number;\n    /**\n     * Register an event that runs when audio ends.\n     *\n     * @since v3000.0\n     */\n    onEnd(action: () => void): KEventController;\n    then(action: () => void): KEventController;\n}\n\nexport function play(\n    src:\n        | string\n        | SoundData\n        | Asset<SoundData>\n        | MusicData\n        | Asset<MusicData>,\n    opt: AudioPlayOpt = {},\n): AudioPlay {\n    if (typeof src === \"string\" && _k.assets.music[src]) {\n        return playMusic(_k.assets.music[src], opt);\n    }\n\n    const ctx = _k.audio.ctx;\n    let paused = opt.paused ?? false;\n    let srcNode = ctx.createBufferSource();\n    const onEndEvents = new KEvent();\n    const gainNode = ctx.createGain();\n    const panNode = ctx.createStereoPanner();\n    const pos = opt.seek ?? 0;\n    let startTime = 0;\n    let stopTime = 0;\n    let started = false;\n\n    srcNode.loop = Boolean(opt.loop);\n    srcNode.detune.value = opt.detune ?? 0;\n    srcNode.playbackRate.value = opt.speed ?? 1;\n    srcNode.connect(panNode);\n    srcNode.onended = () => {\n        if (\n            getTime()\n                >= (srcNode.buffer?.duration ?? Number.POSITIVE_INFINITY)\n        ) {\n            onEndEvents.trigger();\n        }\n    };\n    panNode.pan.value = opt.pan ?? 0;\n    panNode.connect(gainNode);\n    gainNode.connect(_k.audio.masterNode);\n    gainNode.gain.value = opt.volume ?? 1;\n\n    const start = (data: SoundData) => {\n        srcNode.buffer = data.buf;\n        if (!paused) {\n            startTime = ctx.currentTime;\n            srcNode.start(0, pos);\n            started = true;\n        }\n    };\n\n    // @ts-ignore\n    const snd = resolveSound(src);\n\n    if (snd instanceof Asset) {\n        snd.onLoad(start);\n    }\n\n    const getTime = () => {\n        if (!srcNode.buffer) return 0;\n        const t = paused\n            ? stopTime - startTime\n            : ctx.currentTime - startTime;\n        const d = srcNode.buffer.duration;\n        return srcNode.loop ? t % d : Math.min(t, d);\n    };\n\n    const cloneNode = (oldNode: AudioBufferSourceNode) => {\n        const newNode = ctx.createBufferSource();\n        newNode.buffer = oldNode.buffer;\n        newNode.loop = oldNode.loop;\n        newNode.playbackRate.value = oldNode.playbackRate.value;\n        newNode.detune.value = oldNode.detune.value;\n        newNode.onended = oldNode.onended;\n        newNode.connect(panNode);\n        return newNode;\n    };\n\n    return {\n        stop() {\n            this.paused = true;\n            this.seek(0);\n        },\n\n        set paused(p: boolean) {\n            if (paused === p) return;\n            paused = p;\n            if (p) {\n                if (started) {\n                    srcNode.stop();\n                    started = false;\n                }\n                stopTime = ctx.currentTime;\n            }\n            else {\n                srcNode = cloneNode(srcNode);\n                const pos = stopTime - startTime;\n                srcNode.start(0, pos);\n                started = true;\n                startTime = ctx.currentTime - pos;\n                stopTime = 0;\n            }\n        },\n\n        get paused() {\n            return paused;\n        },\n\n        play(time: number = 0) {\n            this.seek(time);\n            this.paused = false;\n        },\n\n        seek(time: number) {\n            if (!srcNode.buffer?.duration) return;\n            if (time > srcNode.buffer.duration) return;\n            if (paused) {\n                srcNode = cloneNode(srcNode);\n                startTime = stopTime - time;\n            }\n            else {\n                srcNode.stop();\n                srcNode = cloneNode(srcNode);\n                startTime = ctx.currentTime - time;\n                srcNode.start(0, time);\n                started = true;\n                stopTime = 0;\n            }\n        },\n\n        // TODO: affect time()\n        set speed(val: number) {\n            srcNode.playbackRate.value = val;\n        },\n\n        get speed() {\n            return srcNode.playbackRate.value;\n        },\n\n        set detune(val: number) {\n            srcNode.detune.value = val;\n        },\n\n        get detune() {\n            return srcNode.detune.value;\n        },\n\n        set volume(val: number) {\n            gainNode.gain.value = Math.max(val, 0);\n        },\n\n        get volume() {\n            return gainNode.gain.value;\n        },\n\n        set pan(pan: number) {\n            panNode.pan.value = pan;\n        },\n\n        get pan() {\n            return panNode.pan.value;\n        },\n\n        set loop(l: boolean) {\n            srcNode.loop = l;\n        },\n\n        get loop() {\n            return srcNode.loop;\n        },\n\n        duration(): number {\n            return srcNode.buffer?.duration ?? 0;\n        },\n\n        time(): number {\n            return getTime() % this.duration();\n        },\n\n        onEnd(action: () => void) {\n            return onEndEvents.add(action);\n        },\n\n        then(action: () => void) {\n            return this.onEnd(action);\n        },\n    };\n}\n", "import { _k } from \"../kaplay\";\nimport { type AudioPlay, type AudioPlayOpt, play } from \"./play\";\n\n// core KAPLAY logic\nexport function burp(opt?: AudioPlayOpt): AudioPlay {\n    return _k.k.play(_k.audio.burpSnd, opt);\n}\n", "import { _k } from \"../kaplay\";\nimport { deprecate, deprecateMsg } from \"../utils\";\n\nexport function setVolume(v: number) {\n    _k.audio.masterNode.gain.value = v;\n}\n\nexport function getVolume() {\n    return _k.audio.masterNode.gain.value;\n}\n\n// get / set master volume\nexport function volume(v?: number): number {\n    deprecateMsg(\"volume\", \"setVolume / getVolume\");\n\n    if (v !== undefined) {\n        setVolume(v);\n    }\n    return getVolume();\n}\n", "import { burp } from \"../audio\";\nimport { FrameBuffer, updateViewport } from \"../gfx\";\nimport { _k } from \"../kaplay\";\nimport { clamp } from \"../math/clamp\";\nimport { toFixed } from \"../utils\";\n\nexport function initEvents() {\n    _k.app.onHide(() => {\n        if (!_k.globalOpt.backgroundAudio) {\n            _k.audio.ctx.suspend();\n        }\n    });\n\n    _k.app.onShow(() => {\n        if (!_k.globalOpt.backgroundAudio && !_k.debug.paused) {\n            _k.audio.ctx.resume();\n        }\n    });\n\n    _k.app.onResize(() => {\n        if (_k.app.isFullscreen()) return;\n        const fixedSize = _k.globalOpt.width && _k.globalOpt.height;\n        if (fixedSize && !_k.globalOpt.stretch && !_k.globalOpt.letterbox) {\n            return;\n        }\n\n        _k.canvas.width = _k.canvas.offsetWidth * _k.pixelDensity;\n        _k.canvas.height = _k.canvas.offsetHeight * _k.pixelDensity;\n\n        updateViewport();\n\n        if (!fixedSize) {\n            _k.gfx.frameBuffer.free();\n            _k.gfx.frameBuffer = new FrameBuffer(\n                _k.gfx.ggl,\n                _k.gfx.ggl.gl.drawingBufferWidth,\n                _k.gfx.ggl.gl.drawingBufferHeight,\n            );\n            _k.gfx.width = _k.gfx.ggl.gl.drawingBufferWidth / _k.pixelDensity\n                / _k.gscale;\n            _k.gfx.height = _k.gfx.ggl.gl.drawingBufferHeight / _k.pixelDensity\n                / _k.gscale;\n        }\n    });\n\n    if (_k.globalOpt.debug !== false) {\n        _k.app.onKeyPress(\n            _k.globalOpt.debugKey ?? \"f1\",\n            () => _k.debug.inspect = !_k.debug.inspect,\n        );\n        _k.app.onKeyPress(\"f2\", () => _k.debug.clearLog());\n        _k.app.onKeyPress(\"f8\", () => _k.debug.paused = !_k.debug.paused);\n        _k.app.onKeyPress(\"f7\", () => {\n            _k.debug.timeScale = toFixed(\n                clamp(_k.debug.timeScale - 0.2, 0, 2),\n                1,\n            );\n        });\n        _k.app.onKeyPress(\"f9\", () => {\n            _k.debug.timeScale = toFixed(\n                clamp(_k.debug.timeScale + 0.2, 0, 2),\n                1,\n            );\n        });\n        _k.app.onKeyPress(\"f10\", () => _k.debug.stepFrame());\n    }\n\n    // burp mode initialization\n    if (_k.globalOpt.burp) {\n        _k.app.onKeyPress(\"b\", () => burp());\n    }\n}\n", "import { anchor, boom, pos, scale, sprite, stay, timer } from \"../components\";\nimport { _k } from \"../kaplay\";\nimport type { Vec2 } from \"../math\";\nimport type { CompList, GameObj } from \"../types\";\n\n/**\n * @group Options\n */\nexport interface BoomOpt {\n    /**\n     * Animation speed.\n     */\n    speed?: number;\n    /**\n     * Scale.\n     */\n    scale?: number;\n    /**\n     * Additional components.\n     *\n     * @since v3000.0\n     */\n    comps?: CompList<any>;\n}\n\nexport function addKaboom(p: Vec2, opt: BoomOpt = {}): GameObj {\n    const kaboom = _k.game.root.add([\n        pos(p),\n        stay(),\n    ]);\n\n    const speed = (opt.speed || 1) * 5;\n    const s = opt.scale || 1;\n\n    kaboom.add([\n        sprite(_k.boomSprite),\n        scale(0),\n        anchor(\"center\"),\n        boom(speed, s),\n        ...opt.comps ?? [],\n    ]);\n\n    const ka = kaboom.add([\n        sprite(_k.kaSprite),\n        scale(0),\n        anchor(\"center\"),\n        timer(),\n        ...opt.comps ?? [],\n    ]);\n\n    ka.wait(0.4 / speed, () => ka.use(boom(speed, s)));\n    ka.onDestroy(() => kaboom.destroy());\n\n    return kaboom;\n}\n", "import { _k } from \"../kaplay\";\nimport { deprecateMsg } from \"../utils\";\n\nexport function setLayers(layerNames: string[], defaultLayer: string) {\n    if (_k.game.layers) {\n        throw Error(\"Layers can only be assigned once.\");\n    }\n    const defaultLayerIndex = layerNames.indexOf(defaultLayer);\n    if (defaultLayerIndex == -1) {\n        throw Error(\n            \"The default layer name should be present in the layers list.\",\n        );\n    }\n    _k.game.layers = layerNames;\n    _k.game.defaultLayerIndex = defaultLayerIndex;\n}\n\nexport function getLayers() {\n    return _k.game.layers;\n}\n\nexport function getDefaultLayer() {\n    return _k.game.layers?.[_k.game.defaultLayerIndex] ?? null;\n}\n\nexport function layers(layerNames: string[], defaultLayer: string) {\n    deprecateMsg(\"layers\", \"setLayers\");\n    setLayers(layerNames, defaultLayer);\n}\n", "import { _k } from \"../kaplay\";\nimport type { GameObj } from \"../types\";\n\nexport function destroy(obj: GameObj) {\n    obj.destroy();\n}\n\nexport function getTreeRoot(): GameObj {\n    return _k.game.root;\n}\n", "import { _k } from \"../kaplay\";\nimport { Mat4, vec2 } from \"../math/math\";\nimport type { KEventController } from \"../utils\";\nimport { initEvents } from \"./initEvents\";\n\n/**\n * The name of a scene.\n */\nexport type SceneName = string;\nexport type SceneDef = (...args: any) => void;\n\nexport function scene(id: SceneName, def: SceneDef) {\n    _k.game.scenes[id] = def;\n}\n\nexport function go(name: SceneName, ...args: unknown[]) {\n    if (!_k.game.scenes[name]) {\n        throw new Error(`Scene not found: ${name}`);\n    }\n\n    _k.game.events.onOnce(\"frameEnd\", () => {\n        _k.game.events.trigger(\"sceneLeave\", name);\n        _k.app.events.clear();\n        _k.game.events.clear();\n        _k.game.objEvents.clear();\n\n        [..._k.game.root.children].forEach((obj) => {\n            if (\n                !obj.stay\n                || (obj.scenesToStay && !obj.scenesToStay.includes(name))\n            ) {\n                _k.game.root.remove(obj);\n            }\n            else {\n                obj.trigger(\"sceneEnter\", name);\n            }\n        });\n\n        _k.game.root.clearEvents();\n        initEvents();\n\n        // cam\n        _k.game.cam = {\n            pos: null,\n            scale: vec2(1),\n            angle: 0,\n            shake: 0,\n            transform: new Mat4(),\n        };\n\n        _k.game.scenes[name](...args);\n    });\n\n    _k.game.currentScene = name;\n}\n\nexport function onSceneLeave(\n    action: (newScene?: string) => void,\n): KEventController {\n    return _k.game.events.on(\"sceneLeave\", action);\n}\n\nexport function getSceneName() {\n    return _k.game.currentScene;\n}\n", "// TODO: accept canvas\n\nimport { dt } from \"../../app\";\nimport type { Asset, SpriteAnim, SpriteData } from \"../../assets\";\nimport { resolveSprite } from \"../../assets/sprite\";\nimport { onLoad } from \"../../game\";\nimport { getRenderProps } from \"../../game/utils\";\nimport { drawTexture, type Texture } from \"../../gfx\";\nimport { Quad, quad, Rect, Vec2, vec2 } from \"../../math\";\nimport type {\n    Comp,\n    GameObj,\n    SpriteAnimPlayOpt,\n    SpriteCurAnim,\n} from \"../../types\";\nimport { KEvent, KEventController } from \"../../utils/\";\n\n/**\n * The {@link sprite `sprite()`} component.\n *\n * @group Component Types\n */\nexport interface SpriteComp extends Comp {\n    draw: Comp[\"draw\"];\n    /**\n     * Name of the sprite.\n     */\n    sprite: string;\n    /**\n     * Width for sprite.\n     */\n    width: number;\n    /**\n     * Height for sprite.\n     */\n    height: number;\n    /**\n     * Current frame in the entire spritesheet.\n     */\n    frame: number;\n    /**\n     * Current frame in relative to the animation that is currently playing.\n     */\n    animFrame: number;\n    /**\n     * The rectangular area of the texture to render.\n     */\n    quad: Quad;\n    /**\n     * Play a piece of anim.\n     */\n    play(anim: string, options?: SpriteAnimPlayOpt): void;\n    /**\n     * Stop current anim.\n     */\n    stop(): void;\n    /**\n     * Get total number of frames.\n     */\n    numFrames(): number;\n    /**\n     * Get the current animation data.\n     *\n     * @since v3001.0\n     */\n    getCurAnim(): SpriteCurAnim | null;\n    /**\n     * Get current anim name.\n     *\n     * @deprecated Use `getCurAnim().name` instead.\n     */\n    curAnim(): string | undefined;\n    /**\n     * Check if object's sprite has an animation.\n     */\n    hasAnim(name: string): boolean;\n    /**\n     * Get an animation.\n     */\n    getAnim(name: string): SpriteAnim | null;\n    /**\n     * Speed multiplier for all animations (for the actual fps for an anim use .play(\"anim\", { speed: 10 })).\n     */\n    animSpeed: number;\n    /**\n     * Flip texture horizontally.\n     */\n    flipX: boolean;\n    /**\n     * Flip texture vertically.\n     */\n    flipY: boolean;\n    /**\n     * Register an event that runs when an animation is played.\n     */\n    onAnimStart(action: (anim: string) => void): KEventController;\n    /**\n     * Register an event that runs when an animation is ended.\n     */\n    onAnimEnd(action: (anim: string) => void): KEventController;\n    /**\n     * @since v3000.0\n     */\n    renderArea(): Rect;\n}\n\n/**\n * Options for the {@link sprite `sprite()`} component.\n *\n * @group Component Types\n */\nexport interface SpriteCompOpt {\n    /**\n     * If the sprite is loaded with multiple frames, or sliced, use the frame option to specify which frame to draw.\n     */\n    frame?: number;\n    /**\n     * If provided width and height, don't stretch but instead render tiled.\n     */\n    tiled?: boolean;\n    /**\n     * Stretch sprite to a certain width.\n     */\n    width?: number;\n    /**\n     * Stretch sprite to a certain height.\n     */\n    height?: number;\n    /**\n     * Play an animation on start.\n     */\n    anim?: string;\n    /**\n     * Speed multiplier for all animations (for the actual fps for an anim use .play(\"anim\", { speed: 10 })).\n     */\n    animSpeed?: number;\n    /**\n     * Flip texture horizontally.\n     */\n    flipX?: boolean;\n    /**\n     * Flip texture vertically.\n     */\n    flipY?: boolean;\n    /**\n     * The rectangular sub-area of the texture to render, default to full texture `quad(0, 0, 1, 1)`.\n     */\n    quad?: Quad;\n    /**\n     * If fill the sprite (useful if you only want to render outline with outline() component).\n     */\n    fill?: boolean;\n}\n\n// TODO: clean\nexport function sprite(\n    src: string | SpriteData | Asset<SpriteData>,\n    opt: SpriteCompOpt = {},\n): SpriteComp {\n    let spriteData: SpriteData | null = null;\n    let curAnim: SpriteCurAnim | null = null;\n    // 1  - from small index to large index\n    // -1 - reverse\n    let curAnimDir: -1 | 1 | null = null;\n    const spriteLoadedEvent = new KEvent<[SpriteData]>();\n\n    if (!src) {\n        throw new Error(\n            \"Please pass the resource name or data to sprite()\",\n        );\n    }\n\n    const calcTexScale = (\n        tex: Texture,\n        q: Quad,\n        w?: number,\n        h?: number,\n    ): Vec2 => {\n        const scale = vec2(1, 1);\n        if (w && h) {\n            scale.x = w / (tex.width * q.w);\n            scale.y = h / (tex.height * q.h);\n        }\n        else if (w) {\n            scale.x = w / (tex.width * q.w);\n            scale.y = scale.x;\n        }\n        else if (h) {\n            scale.y = h / (tex.height * q.h);\n            scale.x = scale.y;\n        }\n        return scale;\n    };\n\n    const setSpriteData = (\n        obj: GameObj<SpriteComp>,\n        spr: SpriteData | null,\n    ) => {\n        if (!spr) return;\n\n        let q = spr.frames[0].clone();\n\n        if (opt.quad) {\n            q = q.scale(opt.quad);\n        }\n\n        const scale = calcTexScale(\n            spr.tex,\n            q,\n            opt.width,\n            opt.height,\n        );\n\n        obj.width = spr.tex.width * q.w * scale.x;\n        obj.height = spr.tex.height * q.h * scale.y;\n\n        if (spr.anims) {\n            for (let animName in spr.anims) {\n                const anim = spr.anims[animName];\n                if (typeof anim !== \"number\") {\n                    anim.frames = createAnimFrames(anim);\n                }\n            }\n        }\n\n        spriteData = spr;\n        spriteLoadedEvent.trigger(spriteData);\n\n        if (opt.anim) {\n            obj.play(opt.anim);\n        }\n    };\n\n    const createAnimFrames = (anim: Exclude<SpriteAnim, number>) => {\n        if (anim.frames) {\n            return anim.frames;\n        }\n        const frames = [];\n        if (anim.from === undefined || anim.to === undefined) {\n            throw new Error(\"Sprite anim 'from' and 'to' must be defined if 'frames' is not defined\");\n        }\n        const frameSeqLength = Math.abs(anim.to - anim.from) + 1;\n        for (let i = 0; i < frameSeqLength; i++) {\n            frames.push(anim.from + i * Math.sign(anim.to - anim.from));\n        }\n        if (anim.pingpong) {\n            for (let i = frameSeqLength - 2; i > 0; i--) {\n                frames.push(frames[i]);\n            }\n        }\n        return frames;\n    }\n\n    return {\n        id: \"sprite\",\n        // TODO: allow update\n        width: 0,\n        height: 0,\n        frame: opt.frame || 0,\n        quad: opt.quad || new Quad(0, 0, 1, 1),\n        animSpeed: opt.animSpeed ?? 1,\n        flipX: opt.flipX ?? false,\n        flipY: opt.flipY ?? false,\n\n        get sprite() {\n            return src.toString();\n        },\n\n        set sprite(src) {\n            const spr = resolveSprite(src);\n\n            if (spr) {\n                spr.onLoad(spr =>\n                    setSpriteData(this as unknown as GameObj<SpriteComp>, spr)\n                );\n            }\n        },\n\n        get animFrame() {\n            if (!spriteData || !curAnim || curAnimDir === null) {\n                return this.frame;\n            }\n\n            const anim = spriteData.anims[curAnim.name];\n\n            if (typeof anim === \"number\") {\n                return anim;\n            }\n\n            if (anim.from === undefined || anim.to === undefined) {\n                return curAnim.frameIndex;\n            }\n\n            return this.frame - Math.min(anim.from, anim.to);\n        },\n\n        draw(this: GameObj<SpriteComp>) {\n            if (!spriteData) return;\n\n            const q = spriteData.frames[this.frame ?? 0];\n\n            if (!q) {\n                throw new Error(`Frame not found: ${this.frame ?? 0}`);\n            }\n\n            if (spriteData.slice9) {\n                // TODO: tile\n                // TODO: use scale or width / height, or both?\n                const { left, right, top, bottom } = spriteData.slice9;\n                const tw = spriteData.tex.width * q.w;\n                const th = spriteData.tex.height * q.h;\n                const iw = this.width - left - right;\n                const ih = this.height - top - bottom;\n                const w1 = left / tw;\n                const w3 = right / tw;\n                const w2 = 1 - w1 - w3;\n                const h1 = top / th;\n                const h3 = bottom / th;\n                const h2 = 1 - h1 - h3;\n                const quads = [\n                    // uv\n                    quad(0, 0, w1, h1),\n                    quad(w1, 0, w2, h1),\n                    quad(w1 + w2, 0, w3, h1),\n                    quad(0, h1, w1, h2),\n                    quad(w1, h1, w2, h2),\n                    quad(w1 + w2, h1, w3, h2),\n                    quad(0, h1 + h2, w1, h3),\n                    quad(w1, h1 + h2, w2, h3),\n                    quad(w1 + w2, h1 + h2, w3, h3),\n                    // transform\n                    quad(0, 0, left, top),\n                    quad(left, 0, iw, top),\n                    quad(left + iw, 0, right, top),\n                    quad(0, top, left, ih),\n                    quad(left, top, iw, ih),\n                    quad(left + iw, top, right, ih),\n                    quad(0, top + ih, left, bottom),\n                    quad(left, top + ih, iw, bottom),\n                    quad(left + iw, top + ih, right, bottom),\n                ];\n                for (let i = 0; i < 9; i++) {\n                    const uv = quads[i];\n                    const transform = quads[i + 9];\n                    drawTexture(\n                        Object.assign(getRenderProps(this), {\n                            pos: transform.pos(),\n                            tex: spriteData.tex,\n                            quad: q.scale(uv),\n                            flipX: this.flipX,\n                            flipY: this.flipY,\n                            tiled: opt.tiled,\n                            width: transform.w,\n                            height: transform.h,\n                        }),\n                    );\n                }\n            }\n            else {\n                drawTexture(\n                    Object.assign(getRenderProps(this), {\n                        tex: spriteData.tex,\n                        quad: q.scale(this.quad ?? new Quad(0, 0, 1, 1)),\n                        flipX: this.flipX,\n                        flipY: this.flipY,\n                        tiled: opt.tiled,\n                        width: this.width,\n                        height: this.height,\n                    }),\n                );\n            }\n        },\n\n        add(this: GameObj<SpriteComp>) {\n            const spr = resolveSprite(src);\n\n            if (spr) {\n                // The sprite exists\n                spr.onLoad(spr => setSpriteData(this, spr));\n            }\n            else {\n                // The sprite may be loaded later in the script, check again when all resources have been loaded\n                onLoad(() => setSpriteData(this, resolveSprite(src)!.data));\n            }\n        },\n\n        update(this: GameObj<SpriteComp>) {\n            if (!spriteData || !curAnim || curAnimDir === null) {\n                return;\n            }\n\n            const anim = spriteData!.anims[curAnim.name];\n\n            if (typeof anim === \"number\") {\n                this.frame = anim;\n                return;\n            }\n\n            if (anim.speed === 0) {\n                throw new Error(\"Sprite anim speed cannot be 0\");\n            }\n\n            curAnim.timer += dt() * this.animSpeed;\n\n            if (curAnim.timer >= (1 / curAnim.speed)) {\n                curAnim.timer = 0;\n                curAnim.frameIndex += curAnimDir;\n\n                const frames = anim.frames!;\n                if (curAnim.frameIndex >= frames.length) {\n                    if (curAnim.pingpong && !anim.pingpong) {\n                        curAnimDir = -1;\n                        curAnim.frameIndex = frames.length - 2;\n                    } else if (curAnim.loop) {\n                        curAnim.frameIndex = 0;\n                    } else {\n                        this.frame = frames.at(-1)!;\n                        curAnim.onEnd();\n                        this.stop();\n                        return;\n                    }\n                } else if (curAnim.frameIndex < 0) {\n                    if (curAnim.pingpong && curAnim.loop) {\n                        curAnimDir = 1;\n                        curAnim.frameIndex = 1;\n                    } else if (curAnim.loop) {\n                        curAnim.frameIndex = frames.length - 1;\n                    } else {\n                        this.frame = frames[0];\n                        curAnim.onEnd();\n                        this.stop();\n                        return;\n                    }\n                }\n\n                this.frame = frames[curAnim.frameIndex];\n            }\n        },\n\n        play(\n            this: GameObj<SpriteComp>,\n            name: string,\n            opt: SpriteAnimPlayOpt = {},\n        ) {\n            if (!spriteData) {\n                spriteLoadedEvent.add(() => this.play(name, opt));\n                return;\n            }\n\n            const anim = spriteData.anims[name];\n\n            if (anim === undefined) {\n                throw new Error(`Anim not found: ${name}`);\n            }\n\n            if (curAnim) {\n                this.stop();\n            }\n\n            curAnim = typeof anim === \"number\"\n                ? {\n                    name: name,\n                    timer: 0,\n                    loop: false,\n                    pingpong: false,\n                    speed: 0,\n                    frameIndex: 0,\n                    onEnd: () => { },\n                }\n                : {\n                    name: name,\n                    timer: 0,\n                    loop: opt.loop ?? anim.loop ?? false,\n                    pingpong: opt.pingpong ?? anim.pingpong ?? false,\n                    speed: opt.speed ?? anim.speed ?? 10,\n                    frameIndex: 0,\n                    onEnd: opt.onEnd ?? (() => { }),\n                };\n\n            curAnimDir = typeof anim === \"number\" ? null : 1;\n            this.frame = typeof anim === \"number\" ? anim : anim.frames![0];\n\n            this.trigger(\"animStart\", name);\n        },\n\n        stop(this: GameObj<SpriteComp>) {\n            if (!curAnim) {\n                return;\n            }\n            const prevAnim = curAnim.name;\n            curAnim = null;\n            this.trigger(\"animEnd\", prevAnim);\n        },\n\n        numFrames() {\n            return spriteData?.frames.length ?? 0;\n        },\n\n        getCurAnim() {\n            return curAnim;\n        },\n\n        curAnim() {\n            return curAnim?.name;\n        },\n\n        getAnim(name) {\n            return spriteData?.anims[name] ?? null;\n        },\n\n        hasAnim(name) {\n            return Boolean(this.getAnim(name));\n        },\n\n        onAnimEnd(\n            this: GameObj<SpriteComp>,\n            action: (name: string) => void,\n        ): KEventController {\n            return this.on(\"animEnd\", action);\n        },\n\n        onAnimStart(\n            this: GameObj<SpriteComp>,\n            action: (name: string) => void,\n        ): KEventController {\n            return this.on(\"animStart\", action);\n        },\n\n        renderArea() {\n            return new Rect(vec2(0), this.width, this.height);\n        },\n\n        inspect() {\n            if (typeof src === \"string\") {\n                return `sprite: \"${src}\"`;\n            }\n            return null;\n        },\n    };\n}\n", "import type { BitmapFontData } from \"../../assets\";\nimport { DEF_TEXT_SIZE } from \"../../constants\";\nimport { onLoad } from \"../../game\";\nimport { getRenderProps } from \"../../game/utils\";\nimport {\n    type CharTransform,\n    type CharTransformFunc,\n    compileStyledText,\n    drawFormattedText,\n    formatText,\n    type TextAlign,\n} from \"../../gfx\";\nimport { _k } from \"../../kaplay\";\nimport { Rect, vec2 } from \"../../math/math\";\nimport type { Comp, GameObj, KAPLAYCtx } from \"../../types\";\n\n/**\n * The {@link text `text()`} component.\n *\n * @group Component Types\n */\nexport interface TextComp extends Comp {\n    draw: Comp[\"draw\"];\n    /**\n     * The text to render.\n     */\n    text: string;\n    /**\n     * The text after formatting.\n     */\n    renderedText: string;\n    /**\n     * The text size.\n     */\n    textSize: number;\n    /**\n     * The font to use.\n     */\n    font: string | BitmapFontData;\n    /**\n     * Width of text.\n     */\n    width: number;\n    /**\n     * Height of text.\n     */\n    height: number;\n    /**\n     * Text alignment (\"left\", \"center\" or \"right\", default \"left\").\n     *\n     * @since v3000.0\n     */\n    align: TextAlign;\n    /**\n     * The gap between each line.\n     *\n     * @since v2000.2\n     */\n    lineSpacing: number;\n    /**\n     * The gap between each character.\n     *\n     * @since v2000.2\n     */\n    letterSpacing: number;\n    /**\n     * Transform the pos, scale, rotation or color for each character based on the index or char.\n     *\n     * @since v2000.1\n     */\n    textTransform: CharTransform | CharTransformFunc;\n    /**\n     * Stylesheet for styled chunks, in the syntax of \"this is a [style]text[/style] word\".\n     *\n     * @since v2000.2\n     */\n    textStyles: Record<string, CharTransform | CharTransformFunc>;\n    /**\n     * @since v3000.0\n     */\n    renderArea(): Rect;\n}\n\n/**\n * Options for the {@link text `text()`} component.\n *\n * @group Component Types\n */\nexport interface TextCompOpt {\n    /**\n     * Height of text.\n     */\n    size?: number;\n    /**\n     * The font to use.\n     */\n    font?: string | BitmapFontData;\n    /**\n     * Wrap text to a certain width.\n     */\n    width?: number;\n    /**\n     * Text alignment (\"left\", \"center\" or \"right\", default \"left\").\n     *\n     * @since v3000.0\n     */\n    align?: TextAlign;\n    /**\n     * The gap between each line.\n     *\n     * @since v2000.2\n     */\n    lineSpacing?: number;\n    /**\n     * The gap between each character.\n     *\n     * @since v2000.2\n     */\n    letterSpacing?: number;\n    /**\n     * Transform the pos, scale, rotation or color for each character based on the index or char.\n     *\n     * @since v2000.1\n     */\n    transform?: CharTransform | CharTransformFunc;\n    /**\n     * Stylesheet for styled chunks, in the syntax of \"this is a [style]text[/style] word\".\n     *\n     * @since v2000.2\n     */\n    styles?: Record<string, CharTransform | CharTransformFunc>;\n    /**\n     * If true, any (whitespace) indent on the first line of the paragraph\n     * will be copied to all of the lines for those parts that text-wrap.\n     */\n    indentAll?: boolean;\n}\n\nexport function text(t: string, opt: TextCompOpt = {}): TextComp {\n    function update(obj: GameObj<TextComp | any>) {\n        const ftext = formatText(Object.assign(getRenderProps(obj), {\n            text: obj.text + \"\",\n            size: obj.textSize,\n            font: obj.font,\n            width: opt.width && obj.width,\n            align: obj.align,\n            letterSpacing: obj.letterSpacing,\n            lineSpacing: obj.lineSpacing,\n            // TODO: shouldn't run when object / ancestor is paused\n            transform: obj.textTransform,\n            styles: obj.textStyles,\n            indentAll: opt.indentAll,\n        }));\n\n        if (!opt.width) {\n            obj.width = ftext.width / (obj.scale?.x || 1);\n        }\n\n        obj.height = ftext.height / (obj.scale?.y || 1);\n\n        return ftext;\n    }\n\n    const obj = {\n        id: \"text\",\n        set text(nt) {\n            t = nt;\n            // @ts-ignore\n            update(this);\n            this.renderedText = compileStyledText(t).text;\n        },\n        get text() {\n            return t;\n        },\n        textSize: opt.size ?? DEF_TEXT_SIZE,\n        font: opt.font,\n        width: opt.width ?? 0,\n        height: 0,\n        align: opt.align,\n        lineSpacing: opt.lineSpacing,\n        letterSpacing: opt.letterSpacing,\n        textTransform: opt.transform,\n        textStyles: opt.styles,\n        renderedText: t ? compileStyledText(t).text : \"\",\n\n        add(this: GameObj<TextComp>) {\n            onLoad(() => update(this));\n        },\n\n        draw(this: GameObj<TextComp>) {\n            drawFormattedText(update(this));\n        },\n\n        renderArea() {\n            return new Rect(vec2(0), this.width, this.height);\n        },\n    };\n\n    // @ts-ignore\n    update(obj);\n\n    // @ts-ignore Deep check in text related methods\n    return obj;\n}\n", "import { getRenderProps } from \"../../game/utils\";\nimport { drawUVQuad } from \"../../gfx\";\nimport { Rect, vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\n\n/**\n * The {@link uvquad `uvquad()`} component.\n *\n * @group Component Types\n */\nexport interface UVQuadComp extends Comp {\n    draw: Comp[\"draw\"];\n    /**\n     * Width of rect.\n     */\n    width: number;\n    /**\n     * Height of height.\n     */\n    height: number;\n    /**\n     * @since v3000.0\n     */\n    renderArea(): Rect;\n}\nexport function uvquad(w: number, h: number): UVQuadComp {\n    return {\n        id: \"rect\",\n        width: w,\n        height: h,\n        draw(this: GameObj<UVQuadComp>) {\n            drawUVQuad(Object.assign(getRenderProps(this), {\n                width: this.width,\n                height: this.height,\n            }));\n        },\n        renderArea() {\n            return new Rect(vec2(0), this.width, this.height);\n        },\n        inspect() {\n            return `uvquad: (${Math.ceil(this.width)}w, ${\n                Math.ceil(this.height)\n            })h`;\n        },\n    };\n}\n", "import { Vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\nimport type { PosComp } from \"../transform/pos\";\nimport type { TileComp } from \"./tile\";\n\n/**\n * The {@link agent `agent()`} component.\n *\n * @group Component Types\n */\nexport interface AgentComp extends Comp {\n    agentSpeed: number;\n    allowDiagonals: boolean;\n    getDistanceToTarget(): number;\n    getNextLocation(): Vec2 | null;\n    getPath(): Vec2[] | null;\n    getTarget(): Vec2 | null;\n    isNavigationFinished(): boolean;\n    isTargetReachable(): boolean;\n    isTargetReached(): boolean;\n    setTarget(target: Vec2): void;\n    onNavigationStarted(cb: () => void): KEventController;\n    onNavigationNext(cb: () => void): KEventController;\n    onNavigationEnded(cb: () => void): KEventController;\n    onTargetReached(cb: () => void): KEventController;\n}\n\n/**\n * Options for the {@link agent `agent()`} component.\n *\n * @group Component Types\n */\nexport type AgentCompOpt = {\n    speed?: number;\n    allowDiagonals?: boolean;\n};\n\nexport function agent(opts: AgentCompOpt = {}): AgentComp {\n    let target: Vec2 | null = null;\n    let path: Vec2[] | null = null;\n    let index: number | null = null;\n    let navMapChangedEvent: KEventController | null = null;\n    return {\n        id: \"agent\",\n        require: [\"pos\", \"tile\"],\n        agentSpeed: opts.speed ?? 100,\n        allowDiagonals: opts.allowDiagonals ?? true,\n        getDistanceToTarget(this: GameObj<AgentComp | PosComp>) {\n            return target ? this.pos.dist(target) : 0;\n        },\n        getNextLocation() {\n            return path && index ? path[index] : null;\n        },\n        getPath() {\n            return path ? path.slice() : null;\n        },\n        getTarget() {\n            return target;\n        },\n        isNavigationFinished() {\n            return path ? index === null : true;\n        },\n        isTargetReachable() {\n            return path !== null;\n        },\n        isTargetReached(this: GameObj<AgentComp | PosComp>) {\n            return target ? this.pos.eq(target) : true;\n        },\n        setTarget(this: GameObj<AgentComp | TileComp | PosComp>, p: Vec2) {\n            target = p;\n            path = this.getLevel().getPath(this.pos, target, {\n                allowDiagonals: this.allowDiagonals,\n            });\n            index = path ? 0 : null;\n            if (path && index !== null) {\n                if (!navMapChangedEvent) {\n                    navMapChangedEvent = this.getLevel()\n                        .onNavigationMapChanged(() => {\n                            if (target && path && index !== null) {\n                                path = this.getLevel().getPath(\n                                    this.pos,\n                                    target,\n                                    {\n                                        allowDiagonals: this.allowDiagonals,\n                                    },\n                                );\n                                if (path) {\n                                    index = 0;\n                                    this.trigger(\n                                        \"navigationNext\",\n                                        this,\n                                        path[index],\n                                    );\n                                }\n                                else {\n                                    index = null;\n                                    this.trigger(\"navigationEnded\", this);\n                                }\n                            }\n                        });\n                    this.onDestroy(() => navMapChangedEvent?.cancel());\n                }\n                this.trigger(\"navigationStarted\", this);\n                this.trigger(\"navigationNext\", this, path[index]);\n            }\n            else {\n                this.trigger(\"navigationEnded\", this);\n            }\n        },\n        update(this: GameObj<AgentComp | PosComp>) {\n            if (target && path && index !== null) {\n                if (this.pos.sdist(path[index]) < 2) {\n                    if (index === path.length - 1) {\n                        this.pos = target.clone();\n                        index = null;\n                        this.trigger(\"navigationEnded\", this);\n                        this.trigger(\"targetReached\", this);\n                        return;\n                    }\n                    else {\n                        index++;\n                        this.trigger(\"navigationNext\", this, path[index]);\n                    }\n                }\n                this.moveTo(path[index], this.agentSpeed);\n            }\n        },\n        onNavigationStarted(this: GameObj<AgentComp>, cb: () => void) {\n            return this.on(\"navigationStarted\", cb);\n        },\n        onNavigationNext(this: GameObj<AgentComp>, cb: () => void) {\n            return this.on(\"navigationNext\", cb);\n        },\n        onNavigationEnded(this: GameObj<AgentComp>, cb: () => void) {\n            return this.on(\"navigationEnded\", cb);\n        },\n        onTargetReached(this: GameObj<AgentComp>, cb: () => void) {\n            return this.on(\"targetReached\", cb);\n        },\n        inspect() {\n            return `agent: ` + JSON.stringify({\n                target: JSON.stringify(target),\n                path: JSON.stringify(path),\n            });\n        },\n    };\n}\n", "import { Vec2 } from \"../../math/math\";\nimport { type Graph } from \"../../math/navigation\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { PosComp } from \"../transform/pos\";\n\nexport interface PathfinderMapComp extends Comp {\n    /*\n     * Get navigation waypoints to reach the given target from the given origin.\n     */\n    navigate(\n        origin: Vec2,\n        target: Vec2,\n        navigationOpt: any,\n    ): Vec2[] | undefined;\n    /*\n     * The graph to use for navigation.\n     */\n    graph: Graph | undefined;\n}\n\nexport interface PathfinderMapCompOpt {\n    /*\n     * The graph to use for navigation. If null, the ancestors are queried for a pathfinderMap component.\n     */\n    graph?: Graph;\n}\n\nexport function pathfinderMap(\n    opts: PathfinderMapCompOpt,\n): PathfinderMapComp {\n    let graph = opts.graph;\n    return {\n        id: \"pathfinderMap\",\n        get graph(): Graph | undefined {\n            return graph;\n        },\n        set graph(value) {\n            graph = value;\n        },\n        navigate(\n            this: GameObj<PathfinderMapComp>,\n            origin: Vec2,\n            target: Vec2,\n            navigationOpt: any = {},\n        ): Vec2[] | undefined {\n            return graph?.getWaypointPath(origin, target, navigationOpt);\n        },\n    };\n}\n\nexport interface PathfinderComp extends Comp {\n    /*\n     * Get navigation waypoints to reach the given target from the current position.\n     */\n    navigateTo(target: Vec2): Vec2[] | undefined;\n    /*\n     * Get the graph used for navigastion if any.\n     */\n    graph: Graph | undefined;\n}\n\nexport interface PathfinderCompOpt {\n    /*\n     * The graph to use for navigation. If null, the ancestors are queried for a pathfinderMap component.\n     */\n    graph?: Graph;\n    /*\n     * The navigation options depending on the kind of graph used.\n     */\n    navigationOpt?: any;\n}\n\nexport function pathfinder(\n    opts: PathfinderCompOpt,\n): PathfinderComp {\n    let graph = opts.graph;\n    return {\n        id: \"pathfinder\",\n        require: [\"pos\"],\n        navigateTo(\n            this: GameObj<PathfinderComp | PosComp>,\n            target: Vec2,\n        ): Vec2[] | undefined {\n            const graph: Graph | undefined = this.graph;\n            return graph?.getWaypointPath(this.pos, target, opts.navigationOpt);\n        },\n        get graph(): Graph | undefined {\n            if (graph) {\n                return graph;\n            }\n            let parent: GameObj<any> | null =\n                (this as unknown as GameObj<PathfinderComp>).parent;\n            while (parent) {\n                if (parent.has(\"pathfinderMap\")) {\n                    return parent.graph;\n                }\n                parent = parent.parent;\n            }\n            return undefined;\n        },\n        set graph(value) {\n            graph = value;\n        },\n    };\n}\n", "import { Vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\nimport type { PosComp } from \"../transform/pos\";\n\nexport interface PatrolComp extends Comp {\n    /*\n     * Path to follow. If null, doesn't move.\n     */\n    waypoints: Vec2[] | undefined;\n    /*\n     * Speed of the movement during patrol.\n     */\n    patrolSpeed: number;\n    /*\n     * Current subgoal, if any.\n     */\n    nextLocation: Vec2 | undefined;\n    /**\n     * Attaches an event handler which is called when using \"stop\" and the end of the path is reached.\n     * @param cb The event handler called when the patrol finishes.\n     */\n    onPatrolFinished(cb: (objects: GameObj[]) => void): KEventController;\n}\n\ntype PatrolEndBehavior =\n    /* Go directly back to the start */\n    | \"loop\"\n    /* Traveling the reverse path back to the start */\n    | \"ping-pong\"\n    /* Stop */\n    | \"stop\";\n\nexport interface PatrolCompOpt {\n    /*\n     * Path to follow. If null, starts suspended.\n     */\n    waypoints?: Vec2[];\n    /*\n     * Speed of the movement during patrol.\n     */\n    speed?: number;\n    /*\n     * What to do after the last waypoint has been reached.\n     */\n    endBehavior?: PatrolEndBehavior;\n}\n\nexport function patrol(\n    opts: PatrolCompOpt = {},\n): PatrolComp {\n    let waypoints = opts.waypoints;\n    let speed = opts.speed || 100; // Or throw error?\n    let endBehavior = opts.endBehavior || \"stop\"; // Default is stop.\n    let index = 0;\n    let finished = waypoints != null;\n    return {\n        id: \"patrol\",\n        require: [\"pos\"],\n        get patrolSpeed() {\n            return speed;\n        },\n        set patrolSpeed(value) {\n            speed = value;\n        },\n        get waypoints() {\n            return waypoints;\n        },\n        set waypoints(value) {\n            waypoints = value;\n            index = 0;\n            finished = false;\n        },\n        get nextLocation() {\n            return waypoints ? waypoints[index] : undefined;\n        },\n        update(this: GameObj<PatrolComp | PosComp>) {\n            const nextWaypoint = this.nextLocation;\n            if (!waypoints || !nextWaypoint || finished) return;\n            this.moveTo(nextWaypoint, speed);\n            if (this.pos.sdist(nextWaypoint) < 9) {\n                switch (endBehavior) {\n                    case \"loop\":\n                        index = (index + 1) % waypoints.length;\n                        break;\n                    case \"ping-pong\":\n                        index = index + 1;\n                        if (index == waypoints.length) {\n                            waypoints.reverse();\n                            index = 0;\n                        }\n                        break;\n                    case \"stop\":\n                        if (index < waypoints.length - 1) {\n                            index += 1;\n                        }\n                        else if (!finished) {\n                            finished = true;\n                            this.trigger(\"patrolFinished\", this);\n                        }\n                        break;\n                }\n            }\n        },\n        onPatrolFinished(cb: (objects: GameObj[]) => void) {\n            return (this as unknown as GameObj<PatrolComp>).on(\n                \"patrolFinished\",\n                cb,\n            );\n        },\n    };\n}\n", "import { dt } from \"../../app\";\nimport { _k } from \"../../kaplay\";\nimport { Vec2 } from \"../../math/math\";\nimport type { Comp, GameObj, QueryOpt } from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\nimport { raycast } from \"../draw\";\nimport type { PosComp } from \"../transform/pos\";\n\n/**\n * The {@link sentry `sentry()`} component.\n *\n * @group Component Types\n */\nexport interface SentryComp extends Comp {\n    /*\n     * The direction the sentry is pointing to.\n     */\n    direction?: Vec2;\n    /*\n     * The direction of the sentry as an angle in degrees.\n     */\n    directionAngle?: number;\n    /*\n     * The field of view of the sentry in degrees.\n     */\n    fieldOfView?: number;\n    /*\n     * The objects spotted most recently.\n     */\n    spotted: GameObj<any>[];\n    /**\n     * Attaches an event handler which is called when objects of interest are spotted.\n     * @param cb The event handler called when objects are spotted.\n     */\n    onObjectsSpotted(cb: (objects: GameObj[]) => void): KEventController;\n    /**\n     * Returns true if the object is within the field of view.\n     * @param obj The object to test.\n     * @param direction The direction to look at.\n     * @param fieldOfView The field of view in degrees.\n     */\n    isWithinFieldOfView(\n        obj: GameObj<PosComp>,\n        direction?: Vec2,\n        fieldOfView?: number,\n    ): boolean;\n    /**\n     * Returns true if there is a line of sight to the object.\n     * @param obj The object to test.\n     */\n    hasLineOfSight(obj: GameObj<PosComp>): boolean;\n}\n\n/**\n * Options for the {@link sentry `sentry()`} component.\n *\n * @group Component Types\n */\nexport interface SentryCompOpt {\n    /*\n     * The direction the sentry is pointing to. If undefined, direction has no influence.\n     */\n    direction?: Vec2 | number;\n    /*\n     * The field of view of the sentry in degrees. If undefined, defaults to human fov of 200 degrees.\n     */\n    fieldOfView?: number;\n    /*\n     * If true, line of sight matters. This means that objects which are blocked from view by areas are invisible.\n     */\n    lineOfSight?: boolean;\n    /*\n     * When using line of sight, the objects which are transparent for the ray. Include at least a tag identifying the sentry.\n     */\n    raycastExclude?: string[];\n    /*\n     * The frequency of checking, defaults to every second.\n     */\n    checkFrequency?: number;\n}\n\nexport type SentryCandidatesCb = () => GameObj<any>[];\nexport type SentryCandidates = SentryCandidatesCb | QueryOpt;\n\nexport function sentry(\n    candidates: SentryCandidates,\n    opts: SentryCompOpt = {},\n): SentryComp {\n    const get: SentryCandidatesCb = typeof candidates === \"function\"\n        ? candidates\n        : () => {\n            return _k.game.root.query(candidates);\n        };\n    const checkFrequency = opts.checkFrequency || 1;\n    const directionVector = typeof opts.direction === \"number\"\n        ? Vec2.fromAngle(opts.direction)\n        : opts.direction;\n    let t = 0;\n    return {\n        id: \"sentry\",\n        require: [\"pos\"],\n        direction: typeof opts.direction == \"number\"\n            ? Vec2.fromAngle(opts.direction)\n            : opts.direction,\n        spotted: [],\n        set directionAngle(value: number) {\n            this.direction = value !== undefined\n                ? Vec2.fromAngle(value)\n                : undefined;\n        },\n        get directionAngle(): number | undefined {\n            return this.direction ? this.direction.angle() : undefined;\n        },\n        fieldOfView: opts.fieldOfView || 200, // 200 degrees = Human field of view\n        isWithinFieldOfView(\n            this: GameObj<SentryComp | PosComp>,\n            obj: GameObj<PosComp>,\n            direction?: Vec2,\n            fieldOfView?: number,\n        ) {\n            const dir: Vec2 | undefined = (typeof direction === \"number\"\n                ? Vec2.fromAngle(direction)\n                : direction) || directionVector;\n            const fov: number | undefined = fieldOfView || opts.fieldOfView;\n            if (!dir || !fov || fov >= 360) return true;\n            const halfAngle = fov / 2;\n            return obj.pos\n                && dir.angleBetween(obj.pos.sub(this.pos)) <= halfAngle;\n        },\n        hasLineOfSight(\n            this: GameObj<SentryComp | PosComp>,\n            obj: GameObj<PosComp>,\n        ) {\n            const hit = raycast(\n                this.pos,\n                obj.pos.sub(this.pos),\n                opts.raycastExclude,\n            );\n            return hit != null && hit.object === obj;\n        },\n        update(this: GameObj<SentryComp | PosComp>) {\n            t += dt();\n            if (t > checkFrequency) {\n                t -= checkFrequency;\n                let objects = get();\n                // If fieldOfView is used, keep only object within view\n                if (\n                    objects.length && directionVector && this.fieldOfView\n                    && this.fieldOfView < 360\n                ) {\n                    const halfAngle = this.fieldOfView / 2;\n                    objects = objects.filter(o =>\n                        o.pos\n                        && directionVector.angleBetween(o.pos.sub(this.pos))\n                            <= halfAngle\n                    );\n                }\n                // If lineOfSight is used, raycast\n                if (objects.length && opts.lineOfSight) {\n                    objects = objects.filter(o => {\n                        return o.pos\n                            && this.hasLineOfSight(o as GameObj<PosComp>);\n                    });\n                }\n                if (objects.length > 0) {\n                    this.spotted = objects;\n                    this.trigger(\"objectSpotted\", objects);\n                }\n            }\n        },\n        onObjectsSpotted(cb: (objects: GameObj[]) => void) {\n            return (this as unknown as GameObj<SentryComp>).on(\n                \"objectSpotted\",\n                cb,\n            );\n        },\n    };\n}\n", "import { Vec2, vec2 } from \"../../math/math\";\nimport {\n    type Comp,\n    type Edge,\n    EdgeMask,\n    type GameObj,\n    type LevelComp,\n} from \"../../types\";\n\n/**\n * The {@link tile `tile()`} component.\n *\n * @group Component Types\n */\nexport interface TileComp extends Comp {\n    /**\n     * The tile position inside the level.\n     */\n    tilePos: Vec2;\n    /**\n     * If the tile is an obstacle in pathfinding.\n     */\n    isObstacle: boolean;\n    /**\n     * How much a tile is cost to traverse in pathfinding (default 0).\n     */\n    cost: number;\n    /**\n     * If the tile has hard edges that cannot pass in pathfinding.\n     */\n    edges: Edge[];\n    /**\n     * Position offset when setting `tilePos`.\n     */\n    tilePosOffset: Vec2;\n    readonly edgeMask: EdgeMask;\n    getLevel(): GameObj<LevelComp>;\n    tileMove(dir: Vec2): void;\n    moveLeft(): void;\n    moveRight(): void;\n    moveUp(): void;\n    moveDown(): void;\n}\n\n/**\n * Options for the {@link tile `tile()`} component.\n *\n * @group Component Types\n */\nexport type TileCompOpt = {\n    /**\n     * If the tile is an obstacle in pathfinding.\n     */\n    isObstacle?: boolean;\n    /**\n     * How much a tile is cost to traverse in pathfinding (default 0).\n     */\n    cost?: number;\n    /**\n     * If the tile has hard edges that cannot pass in pathfinding.\n     */\n    edges?: Edge[];\n    /**\n     * Position offset when setting `tilePos`.\n     */\n    offset?: Vec2;\n};\n\nexport function tile(opts: TileCompOpt = {}): TileComp {\n    let tilePos = vec2(0);\n    let isObstacle = opts.isObstacle ?? false;\n    let cost = opts.cost ?? 0;\n    let edges = opts.edges ?? [];\n\n    const getEdgeMask = () => {\n        const loopup = {\n            \"left\": EdgeMask.Left,\n            \"top\": EdgeMask.Top,\n            \"right\": EdgeMask.Right,\n            \"bottom\": EdgeMask.Bottom,\n        };\n        return edges.map(s => loopup[s] || 0).reduce(\n            (mask, dir) => mask | dir,\n            0,\n        );\n    };\n\n    let edgeMask = getEdgeMask();\n\n    return {\n        id: \"tile\",\n        tilePosOffset: opts.offset ?? vec2(0),\n\n        set tilePos(p: Vec2) {\n            const level = this.getLevel();\n            tilePos = p.clone();\n            // @ts-ignore\n            this.pos = vec2(\n                this.tilePos.x * level.tileWidth(),\n                this.tilePos.y * level.tileHeight(),\n            ).add(this.tilePosOffset);\n        },\n\n        get tilePos() {\n            return tilePos;\n        },\n\n        set isObstacle(is: boolean) {\n            if (isObstacle === is) return;\n            isObstacle = is;\n            this.getLevel().invalidateNavigationMap();\n        },\n\n        get isObstacle() {\n            return isObstacle;\n        },\n\n        set cost(n: number) {\n            if (cost === n) return;\n            cost = n;\n            this.getLevel().invalidateNavigationMap();\n        },\n\n        get cost() {\n            return cost;\n        },\n\n        set edges(e: Edge[]) {\n            edges = e;\n            edgeMask = getEdgeMask();\n            this.getLevel().invalidateNavigationMap();\n        },\n\n        get edges() {\n            return edges;\n        },\n\n        get edgeMask() {\n            return edgeMask;\n        },\n\n        getLevel(this: GameObj) {\n            return this.parent as GameObj<LevelComp>;\n        },\n\n        tileMove(dir: Vec2) {\n            const level = this.getLevel();\n            level.removeFromSpatialMap(this as unknown as GameObj<TileComp>);\n            this.tilePos = this.tilePos.add(dir);\n            level.insertIntoSpatialMap(this as unknown as GameObj<TileComp>);\n            level.trigger(\"spatialMapChanged\");\n        },\n\n        moveLeft() {\n            this.tileMove(vec2(-1, 0));\n        },\n\n        moveRight() {\n            this.tileMove(vec2(1, 0));\n        },\n\n        moveUp() {\n            this.tileMove(vec2(0, -1));\n        },\n\n        moveDown() {\n            this.tileMove(vec2(0, 1));\n        },\n    };\n}\n", "import { dt } from \"../../app\";\nimport { clamp } from \"../../math/clamp.js\";\nimport { Color } from \"../../math/color\";\nimport easings from \"../../math/easings\";\nimport {\n    catmullRom,\n    hermiteFirstDerivative,\n    lerp,\n    Vec2,\n    vec2,\n} from \"../../math/math\";\nimport type { Comp, EaseFunc, GameObj, LerpValue } from \"../../types\";\nimport type { KEventController } from \"../../utils\";\nimport type { NamedComp } from \"./named\";\n\ntype TimeDirection =\n    /* Animate forward */\n    | \"forward\"\n    /* Animate in reverse */\n    | \"reverse\"\n    /* Alternate animating forward and reverse */\n    | \"ping-pong\";\n\ntype Interpolation =\n    /* No interpolation */\n    | \"none\"\n    /* Linear interpolation */\n    | \"linear\"\n    /* Spherical linear interpolation */\n    | \"slerp\"\n    /* Spline interpolation */\n    | \"spline\";\n\nexport interface AnimateOpt {\n    /**\n     * Duration of the animation in seconds\n     */\n    duration: number;\n    /**\n     * Loops, Default is undefined aka infinite\n     */\n    loops?: number;\n    /**\n     * Behavior when reaching the end of the animation. Default is forward.\n     */\n    direction?: TimeDirection;\n    /**\n     * Easing function. Default is linear time.\n     */\n    easing?: EaseFunc;\n    /**\n     * Interpolation function. Default is linear interpolation.\n     */\n    interpolation?: Interpolation;\n    /**\n     * Timestamps in percent for the given keys, if omitted, keys are equally spaced.\n     */\n    timing?: number[];\n    /**\n     * Easings for the given keys, if omitted, easing is used.\n     */\n    easings?: EaseFunc[];\n}\n\nexport interface AnimateCompOpt {\n    /**\n     * Changes the angle so it follows the motion, requires the rotate component\n     */\n    followMotion?: boolean;\n    /**\n     * The animation is added to the base values of pos, angle, scale and opacity instead of replacing them\n     */\n    relative?: boolean;\n}\n\nexport interface BaseValues {\n    pos: Vec2;\n    angle: number;\n    scale: Vec2;\n    opacity: number;\n}\n\nexport interface AnimateComp extends Comp {\n    /**\n     * Animates a property on this object.\n     * @param name Name of the property to animate.\n     * @param keys Keys determining the value at a certain point in time.\n     * @param opts Options.\n     */\n    animate<T extends LerpValue>(\n        name: string,\n        keys: T[],\n        opts: AnimateOpt,\n    ): void;\n    /**\n     * Removes the animation from the given property.\n     * @param name Name of the property to remove the animation from.\n     */\n    unanimate(name: string): void;\n    /**\n     * Removes the animations from all properties\n     */\n    unanimateAll(): void;\n    /**\n     * Attaches an event handler which is called when all the animation channels have finished.\n     * @param cb The event handler called when the animation finishes.\n     */\n    onAnimateFinished(cb: () => void): KEventController;\n    /**\n     * Attaches an event handler which is called when an animation channels has finished.\n     * @param cb The event handler called when an animation channel finishes.\n     */\n    onAnimateChannelFinished(cb: (name: string) => void): KEventController;\n    /**\n     * Base values for relative animation\n     */\n    base: BaseValues;\n    animation: {\n        /**\n         * Pauses playing\n         */\n        paused: boolean;\n        /**\n         * Move the animation to a specific point in time\n         */\n        seek(time: number): void;\n        /**\n         * Returns the duration of the animation\n         */\n        duration: number;\n        /**\n         * Serializes the animation of this object to plain Javascript types\n         */\n    };\n    serializeAnimationChannels(): Record<string, AnimationChannel>;\n    /**\n     * Serializes the options of this object to plain Javascript types\n     */\n    serializeAnimationOptions(): { followMotion?: boolean; relative?: boolean };\n}\n\n/**\n * Baseclass for animation channels, only handles parameter normalization and keyframe searches\n */\nclass AnimateChannel {\n    name: string;\n    duration: number;\n    loops: number;\n    direction: TimeDirection;\n    easing: EaseFunc;\n    interpolation: Interpolation;\n    isFinished: boolean;\n    timing: number[] | undefined;\n    easings: EaseFunc[] | undefined;\n    relative: boolean;\n    constructor(name: string, opts: AnimateOpt, relative: boolean) {\n        this.name = name;\n        this.duration = opts.duration;\n        this.loops = opts.loops || 0;\n        this.direction = opts.direction || \"forward\";\n        this.easing = opts.easing || easings.linear;\n        this.interpolation = opts.interpolation || \"linear\";\n        this.isFinished = false;\n        this.timing = opts.timing;\n        this.easings = opts.easings;\n        this.relative = relative;\n    }\n\n    update(obj: GameObj<any>, t: number): boolean {\n        return true;\n    }\n\n    /**\n     * Returns the first key index for the given time, as well as the relative time towards the second key.\n     * @param t The time in seconds.\n     * @param timing The optional timestamps in percent.\n     * @returns The first key index for the given time, as well as the relative time towards the second key.\n     */\n    getLowerKeyIndexAndRelativeTime(\n        t: number,\n        count: number,\n        timing?: number[],\n    ): [number, number, boolean] {\n        const maxIndex = count - 1;\n        // Check how many loops we've made\n        let p = t / this.duration;\n        if (this.loops !== 0 && p >= this.loops) {\n            return [maxIndex, 0, true];\n        }\n        // Split looped and actual time\n        const m = Math.trunc(p);\n        p -= m;\n        // Reverse if needed\n        if (\n            this.direction == \"reverse\"\n            || (this.direction == \"ping-pong\" && (m & 1))\n        ) {\n            p = 1 - p;\n        }\n        // If we have individual keyframe positions, use them, otherwise use uniform spread\n        if (timing) {\n            let index = 0;\n            while (timing[index + 1] !== undefined && timing[index + 1] < p) {\n                index++;\n            }\n            if (index >= maxIndex) {\n                return [maxIndex, 0, true];\n            }\n            return [\n                index,\n                (p - timing[index]) / (timing[index + 1] - timing[index]),\n                false,\n            ];\n        }\n        else {\n            const index = Math.floor((count - 1) * p);\n            return [index, (p - index / maxIndex) * maxIndex, false];\n        }\n    }\n\n    setValue<T>(obj: GameObj<any>, name: string, value: T) {\n        if (this.relative) {\n            switch (name) {\n                case \"pos\":\n                    obj[\"pos\"] = obj.base.pos.add(value as Vec2);\n                    break;\n                case \"angle\":\n                    obj[\"angle\"] = obj.base.angle + (value as number);\n                    break;\n                case \"scale\":\n                    obj[\"scale\"] = obj.base.scale.scale(value as Vec2);\n                    break;\n                case \"opacity\":\n                    obj[\"opacity\"] = obj.base.opacity * (value as number);\n                    break;\n                default:\n                    obj[name] = value;\n            }\n        }\n        else {\n            obj[name] = value;\n        }\n    }\n\n    serialize(): AnimationChannel {\n        const serialization: AnimationChannel = {\n            duration: this.duration,\n            keys: [],\n        };\n        if (this.loops) {\n            serialization.loops = this.loops;\n        }\n        if (this.direction !== \"forward\") {\n            serialization.direction = this.direction;\n        }\n        if (this.easing != easings.linear) {\n            serialization.easing = this.easing.name;\n        }\n        if (this.interpolation !== \"linear\") {\n            serialization.interpolation = this.interpolation;\n        }\n        if (this.timing) {\n            serialization.timing = this.timing;\n        }\n        if (this.easings) {\n            serialization.easings = this.easings.map(e => this.easing.name);\n        }\n        return serialization;\n    }\n}\n\n/**\n * Reflects a point around another point\n * @param a Point to reflect\n * @param b Point to reflect around\n * @returns Reflected point\n */\nfunction reflect(a: Vec2, b: Vec2) {\n    return b.add(b.sub(a));\n}\n\n/**\n * Subclass handling number keys\n */\nclass AnimateChannelNumber extends AnimateChannel {\n    keys: number[];\n    constructor(\n        name: string,\n        keys: number[],\n        opts: AnimateOpt,\n        relative: boolean,\n    ) {\n        super(name, opts, relative);\n        this.keys = keys;\n    }\n\n    update(obj: GameObj<any>, t: number): boolean {\n        const [index, alpha, isFinished] = this.getLowerKeyIndexAndRelativeTime(\n            t,\n            this.keys.length,\n            this.timing,\n        );\n        // Return exact value in case of exact hit or no interpolation, otherwise interpolate\n        if (alpha == 0 || this.interpolation === \"none\") {\n            this.setValue(obj, this.name, this.keys[index]);\n        }\n        else {\n            const easing = this.easings ? this.easings[index] : this.easing;\n            this.setValue(\n                obj,\n                this.name,\n                lerp(\n                    this.keys[index],\n                    this.keys[index + 1],\n                    easing(alpha),\n                ),\n            );\n        }\n        return isFinished;\n    }\n\n    serialize() {\n        return Object.assign(super.serialize(), { keys: this.keys });\n    }\n}\n\n/**\n * Subclass handling vector keys\n */\nclass AnimateChannelVec2 extends AnimateChannel {\n    keys: Vec2[];\n    curves?: ((t: number) => Vec2)[];\n    dcurves?: ((t: number) => Vec2)[];\n    constructor(\n        name: string,\n        keys: Vec2[],\n        opts: AnimateOpt,\n        relative: boolean,\n        followMotion: boolean,\n    ) {\n        super(name, opts, relative);\n        this.keys = keys;\n        // If spline interpolation is used, bake splines\n        if (this.interpolation === \"spline\") {\n            this.curves = [];\n            // If following motion, bake derivatives as well\n            if (followMotion) {\n                this.dcurves = [];\n            }\n            for (let i = 0; i < this.keys.length - 1; i++) {\n                const prevKey = this.keys[i];\n                const nextIndex = i + 1;\n                const nextKey = this.keys[nextIndex];\n                const prevPrevKey = i > 0\n                    ? this.keys[i - 1]\n                    : reflect(nextKey, prevKey);\n                const nextNextKey = nextIndex < this.keys.length - 1\n                    ? this.keys[nextIndex + 1]\n                    : reflect(prevKey, nextKey);\n                this.curves.push(\n                    catmullRom(prevPrevKey, prevKey, nextKey, nextNextKey),\n                );\n                if (followMotion) {\n                    this.dcurves?.push(\n                        catmullRom(\n                            prevPrevKey,\n                            prevKey,\n                            nextKey,\n                            nextNextKey,\n                            hermiteFirstDerivative,\n                        ),\n                    );\n                }\n            }\n        }\n    }\n\n    update(obj: GameObj<any>, t: number): boolean {\n        const [index, alpha, isFinished] = this.getLowerKeyIndexAndRelativeTime(\n            t,\n            this.keys.length,\n            this.timing,\n        );\n        // Return exact value in case of exact hit or no interpolation, otherwise interpolate\n        if (alpha == 0 || this.interpolation === \"none\") {\n            this.setValue(obj, this.name, this.keys[index]);\n        }\n        else {\n            const easing = this.easings ? this.easings[index] : this.easing;\n            // Use linear or spline interpolation\n            switch (this.interpolation) {\n                case \"linear\":\n                    this.setValue(\n                        obj,\n                        this.name,\n                        this.keys[index].lerp(\n                            this.keys[index + 1],\n                            easing(alpha),\n                        ),\n                    );\n                    break;\n                case \"slerp\":\n                    this.setValue(\n                        obj,\n                        this.name,\n                        this.keys[index].slerp(\n                            this.keys[index + 1],\n                            easing(alpha),\n                        ),\n                    );\n                    break;\n                case \"spline\":\n                    if (this.curves) {\n                        this.setValue(\n                            obj,\n                            this.name,\n                            this.curves[index](easing(alpha)),\n                        );\n                        if (this.dcurves) {\n                            this.setValue(\n                                obj,\n                                \"angle\",\n                                this.dcurves[index](easing(alpha)).angle(),\n                            );\n                        }\n                        break;\n                    }\n            }\n        }\n        return isFinished;\n    }\n\n    serialize() {\n        return Object.assign(super.serialize(), {\n            keys: this.keys.map(v => [v.x, v.y]),\n        });\n    }\n}\n\n/**\n * Subclass handling color keys\n */\nclass AnimateChannelColor extends AnimateChannel {\n    keys: Color[];\n    constructor(\n        name: string,\n        keys: Color[],\n        opts: AnimateOpt,\n        relative: boolean,\n    ) {\n        super(name, opts, relative);\n        this.keys = keys;\n    }\n\n    update(obj: GameObj<any>, t: number): boolean {\n        const [index, alpha, isFinished] = this.getLowerKeyIndexAndRelativeTime(\n            t,\n            this.keys.length,\n            this.timing,\n        );\n        // Return exact value in case of exact hit or no interpolation, otherwise interpolate\n        if (alpha == 0 || this.interpolation == \"none\") {\n            this.setValue(obj, this.name, this.keys[index]);\n        }\n        else {\n            const easing = this.easings ? this.easings[index] : this.easing;\n            this.setValue(\n                obj,\n                this.name,\n                this.keys[index].lerp(\n                    this.keys[index + 1],\n                    easing(alpha),\n                ),\n            );\n        }\n        return isFinished;\n    }\n\n    serialize() {\n        return Object.assign(super.serialize(), { keys: this.keys });\n    }\n}\n\ntype AnimationChannelKeys = number[] | number[][];\n\ntype AnimationOptions = {\n    duration: number;\n    loops?: number;\n    direction?: TimeDirection;\n    easing?: string;\n    interpolation?: Interpolation;\n    timing?: number[];\n    easings?: string[];\n};\n\ntype AnimationChannel = {\n    keys: AnimationChannelKeys;\n} & AnimationOptions;\n\ntype Animation = {\n    name: string;\n    followMotion?: boolean;\n    relative?: boolean;\n    channels?: Record<string, AnimationChannel>;\n    children?: Animation[];\n};\n\nexport function animate(gopts: AnimateCompOpt = {}): AnimateComp {\n    const channels: AnimateChannel[] = [];\n    let t = 0;\n    let isFinished = false;\n    return {\n        id: \"animate\",\n        require: gopts.followMotion ? [\"rotate\"] : undefined,\n        base: {\n            pos: vec2(0, 0),\n            angle: 0,\n            scale: vec2(1, 1),\n            opacity: 1,\n        },\n        animation: {\n            paused: false,\n            seek(time: number) {\n                t = clamp(time, 0, this.duration);\n                channels.forEach(channel => {\n                    channel.isFinished = false;\n                });\n                isFinished = false;\n            },\n            get duration() {\n                return channels.reduce(\n                    (acc, channel) => Math.max(channel.duration, acc),\n                    0,\n                );\n            },\n        },\n        add(this: GameObj<AnimateComp>) {\n            if (gopts.relative) {\n                if (this.has(\"pos\")) {\n                    this.base.pos = (this as any).pos.clone();\n                }\n                if (this.has(\"rotate\")) {\n                    this.base.angle = (this as any).angle;\n                }\n                if (this.has(\"scale\")) {\n                    this.base.scale = (this as any).scale;\n                }\n                if (this.has(\"opacity\")) {\n                    this.base.opacity = (this as any).opacity;\n                }\n            }\n        },\n        update() {\n            if (this.animation.paused) return;\n            let allFinished: boolean = true;\n            let localFinished: boolean;\n            t += dt();\n            for (const c of channels) {\n                localFinished = c.update(this as unknown as GameObj<any>, t);\n                if (localFinished && !c.isFinished) {\n                    c.isFinished = true;\n                    (this as unknown as GameObj<any>).trigger(\n                        \"animateChannelFinished\",\n                        c.name,\n                    );\n                }\n                allFinished &&= localFinished;\n            }\n            if (allFinished && !isFinished) {\n                isFinished = true;\n                (this as unknown as GameObj<any>).trigger(\"animateFinished\");\n            }\n        },\n        animate<T extends LerpValue>(\n            name: string,\n            keys: T[],\n            opts: AnimateOpt,\n        ) {\n            isFinished = false;\n            this.unanimate(name);\n            if (typeof keys[0] === \"number\") {\n                channels.push(\n                    new AnimateChannelNumber(\n                        name,\n                        keys as number[],\n                        opts,\n                        gopts.relative || false,\n                    ),\n                );\n            }\n            else if (keys[0] instanceof Vec2) {\n                channels.push(\n                    new AnimateChannelVec2(\n                        name,\n                        keys as Vec2[],\n                        opts,\n                        gopts.relative || false,\n                        name === \"pos\" && (gopts.followMotion || false),\n                    ),\n                );\n            }\n            else if (keys[0] instanceof Color) {\n                channels.push(\n                    new AnimateChannelColor(\n                        name,\n                        keys as Color[],\n                        opts,\n                        gopts.relative || false,\n                    ),\n                );\n            }\n        },\n        unanimate(name: string) {\n            const index = channels.findIndex(c => c.name === name);\n            if (index >= 0) {\n                channels.splice(index, 1);\n            }\n        },\n        unanimateAll() {\n            channels.splice(0, channels.length);\n        },\n        onAnimateFinished(cb: () => void) {\n            return (this as unknown as GameObj<any>).on(\"animateFinished\", cb);\n        },\n        onAnimateChannelFinished(cb: (name: string) => void) {\n            return (this as unknown as GameObj<any>).on(\n                \"animateChannelFinished\",\n                cb,\n            );\n        },\n        serializeAnimationChannels() {\n            return channels.reduce((o: Record<string, AnimationChannel>, c) => {\n                o[c.name] = c.serialize();\n                return o;\n            }, {});\n        },\n        serializeAnimationOptions() {\n            const options: any = {};\n            if (gopts.followMotion) {\n                options.followMotion = true;\n            }\n            if (gopts.relative) {\n                options.relative = true;\n            }\n            return options;\n        },\n    };\n}\n\n/**\n * Serializes an animation to javascript objects for serialization to JSON.\n * @param obj The root object to serialize from.\n * @param name Optional name of the root object.\n * @returns A javascript object serialization of the animation.\n */\nexport function serializeAnimation(obj: GameObj<any>, name: string): any {\n    let serialization: Animation = { name: obj.name };\n    if (obj.has(\"animate\")) {\n        serialization.channels = (obj as GameObj<AnimateComp>)\n            .serializeAnimationChannels();\n        Object.assign(\n            serialization,\n            (obj as GameObj<NamedComp | AnimateComp>)\n                .serializeAnimationOptions(),\n        );\n    }\n    if (obj.children.length > 0) {\n        serialization.children = obj.children.filter(o => o.has(\"named\")).map(\n            o => serializeAnimation(o, o.name),\n        );\n    }\n    return serialization;\n}\n\nfunction deserializeKeys(keys: AnimationChannelKeys) {\n    if (typeof keys[0] == \"number\") {\n        return keys;\n    }\n    else if (Array.isArray(keys[0])) {\n        if (keys[0].length == 2) {\n            return (keys as number[][]).map(k => new Vec2(k[0], k[1]));\n        }\n        else if (keys[0].length == 3) {\n            return (keys as number[][]).map(k => new Color(k[0], k[1], k[2]));\n        }\n    }\n}\n\nfunction deserializeOptions(options: AnimationOptions) {\n    if (options.easing) {\n        options.easing = (easings as any)[options.easing];\n    }\n    if (options.easings) {\n        options.easings = options.easings.map(e => (easings as any)[e]);\n    }\n    return options;\n}\n\n/**\n * Applies the animation to this object and its named children\n * @param obj The root object to deserialize to.\n * @param animation A javascript object serialization of the animation.\n */\nexport function applyAnimation(obj: GameObj<any>, animation: Animation) {\n    // TODO: test this\n    obj.use(animate({\n        followMotion: animation.followMotion,\n        relative: animation.relative,\n    }));\n    if (animation.channels) {\n        for (const name in animation.channels) {\n            const channel = animation.channels[name];\n            obj.animate(\n                name,\n                deserializeKeys(channel.keys),\n                deserializeOptions(channel),\n            );\n        }\n    }\n    if (animation.children) {\n        for (const childAnimation of animation.children) {\n            const q = obj.query({ name: childAnimation.name });\n            if (q.length != 0) {\n                applyAnimation(q[0], childAnimation);\n            }\n        }\n    }\n}\n", "import { dt } from \"../../app\";\nimport { vec2 } from \"../../math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { ScaleComp } from \"../transform/scale\";\n\nexport function boom(speed: number = 2, size: number = 1): Comp {\n    let time = 0;\n    return {\n        require: [\"scale\"],\n        update(this: GameObj<ScaleComp>) {\n            const s = Math.sin(time * speed) * size;\n            if (s < 0) {\n                this.destroy();\n            }\n            this.scale = vec2(s);\n            time += dt();\n        },\n    };\n}\n", "import type { Comp, GameObj } from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\n\n/**\n * The {@link health `health()`} component.\n *\n * @group Component Types\n */\nexport interface HealthComp extends Comp {\n    /**\n     * Decrease HP by n (defaults to 1).\n     */\n    hurt(n?: number): void;\n    /**\n     * Increase HP by n (defaults to 1).\n     */\n    heal(n?: number): void;\n    /**\n     * Current health points.\n     */\n    hp(): number;\n    /**\n     * Set current health points.\n     */\n    setHP(hp: number): void;\n    /**\n     * Max amount of HP.\n     */\n    maxHP(): number | null;\n    /**\n     * Set max amount of HP.\n     */\n    setMaxHP(hp: number): void;\n    /**\n     * Register an event that runs when hurt() is called upon the object.\n     *\n     * @since v2000.1\n     */\n    onHurt(action: (amount?: number) => void): KEventController;\n    /**\n     * Register an event that runs when heal() is called upon the object.\n     *\n     * @since v2000.1\n     */\n    onHeal(action: (amount?: number) => void): KEventController;\n    /**\n     * Register an event that runs when object's HP is equal or below 0.\n     *\n     * @since v2000.1\n     */\n    onDeath(action: () => void): KEventController;\n}\n\nexport function health(\n    hp: number,\n    maxHP?: number,\n): HealthComp {\n    if (hp == null) {\n        throw new Error(\"health() requires the initial amount of hp\");\n    }\n\n    return {\n        id: \"health\",\n        hurt(this: GameObj, n: number = 1) {\n            this.setHP(hp - n);\n            this.trigger(\"hurt\", n);\n        },\n        heal(this: GameObj, n: number = 1) {\n            const origHP = hp;\n            this.setHP(hp + n);\n            this.trigger(\"heal\", hp - origHP);\n        },\n        hp(): number {\n            return hp;\n        },\n        maxHP(): number | null {\n            return maxHP ?? null;\n        },\n        setMaxHP(n: number): void {\n            maxHP = n;\n        },\n        setHP(this: GameObj, n: number) {\n            hp = maxHP ? Math.min(maxHP, n) : n;\n            if (hp <= 0) {\n                this.trigger(\"death\");\n            }\n        },\n        onHurt(\n            this: GameObj,\n            action: (amount?: number) => void,\n        ): KEventController {\n            return this.on(\"hurt\", action);\n        },\n        onHeal(\n            this: GameObj,\n            action: (amount?: number) => void,\n        ): KEventController {\n            return this.on(\"heal\", action);\n        },\n        onDeath(this: GameObj, action: () => void): KEventController {\n            return this.on(\"death\", action);\n        },\n        inspect() {\n            return `health: ${hp}`;\n        },\n    };\n}\n", "import { _k } from \"../../kaplay\";\nimport easings from \"../../math/easings\";\nimport type { EmptyComp, GameObj } from \"../../types\";\nimport type { OpacityComp } from \"../draw/opacity\";\n\n/**\n * The {@link lifespan `lifespan()`} component.\n *\n * @group Component Types\n */\nexport interface LifespanCompOpt {\n    /**\n     * Fade out duration (default 0 which is no fade out).\n     */\n    fade?: number;\n}\n\nexport function lifespan(time: number, opt: LifespanCompOpt = {}): EmptyComp {\n    if (time == null) {\n        throw new Error(\"lifespan() requires time\");\n    }\n    const fade = opt.fade ?? 0;\n    return {\n        id: \"lifespan\",\n        require: [\"opacity\"],\n        add(this: GameObj<OpacityComp>) {\n            _k.game.root.wait(time, () => {\n                this.opacity = this.opacity ?? 1;\n\n                if (fade > 0) {\n                    _k.game.root.tween(\n                        this.opacity,\n                        0,\n                        fade,\n                        (a) => this.opacity = a,\n                        easings.linear,\n                    ).onEnd(() => {\n                        this.destroy();\n                    });\n                }\n                else {\n                    this.destroy();\n                }\n            });\n        },\n    };\n}\n", "import type { Comp } from \"../../types\";\n\n/**\n * The {@link named `named()`} component.\n *\n * @group Component Types\n */\nexport interface NamedComp extends Comp {\n    /** The name assigned to this object. */\n    name: string;\n}\n\nexport function named(name: string): NamedComp {\n    return {\n        id: \"named\",\n        name,\n    };\n}\n", "import type { Comp } from \"../../types\";\nimport { KEvent, KEventController } from \"../../utils/\";\n\n/**\n * The {@link state `state()`} component.\n *\n * @group Component Types\n */\nexport interface StateComp extends Comp {\n    /**\n     * Current state.\n     */\n    state: string;\n    /**\n     * Enter a state, trigger onStateEnd for previous state and onStateEnter for the new State state.\n     */\n    enterState: (state: string, ...args: any) => void;\n    /**\n     * Register event that runs once when a specific state transition happens. Accepts arguments passed from `enterState(name, ...args)`.\n     *\n     * @since v2000.2\n     */\n    onStateTransition(\n        from: string,\n        to: string,\n        action: () => void,\n    ): KEventController;\n    /**\n     * Register event that runs once when enters a specific state. Accepts arguments passed from `enterState(name, ...args)`.\n     */\n    onStateEnter: (\n        state: string,\n        action: (...args: any) => void,\n    ) => KEventController;\n    /**\n     * Register an event that runs once when leaves a specific state.\n     */\n    onStateEnd: (state: string, action: () => void) => KEventController;\n    /**\n     * Register an event that runs every frame when in a specific state.\n     */\n    onStateUpdate: (state: string, action: () => void) => KEventController;\n    /**\n     * Register an event that runs every frame when in a specific state.\n     */\n    onStateDraw: (state: string, action: () => void) => KEventController;\n}\n\nexport function state(\n    initState: string,\n    stateList?: string[],\n    transitions?: Record<string, string | string[]>,\n): StateComp {\n    if (!initState) {\n        throw new Error(\"state() requires an initial state\");\n    }\n\n    const events: { [k: string]: any } = {};\n\n    function initStateEvents(state: string) {\n        if (!events[state]) {\n            events[state] = {\n                enter: new KEvent(),\n                end: new KEvent(),\n                update: new KEvent(),\n                draw: new KEvent(),\n            };\n        }\n    }\n\n    function on(event: string, state: string, action: () => void) {\n        initStateEvents(state);\n        return events[state][event].add(action);\n    }\n\n    function trigger(event: string, state: string, ...args: any[]) {\n        initStateEvents(state);\n        events[state][event].trigger(...args);\n    }\n\n    let didFirstEnter = false;\n\n    return {\n        id: \"state\",\n        state: initState,\n\n        enterState(state: string, ...args) {\n            didFirstEnter = true;\n\n            if (stateList && !stateList.includes(state)) {\n                throw new Error(`State not found: ${state}`);\n            }\n\n            const oldState = this.state;\n\n            if (transitions) {\n                // check if the transition is legal, if transition graph is defined\n                if (!transitions?.[oldState]) {\n                    return;\n                }\n\n                const available = typeof transitions[oldState] === \"string\"\n                    ? [transitions[oldState]]\n                    : transitions[oldState] as string[];\n\n                if (!available.includes(state)) {\n                    throw new Error(\n                        `Cannot transition state from \"${oldState}\" to \"${state}\". Available transitions: ${\n                            available.map((s) => `\"${s}\"`).join(\", \")\n                        }`,\n                    );\n                }\n            }\n\n            trigger(\"end\", oldState, ...args);\n            this.state = state;\n            trigger(\"enter\", state, ...args);\n            trigger(\"enter\", `${oldState} -> ${state}`, ...args);\n        },\n\n        onStateTransition(\n            from: string,\n            to: string,\n            action: () => void,\n        ): KEventController {\n            return on(\"enter\", `${from} -> ${to}`, action);\n        },\n\n        onStateEnter(state: string, action: () => void): KEventController {\n            return on(\"enter\", state, action);\n        },\n\n        onStateUpdate(state: string, action: () => void): KEventController {\n            return on(\"update\", state, action);\n        },\n\n        onStateDraw(state: string, action: () => void): KEventController {\n            return on(\"draw\", state, action);\n        },\n\n        onStateEnd(state: string, action: () => void): KEventController {\n            return on(\"end\", state, action);\n        },\n\n        update() {\n            // execute the enter event for initState\n            if (!didFirstEnter) {\n                trigger(\"enter\", initState);\n                didFirstEnter = true;\n            }\n            trigger(\"update\", this.state);\n        },\n\n        draw() {\n            trigger(\"draw\", this.state);\n        },\n\n        inspect() {\n            return `state: ${this.state}`;\n        },\n    };\n}\n", "import type { Comp } from \"../../types\";\n\n/**\n * The {@link stay `stay()`} component.\n *\n * @group Component Types\n */\nexport interface StayComp extends Comp {\n    /**\n     * If the obj should not be destroyed on scene switch.\n     */\n    stay: boolean;\n    /**\n     * Array of scenes that the obj will stay on.\n     */\n    scenesToStay?: string[];\n}\n\nexport function stay(scenesToStay?: string[]): StayComp {\n    return {\n        id: \"stay\",\n        stay: true,\n        scenesToStay,\n    };\n}\n", "import { _k } from \"../../kaplay\";\nimport type { Comp, GameObj, KAPLAYCtx } from \"../../types\";\nimport type { KEventController } from \"../../utils\";\nimport type { TextComp } from \"../draw/text\";\n\n/**\n * The {@link textInput `textInput()`} component.\n *\n * @group Component Types\n */\nexport interface TextInputComp extends Comp {\n    /**\n     * Enable the text input array from being modified by user input.\n     */\n    hasFocus: boolean;\n    /**\n     * The \"real\" text that the user typed, without any escaping.\n     */\n    typedText: string;\n}\n\nexport function textInput(\n    this: KAPLAYCtx,\n    hasFocus: boolean = true,\n    maxInputLength?: number,\n): TextInputComp {\n    let charEv: KEventController;\n    let backEv: KEventController;\n    return {\n        id: \"textInput\",\n        hasFocus: hasFocus,\n        require: [\"text\"],\n        typedText: \"\",\n        add(this: GameObj<TextComp & TextInputComp>) {\n            const flip = () => {\n                this.text = this.typedText.replace(/([\\[\\\\])/g, \"\\\\$1\");\n            };\n\n            charEv = _k.k.onCharInput((character) => {\n                if (\n                    this.hasFocus\n                    && (!maxInputLength\n                        || this.typedText.length < maxInputLength)\n                ) {\n                    if (_k.k.isKeyDown(\"shift\")) {\n                        this.typedText += character.toUpperCase();\n                    }\n                    else {\n                        this.typedText += character;\n                    }\n                    flip();\n                }\n            });\n\n            backEv = _k.k.onKeyPressRepeat(\"backspace\", () => {\n                if (this.hasFocus) {\n                    this.typedText = this.typedText.slice(0, -1);\n\n                    flip();\n                }\n            });\n        },\n        destroy() {\n            charEv.cancel();\n            backEv.cancel();\n        },\n    };\n}\n", "import { _k } from \"../../kaplay\";\nimport easings from \"../../math/easings\";\nimport { lerp } from \"../../math/math\";\nimport type {\n    Comp,\n    GameObj,\n    LerpValue,\n    TimerController,\n    TweenController,\n} from \"../../types\";\nimport { KEvent } from \"../../utils\";\n\n/**\n * The {@link timer `timer()`} component.\n *\n * @group Component Types\n */\nexport interface TimerComp extends Comp {\n    /**\n     * The maximum number of loops per frame allowed,\n     * to keep loops with sub-frame intervals from freezing the game.\n     */\n    maxLoopsPerFrame: number;\n    /**\n     * Run the callback after n seconds.\n     */\n    wait(time: number, action?: () => void): TimerController;\n    /**\n     * Run the callback every n seconds.\n     *\n     * If waitFirst is false (the default), the function will\n     * be called once on the very next frame, and then loop like normal.\n     *\n     * @since v3000.0\n     */\n    loop(\n        time: number,\n        action: () => void,\n        maxLoops?: number,\n        waitFirst?: boolean,\n    ): TimerController;\n    /**\n     * Tweeeeen! Note that this doesn't specifically mean tweening on this object's property, this just registers the timer on this object, so the tween will cancel with the object gets destroyed, or paused when obj.paused is true.\n     *\n     * @since v3000.0\n     */\n    tween<V extends LerpValue>(\n        from: V,\n        to: V,\n        duration: number,\n        setValue: (value: V) => void,\n        easeFunc?: (t: number) => number,\n    ): TweenController;\n}\n\nexport function timer(maxLoopsPerFrame: number = 1000): TimerComp {\n    return {\n        id: \"timer\",\n        maxLoopsPerFrame,\n        loop(\n            this: GameObj<TimerComp>,\n            time: number,\n            action: () => void,\n            count: number = Infinity,\n            waitFirst: boolean = false,\n        ): TimerController {\n            let t: number = waitFirst ? 0 : time;\n            let onEndEvents = new KEvent();\n            const ev = this.onUpdate(() => {\n                t += _k.app.state.dt;\n                for (let i = 0; t >= time && i < this.maxLoopsPerFrame; i++) {\n                    count--;\n                    action();\n                    t -= time;\n                    if (count <= 0) {\n                        ev.cancel();\n                        onEndEvents.trigger();\n                        return;\n                    }\n                }\n            });\n            return {\n                get paused() {\n                    return ev.paused;\n                },\n                set paused(p) {\n                    ev.paused = p;\n                },\n                cancel: ev.cancel,\n                onEnd(f) {\n                    onEndEvents.add(f);\n                },\n                then(f) {\n                    onEndEvents.add(f);\n                    return this;\n                },\n            };\n        },\n        wait(\n            this: GameObj<TimerComp>,\n            time: number,\n            action?: () => void,\n        ): TimerController {\n            return this.loop(time, action ?? (() => { }), 1, true);\n        },\n        tween<V extends LerpValue>(\n            this: GameObj<TimerComp>,\n            from: V,\n            to: V,\n            duration: number,\n            setValue: (value: V) => void,\n            easeFunc = easings.linear,\n        ) {\n            let curTime = 0;\n            const onEndEvents: Array<() => void> = [];\n            const ev = this.onUpdate(() => {\n                curTime += _k.app.state.dt;\n                const t = Math.min(curTime / duration, 1);\n                setValue(lerp(from, to, easeFunc(t)));\n                if (t === 1) {\n                    ev.cancel();\n                    setValue(to);\n                    onEndEvents.forEach((action) => action());\n                }\n            });\n            return {\n                get paused() {\n                    return ev.paused;\n                },\n                set paused(p) {\n                    ev.paused = p;\n                },\n                onEnd(action: () => void) {\n                    onEndEvents.push(action);\n                },\n                then(action: () => void) {\n                    this.onEnd(action);\n                    return this;\n                },\n                cancel() {\n                    ev.cancel();\n                },\n                finish() {\n                    ev.cancel();\n                    setValue(to);\n                    onEndEvents.forEach((action) => action());\n                },\n            };\n        },\n    };\n}\n", "import { DEF_ANCHOR } from \"../../constants\";\nimport { isFixed } from \"../../game/utils\";\nimport {\n    anchorPt,\n    drawCircle,\n    drawPolygon,\n    drawRect,\n    getViewportScale,\n    popTransform,\n    pushTransform,\n    pushTranslate,\n} from \"../../gfx\";\nimport { _k } from \"../../kaplay\";\nimport { rgb } from \"../../math/color\";\nimport {\n    Circle,\n    Polygon,\n    Rect,\n    testPolygonPoint,\n    Vec2,\n    vec2,\n} from \"../../math/math\";\nimport type {\n    Collision,\n    Comp,\n    Cursor,\n    GameObj,\n    MouseButton,\n    Shape,\n    Tag,\n} from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\nimport type { AnchorComp } from \"../transform/anchor\";\nimport type { FixedComp } from \"../transform/fixed\";\nimport type { PosComp } from \"../transform/pos\";\n\nlet areaCount = 0;\n\nexport function usesArea() {\n    return areaCount > 0;\n}\n\n/**\n * The {@link area `area()`} component.\n *\n * @group Component Types\n */\nexport interface AreaComp extends Comp {\n    /**\n     * Collider area info.\n     */\n    area: {\n        /**\n         * If we use a custom shape over render shape.\n         */\n        shape: Shape | null;\n        /**\n         * Area scale.\n         */\n        scale: Vec2;\n        /**\n         * Area offset.\n         */\n        offset: Vec2;\n        /**\n         * Cursor on hover.\n         */\n        cursor: Cursor | null;\n    };\n    /**\n     * If this object should ignore collisions against certain other objects.\n     *\n     * @since v3000.0\n     */\n    collisionIgnore: Tag[];\n    /**\n     * If was just clicked on last frame.\n     */\n    isClicked(): boolean;\n    /**\n     * If is being hovered on.\n     */\n    isHovering(): boolean;\n    /**\n     * Check collision with another game obj.\n     *\n     * @since v3000.0\n     */\n    checkCollision(other: GameObj<AreaComp>): Collision | null;\n    /**\n     * Get all collisions currently happening.\n     *\n     * @since v3000.0\n     */\n    getCollisions(): Collision[];\n    /**\n     * If is currently colliding with another game obj.\n     */\n    isColliding(o: GameObj<AreaComp>): boolean;\n    /**\n     * If is currently overlapping with another game obj (like isColliding, but will return false if the objects are just touching edges).\n     */\n    isOverlapping(o: GameObj<AreaComp>): boolean;\n    /**\n     * Register an event runs when clicked.\n     *\n     * @since v2000.1\n     */\n    onClick(f: () => void, btn?: MouseButton): KEventController;\n    /**\n     * Register an event runs once when hovered.\n     *\n     * @since v3000.0\n     */\n    onHover(action: () => void): KEventController;\n    /**\n     * Register an event runs every frame when hovered.\n     *\n     * @since v3000.0\n     */\n    onHoverUpdate(action: () => void): KEventController;\n    /**\n     * Register an event runs once when unhovered.\n     *\n     * @since v3000.0\n     */\n    onHoverEnd(action: () => void): KEventController;\n    /**\n     * Register an event runs once when collide with another game obj with certain tag.\n     *\n     * @since v2001.0\n     */\n    onCollide(\n        tag: Tag,\n        f: (obj: GameObj, col?: Collision) => void,\n    ): KEventController;\n    /**\n     * Register an event runs once when collide with another game obj.\n     *\n     * @since v2000.1\n     */\n    onCollide(f: (obj: GameObj, col?: Collision) => void): KEventController;\n    /**\n     * Register an event runs every frame when collide with another game obj with certain tag.\n     *\n     * @since v3000.0\n     */\n    onCollideUpdate(\n        tag: Tag,\n        f: (obj: GameObj, col?: Collision) => KEventController,\n    ): KEventController;\n    /**\n     * Register an event runs every frame when collide with another game obj.\n     *\n     * @since v3000.0\n     */\n    onCollideUpdate(\n        f: (obj: GameObj, col?: Collision) => void,\n    ): KEventController;\n    /**\n     * Register an event runs once when stopped colliding with another game obj with certain tag.\n     *\n     * @since v3000.0\n     */\n    onCollideEnd(tag: Tag, f: (obj: GameObj) => void): KEventController;\n    /**\n     * Register an event runs once when stopped colliding with another game obj.\n     *\n     * @since v3000.0\n     */\n    onCollideEnd(f: (obj: GameObj) => void): void;\n    /**\n     * If has a certain point inside collider.\n     */\n    hasPoint(p: Vec2): boolean;\n    /**\n     * Push out from another solid game obj if currently overlapping.\n     */\n    resolveCollision(obj: GameObj): void;\n    /**\n     * Get the geometry data for the collider in local coordinate space.\n     *\n     * @since v3000.0\n     */\n    localArea(): Shape;\n    /**\n     * Get the geometry data for the collider in world coordinate space.\n     */\n    worldArea(): Polygon;\n    /**\n     * Get the geometry data for the collider in screen coordinate space.\n     */\n    screenArea(): Polygon;\n}\n\n/**\n * Options for the {@link area `area()`} component.\n *\n * @group Component Types\n */\nexport interface AreaCompOpt {\n    /**\n     * The shape of the area (currently only Rect and Polygon is supported).\n     *\n     * @example\n     * ```js\n     * add([\n     *     sprite(\"butterfly\"),\n     *     pos(100, 200),\n     *     // a triangle shape!\n     *     area({ shape: new Polygon([vec2(0), vec2(100), vec2(-100, 100)]) }),\n     * ])\n     * ```\n     */\n    shape?: Shape;\n    /**\n     * Area scale.\n     */\n    scale?: number | Vec2;\n    /**\n     * Area offset.\n     */\n    offset?: Vec2;\n    /**\n     * Cursor on hover.\n     */\n    cursor?: Cursor;\n    /**\n     * If this object should ignore collisions against certain other objects.\n     *\n     * @since v3000.0\n     */\n    collisionIgnore?: Tag[];\n}\n\nexport function area(opt: AreaCompOpt = {}): AreaComp {\n    const colliding: Record<string, Collision> = {};\n    const collidingThisFrame = new Set();\n    const events: KEventController[] = [];\n\n    return {\n        id: \"area\",\n        collisionIgnore: opt.collisionIgnore ?? [],\n\n        add(this: GameObj<AreaComp>) {\n            areaCount++;\n            if (this.area.cursor) {\n                events.push(\n                    this.onHover(() => _k.app.setCursor(this.area.cursor!)),\n                );\n            }\n\n            events.push(this.onCollideUpdate((obj, col) => {\n                if (!obj.id) {\n                    throw new Error(\"area() requires the object to have an id\");\n                }\n                if (!colliding[obj.id]) {\n                    this.trigger(\"collide\", obj, col);\n                }\n                if (!col) {\n                    return;\n                }\n\n                colliding[obj.id] = col;\n                collidingThisFrame.add(obj.id);\n            }));\n        },\n\n        destroy() {\n            areaCount--;\n            for (const event of events) {\n                event.cancel();\n            }\n        },\n\n        fixedUpdate(this: GameObj<AreaComp>) {\n            for (const id in colliding) {\n                if (!collidingThisFrame.has(Number(id))) {\n                    this.trigger(\"collideEnd\", colliding[id].target);\n                    delete colliding[id];\n                }\n            }\n            collidingThisFrame.clear();\n        },\n\n        drawInspect(this: GameObj<AreaComp | AnchorComp | FixedComp>) {\n            const a = this.localArea();\n\n            pushTransform();\n            pushTranslate(this.area.offset);\n\n            const opts = {\n                outline: {\n                    width: 4 / getViewportScale(),\n                    color: rgb(0, 0, 255),\n                },\n                anchor: this.anchor,\n                fill: false,\n                fixed: isFixed(this),\n            };\n\n            if (a instanceof Rect) {\n                drawRect({\n                    ...opts,\n                    pos: a.pos,\n                    width: a.width * this.area.scale.x,\n                    height: a.height * this.area.scale.y,\n                });\n            }\n            else if (a instanceof Polygon) {\n                drawPolygon({\n                    ...opts,\n                    pts: a.pts,\n                    scale: this.area.scale,\n                });\n            }\n            else if (a instanceof Circle) {\n                drawCircle({\n                    ...opts,\n                    pos: a.center,\n                    radius: a.radius,\n                });\n            }\n\n            popTransform();\n        },\n\n        area: {\n            shape: opt.shape ?? null,\n            scale: opt.scale ? vec2(opt.scale) : vec2(1),\n            offset: opt.offset ?? vec2(0),\n            cursor: opt.cursor ?? null,\n        },\n\n        isClicked(): boolean {\n            return _k.app.isMousePressed() && this.isHovering();\n        },\n\n        isHovering(this: GameObj) {\n            const mpos = isFixed(this)\n                ? _k.k.mousePos()\n                : _k.k.toWorld(_k.k.mousePos());\n            return this.hasPoint(mpos);\n        },\n\n        checkCollision(this: GameObj, other: GameObj<AreaComp>) {\n            if (!other.id) {\n                throw new Error(\n                    \"checkCollision() requires the object to have an id\",\n                );\n            }\n            return colliding[other.id] ?? null;\n        },\n\n        getCollisions() {\n            return Object.values(colliding);\n        },\n\n        // TODO: perform check instead of use cache\n        isColliding(other: GameObj<AreaComp>) {\n            if (!other.id) {\n                throw new Error(\n                    \"isColliding() requires the object to have an id\",\n                );\n            }\n            return Boolean(colliding[other.id]);\n        },\n\n        isOverlapping(other) {\n            if (!other.id) {\n                throw new Error(\n                    \"isOverlapping() requires the object to have an id\",\n                );\n            }\n            const col = colliding[other.id];\n            return col && col.hasOverlap();\n        },\n\n        onClick(\n            this: GameObj<AreaComp>,\n            f: () => void,\n            btn: MouseButton = \"left\",\n        ): KEventController {\n            const e = this.onMousePress(btn, () => {\n                if (this.isHovering()) {\n                    f();\n                }\n            });\n            events.push(e);\n\n            return e;\n        },\n\n        onHover(this: GameObj, action: () => void): KEventController {\n            let hovering = false;\n            return this.onUpdate(() => {\n                if (!hovering) {\n                    if (this.isHovering()) {\n                        hovering = true;\n                        action();\n                    }\n                }\n                else {\n                    hovering = this.isHovering();\n                }\n            });\n        },\n\n        onHoverUpdate(this: GameObj, onHover: () => void): KEventController {\n            return this.onUpdate(() => {\n                if (this.isHovering()) {\n                    onHover();\n                }\n            });\n        },\n\n        onHoverEnd(this: GameObj, action: () => void): KEventController {\n            let hovering = false;\n            return this.onUpdate(() => {\n                if (hovering) {\n                    if (!this.isHovering()) {\n                        hovering = false;\n                        action();\n                    }\n                }\n                else {\n                    hovering = this.isHovering();\n                }\n            });\n        },\n\n        onCollide(\n            this: GameObj,\n            tag: Tag | ((obj: GameObj, col?: Collision) => void),\n            cb?: (obj: GameObj, col?: Collision) => void,\n        ): KEventController {\n            if (typeof tag === \"function\" && cb === undefined) {\n                return this.on(\"collide\", tag);\n            }\n            else if (typeof tag === \"string\") {\n                return this.onCollide((obj: GameObj, col: Collision) => {\n                    if (obj.is(tag)) {\n                        cb?.(obj, col);\n                    }\n                });\n            }\n            else {\n                throw new Error(\n                    \"onCollide() requires either a function or a tag\",\n                );\n            }\n        },\n\n        onCollideUpdate(\n            this: GameObj<AreaComp>,\n            tag: Tag | ((obj: GameObj, col?: Collision) => void),\n            cb?: (obj: GameObj, col?: Collision) => void,\n        ): KEventController {\n            if (typeof tag === \"function\" && cb === undefined) {\n                return this.on(\"collideUpdate\", tag);\n            }\n            else if (typeof tag === \"string\") {\n                return this.on(\n                    \"collideUpdate\",\n                    (obj, col) => obj.is(tag) && cb?.(obj, col),\n                );\n            }\n            else {\n                throw new Error(\n                    \"onCollideUpdate() requires either a function or a tag\",\n                );\n            }\n        },\n\n        onCollideEnd(\n            this: GameObj<AreaComp>,\n            tag: Tag | ((obj: GameObj) => void),\n            cb?: (obj: GameObj) => void,\n        ): KEventController {\n            if (typeof tag === \"function\" && cb === undefined) {\n                return this.on(\"collideEnd\", tag);\n            }\n            else if (typeof tag === \"string\") {\n                return this.on(\n                    \"collideEnd\",\n                    (obj) => obj.is(tag) && cb?.(obj),\n                );\n            }\n            else {\n                throw new Error(\n                    \"onCollideEnd() requires either a function or a tag\",\n                );\n            }\n        },\n\n        hasPoint(pt: Vec2): boolean {\n            // TODO: convert to pt to local space instead\n            return testPolygonPoint(this.worldArea(), pt);\n        },\n\n        // push an obj out of another if they're overlapped\n        resolveCollision(\n            this: GameObj<AreaComp | PosComp>,\n            obj: GameObj<AreaComp>,\n        ) {\n            const col = this.checkCollision(obj);\n            if (col && !col.resolved) {\n                this.pos = this.pos.add(col.displacement);\n                col.resolved = true;\n            }\n        },\n\n        localArea(\n            this: GameObj<AreaComp | { renderArea(): Shape }>,\n        ): Shape {\n            return this.area.shape\n                ? this.area.shape\n                : this.renderArea();\n        },\n\n        // TODO: cache\n        worldArea(this: GameObj<AreaComp | AnchorComp>): Polygon {\n            const localArea = this.localArea();\n\n            if (\n                !(localArea instanceof Polygon || localArea instanceof Rect)\n            ) {\n                throw new Error(\n                    \"Only support polygon and rect shapes for now\",\n                );\n            }\n\n            const transform = this.transform\n                .clone()\n                .translate(this.area.offset)\n                .scale(vec2(this.area.scale ?? 1));\n\n            if (localArea instanceof Rect) {\n                const offset = anchorPt(this.anchor || DEF_ANCHOR)\n                    .add(1, 1)\n                    .scale(-0.5)\n                    .scale(localArea.width, localArea.height);\n                transform.translate(offset);\n            }\n\n            return localArea.transform(transform) as Polygon;\n        },\n\n        screenArea(this: GameObj<AreaComp | FixedComp>): Polygon {\n            const area = this.worldArea();\n            if (isFixed(this)) {\n                return area;\n            }\n            else {\n                return area.transform(_k.game.cam.transform);\n            }\n        },\n\n        inspect() {\n            if (this.area.scale?.x == this.area.scale?.y) {\n                return `area: ${this.area.scale?.x?.toFixed(1)}x`;\n            }\n            else {\n                return `area: (${this.area.scale?.x?.toFixed(1)}x, ${\n                    this.area.scale.y?.toFixed(1)\n                }y)`;\n            }\n        },\n    };\n}\n", "import { dt, fixedDt, restDt } from \"../../app\";\nimport { DEF_JUMP_FORCE, MAX_VEL } from \"../../constants\";\nimport { getGravityDirection } from \"../../game\";\nimport { _k } from \"../../kaplay\";\nimport { lerp, type Vec2, vec2 } from \"../../math/math\";\nimport { calcTransform } from \"../../math/various\";\nimport type { Collision, Comp, GameObj } from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\nimport type { PosComp } from \"../transform/pos\";\nimport type { AreaComp } from \"./area\";\n\n/**\n * The {@link body `body()`} component.\n *\n * @group Component Types\n */\nexport interface BodyComp extends Comp {\n    /**\n     * Object current velocity.\n     *\n     * @since v3001.0\n     */\n    vel: Vec2;\n    /**\n     * How much velocity decays (velocity *= (1 - drag) every frame).\n     *\n     * @since v3001.0\n     */\n    drag: number;\n    /**\n     * If object is static, it won't move, all non static objects won't move past it, and all\n     * calls to addForce(), applyImpulse(), or jump() on this body will do absolutely nothing.\n     */\n    isStatic: boolean;\n    /**\n     * Initial speed in pixels per second for jump().\n     */\n    jumpForce: number;\n    /**\n     * Gravity multiplier.\n     */\n    gravityScale: number;\n    /**\n     * Mass of the body, decides how much a non-static body should move when resolves with another non-static body. (default 1).\n     *\n     * @since v3000.0\n     */\n    mass: number;\n    /**\n     * If object should move with moving platform (default true).\n     *\n     * @since v3000.0\n     */\n    stickToPlatform?: boolean;\n    /**\n     * Current platform landing on.\n     */\n    curPlatform(): GameObj | null;\n    /**\n     * If currently landing on a platform.\n     *\n     * @since v2000.1\n     */\n    isGrounded(): boolean;\n    /**\n     * If currently falling.\n     *\n     * @since v2000.1\n     */\n    isFalling(): boolean;\n    /**\n     * If currently rising.\n     *\n     * @since v3000.0\n     */\n    isJumping(): boolean;\n    /**\n     * Applies an impulse\n     * @param impulse The impulse vector, applied directly\n     */\n    applyImpulse(impulse: Vec2): void;\n    /**\n     * Applies a force\n     * @param force The force vector, applied after scaled by the inverse mass\n     */\n    addForce(force: Vec2): void;\n    /**\n     * Upward thrust.\n     */\n    jump(force?: number): void;\n    /**\n     * Register an event that runs when a collision is resolved.\n     *\n     * @since v3000.0\n     */\n    onPhysicsResolve(action: (col: Collision) => void): KEventController;\n    /**\n     * Register an event that runs before a collision would be resolved.\n     *\n     * @since v3000.0\n     */\n    onBeforePhysicsResolve(action: (col: Collision) => void): KEventController;\n    /**\n     * Register an event that runs when the object is grounded.\n     *\n     * @since v2000.1\n     */\n    onGround(action: () => void): KEventController;\n    /**\n     * Register an event that runs when the object starts falling.\n     *\n     * @since v2000.1\n     */\n    onFall(action: () => void): KEventController;\n    /**\n     * Register an event that runs when the object falls off platform.\n     *\n     * @since v3000.0\n     */\n    onFallOff(action: () => void): KEventController;\n    /**\n     * Register an event that runs when the object bumps into something on the head.\n     *\n     * @since v2000.1\n     */\n    onHeadbutt(action: () => void): KEventController;\n    /**\n     * Register an event that runs when an object lands on this object.\n     *\n     * @since v3001.0\n     */\n    onLand(action: (obj: GameObj) => void): KEventController;\n    /**\n     * Register an event that runs when the object is bumped by another object head.\n     */\n    onHeadbutted(action: (obj: GameObj) => void): KEventController;\n}\n\n/**\n * Options for the {@link body `body()`} component.\n *\n * @group Component Types\n */\nexport interface BodyCompOpt {\n    /**\n     * How much velocity decays (velocity *= (1 - drag) every frame).\n     *\n     * @since v3001.0\n     */\n    drag?: number;\n    /**\n     * Initial speed in pixels per second for jump().\n     */\n    jumpForce?: number;\n    /**\n     * Maximum velocity when falling.\n     */\n    maxVelocity?: number;\n    /**\n     * Gravity multiplier.\n     */\n    gravityScale?: number;\n    /**\n     * If object is static, it won't move, all non static objects won't move past it, and all\n     * calls to addForce(), applyImpulse(), or jump() on this body will do absolutely nothing.\n     *\n     * @since v3000.0\n     */\n    isStatic?: boolean;\n    /**\n     * If object should move with moving platform (default true).\n     *\n     * @since v3000.0\n     */\n    stickToPlatform?: boolean;\n    /**\n     * Mass of the body, decides how much a non-static body should move when resolves with another non-static body. (default 1).\n     *\n     * @since v3000.0\n     */\n    mass?: number;\n}\n\nexport function body(opt: BodyCompOpt = {}): BodyComp {\n    let curPlatform: GameObj<PosComp | AreaComp | BodyComp> | null = null;\n    let lastPlatformPos: null | Vec2 = null;\n    let willFall = false;\n    const acc = vec2(0);\n    let prevPhysicsPos: Vec2 | null = null;\n    let nextPhysicsPos: Vec2 | null = null;\n    let prevDrawPos: Vec2;\n\n    return {\n        id: \"body\",\n        require: [\"pos\"],\n        vel: vec2(0),\n        drag: opt.drag ?? 0,\n        jumpForce: opt.jumpForce ?? DEF_JUMP_FORCE,\n        gravityScale: opt.gravityScale ?? 1,\n        isStatic: opt.isStatic ?? false,\n        // TODO: prefer density * area\n        mass: opt.mass ?? 1,\n        add(this: GameObj<PosComp | BodyComp | AreaComp>) {\n            prevPhysicsPos = this.pos.clone();\n            nextPhysicsPos = this.pos.clone();\n            prevDrawPos = this.pos.clone();\n            if (this.mass === 0) {\n                throw new Error(\"Can't set body mass to 0\");\n            }\n\n            if (this.has(\"area\")) {\n                // static vs static: don't resolve\n                // static vs non-static: always resolve non-static\n                // non-static vs non-static: resolve the first one\n                this.onCollideUpdate(\n                    (other, col) => {\n                        if (!col) return;\n                        if (!other.has(\"body\")) return;\n                        if (col.resolved) return;\n\n                        this.trigger(\"beforePhysicsResolve\", col);\n                        const rcol = col.reverse();\n                        other.trigger(\"beforePhysicsResolve\", rcol);\n\n                        // user can mark 'resolved' in beforePhysicsResolve to stop a resolution\n                        if (col.resolved || rcol.resolved) {\n                            return;\n                        }\n\n                        if (this.isStatic && other.isStatic) {\n                            return;\n                        }\n                        else if (!this.isStatic && !other.isStatic) {\n                            // TODO: update all children transform?\n                            const tmass = this.mass + other.mass;\n                            this.pos = this.pos.add(\n                                col.displacement.scale(other.mass / tmass),\n                            );\n                            other.pos = other.pos.add(\n                                col.displacement.scale(-this.mass / tmass),\n                            );\n                            this.transform = calcTransform(this);\n                            other.transform = calcTransform(other);\n                        }\n                        else {\n                            // if one is static and on is not, resolve the non static one\n                            const col2 = (!this.isStatic && other.isStatic)\n                                ? col\n                                : col.reverse();\n                            col2.source.pos = col2.source.pos.add(\n                                col2.displacement,\n                            );\n                            col2.source.transform = calcTransform(\n                                col2.source,\n                            );\n                        }\n\n                        col.resolved = true;\n                        this.trigger(\"physicsResolve\", col);\n                        other.trigger(\"physicsResolve\", col.reverse());\n                    },\n                );\n\n                this.onPhysicsResolve((col) => {\n                    if (_k.game.gravity) {\n                        if (col.isBottom() && this.isFalling()) {\n                            // Clear the velocity in the direction of gravity, as we've hit something\n                            this.vel = this.vel.reject(\n                                _k.game.gravity.unit(),\n                            );\n                            // We need the past platform to check if we already were on a platform\n                            const pastPlatform = curPlatform;\n                            curPlatform = col.target as GameObj<\n                                PosComp | BodyComp | AreaComp\n                            >;\n                            if (pastPlatform != curPlatform) {\n                                // If we are on a new platform, update the sticky position\n                                lastPlatformPos = col.target.pos;\n                            }\n                            if (willFall) {\n                                // We would have fallen, but didn't.\n                                // This happens when we leave one platform block and move onto another\n                                willFall = false;\n                            }\n                            else if (!pastPlatform) {\n                                // We weren't on a platform, land\n                                this.trigger(\"ground\", curPlatform);\n                                col.target.trigger(\"land\", this);\n                            }\n                        }\n                        else if (col.isTop() && this.isJumping()) {\n                            this.vel = this.vel.reject(\n                                _k.game.gravity.unit(),\n                            );\n                            this.trigger(\"headbutt\", col.target);\n                            col.target.trigger(\"headbutted\", this);\n                        }\n                    }\n                });\n            }\n        },\n\n        update(this: GameObj<PosComp | BodyComp | AreaComp>) {\n            // Sticky platform\n            if (curPlatform) {\n                if (\n                    // We are still colliding with the platform and the platform exists\n                    this.isColliding(curPlatform)\n                    && curPlatform.exists()\n                    && curPlatform.has(\"body\")\n                ) {\n                    // This needs to happen in onUpdate. Otherwise the player position will jitter.\n                    if (\n                        lastPlatformPos\n                        && !curPlatform.pos.eq(lastPlatformPos)\n                        && opt.stickToPlatform !== false\n                    ) {\n                        // Stick to the platform\n                        this.moveBy(\n                            curPlatform.pos.sub(lastPlatformPos),\n                        );\n                    }\n                    lastPlatformPos = curPlatform.pos;\n                }\n            }\n\n            const dt = restDt();\n            if (dt) {\n                // Check if no external changes were made\n                if (this.pos.x == prevDrawPos.x) {\n                    // Interpolate physics steps\n                    this.pos.x = lerp(\n                        prevPhysicsPos!.x,\n                        nextPhysicsPos!.x,\n                        dt / fixedDt(),\n                    );\n                    // Copy to check for changes\n                    prevDrawPos.x = this.pos.x;\n                }\n                if (this.pos.y == prevDrawPos.y) {\n                    // Interpolate physics steps\n                    this.pos.y = lerp(\n                        prevPhysicsPos!.y,\n                        nextPhysicsPos!.y,\n                        dt / fixedDt(),\n                    );\n                    // Copy to check for changes\n                    prevDrawPos.y = this.pos.y;\n                }\n            }\n        },\n\n        fixedUpdate(this: GameObj<PosComp | BodyComp | AreaComp>) {\n            // If we were interpolating, and the position wasn't set manually, reset to last physics position\n            if (prevPhysicsPos) {\n                if (this.pos.x == prevDrawPos.x) {\n                    this.pos.x = prevPhysicsPos.x;\n                }\n                if (this.pos.y == prevDrawPos.y) {\n                    this.pos.y = prevPhysicsPos.y;\n                }\n                prevPhysicsPos = null;\n            }\n\n            if (_k.game.gravity && !this.isStatic) {\n                // If we are falling over the edge of the current a platform\n                if (willFall) {\n                    curPlatform = null;\n                    lastPlatformPos = null;\n                    this.trigger(\"fallOff\");\n                    willFall = false;\n                }\n\n                // If we were previously on a platform\n                if (curPlatform) {\n                    if (\n                        // If we are no longer on the platform, or the platform was deleted\n                        !this.isColliding(curPlatform)\n                        || !curPlatform.exists()\n                        || !curPlatform.has(\"body\")\n                    ) {\n                        willFall = true;\n                    }\n                }\n\n                const prevVel = this.vel.clone();\n\n                // Apply gravity\n                this.vel = this.vel.add(\n                    _k.game.gravity.scale(this.gravityScale * dt()),\n                );\n\n                // Clamp velocity\n                const maxVel = opt.maxVelocity ?? MAX_VEL;\n                if (this.vel.slen() > maxVel * maxVel) {\n                    this.vel = this.vel.unit().scale(maxVel);\n                }\n\n                // Check if we have started to fall.\n                // We do this by looking at the velocity vector along the direction of gravity\n                if (\n                    prevVel.dot(_k.game.gravity) < 0\n                    && this.vel.dot(_k.game.gravity) >= 0\n                ) {\n                    this.trigger(\"fall\");\n                }\n            }\n\n            // Apply velocity and position changes\n            this.vel.x += acc.x * dt();\n            this.vel.y += acc.y * dt();\n\n            this.vel.x *= 1 - this.drag * dt();\n            this.vel.y *= 1 - this.drag * dt();\n\n            this.move(this.vel);\n\n            // If we need to interpolate physics, prepare interpolation data\n            const rDt = restDt();\n            if (rDt) {\n                // Save this position as previous\n                prevPhysicsPos = this.pos.clone();\n                // Calculate next (future) position\n                const nextVel = this.vel.add(acc.scale(dt()));\n                nextPhysicsPos = this.pos.add(nextVel.scale(dt()));\n                // Copy to check for changes\n                prevDrawPos = this.pos.clone();\n            }\n\n            // Reset acceleration\n            acc.x = 0;\n            acc.y = 0;\n        },\n\n        onPhysicsResolve(this: GameObj, action) {\n            return this.on(\"physicsResolve\", action);\n        },\n\n        onBeforePhysicsResolve(this: GameObj, action) {\n            return this.on(\"beforePhysicsResolve\", action);\n        },\n\n        curPlatform(): GameObj | null {\n            return curPlatform;\n        },\n\n        isGrounded() {\n            return curPlatform !== null;\n        },\n\n        isFalling(): boolean {\n            return this.vel.dot(getGravityDirection()) > 0;\n        },\n\n        isJumping(): boolean {\n            return this.vel.dot(getGravityDirection()) < 0;\n        },\n\n        applyImpulse(impulse: Vec2) {\n            if (this.isStatic) return;\n            this.vel = this.vel.add(impulse);\n        },\n\n        addForce(force: Vec2) {\n            if (this.isStatic) return;\n            acc.x += force.x / this.mass;\n            acc.y += force.y / this.mass;\n        },\n\n        jump(force: number) {\n            if (this.isStatic) return;\n            curPlatform = null;\n            lastPlatformPos = null;\n            this.vel = getGravityDirection().scale(\n                -force || -this.jumpForce,\n            );\n        },\n\n        onGround(this: GameObj, action: () => void): KEventController {\n            return this.on(\"ground\", action);\n        },\n\n        onFall(this: GameObj, action: () => void): KEventController {\n            return this.on(\"fall\", action);\n        },\n\n        onFallOff(this: GameObj, action: () => void): KEventController {\n            return this.on(\"fallOff\", action);\n        },\n\n        onHeadbutt(this: GameObj, action: () => void): KEventController {\n            return this.on(\"headbutt\", action);\n        },\n\n        onLand(this: GameObj, action: (obj: GameObj) => void) {\n            return this.on(\"land\", action);\n        },\n\n        onHeadbutted(this: GameObj, action: (obj: GameObj) => void) {\n            return this.on(\"headbutted\", action);\n        },\n\n        inspect() {\n            return `gravityScale: ${this.gravityScale}x`;\n        },\n    };\n}\n", "import type { Comp, GameObj } from \"../../types\";\nimport type { KEventController } from \"../../utils/\";\nimport type { BodyComp } from \"./body\";\n\n/**\n * The {@link doubleJump `doubleJump()`} component.\n *\n * @group Component Types\n */\nexport interface DoubleJumpComp extends Comp {\n    /**\n     * Number of jumps allowed.\n     */\n    numJumps: number;\n    /**\n     * Performs double jump (the initial jump only happens if player is grounded).\n     */\n    doubleJump(force?: number): void;\n    /**\n     * Register an event that runs when the object performs the second jump when double jumping.\n     */\n    onDoubleJump(action: () => void): KEventController;\n}\n\nexport function doubleJump(numJumps: number = 2): DoubleJumpComp {\n    let jumpsLeft = numJumps;\n    return {\n        id: \"doubleJump\",\n        require: [\"body\"],\n        numJumps: numJumps,\n        add(this: GameObj<BodyComp | DoubleJumpComp>) {\n            this.onGround(() => {\n                jumpsLeft = this.numJumps;\n            });\n        },\n        doubleJump(\n            this: GameObj<BodyComp | DoubleJumpComp>,\n            force?: number,\n        ) {\n            if (jumpsLeft <= 0) {\n                return;\n            }\n            if (jumpsLeft < this.numJumps) {\n                this.trigger(\"doubleJump\");\n            }\n            jumpsLeft--;\n            this.jump(force);\n        },\n        onDoubleJump(this: GameObj, action: () => void): KEventController {\n            return this.on(\"doubleJump\", action);\n        },\n        inspect(this: GameObj<BodyComp | DoubleJumpComp>) {\n            return `jumpsLeft: ${jumpsLeft}`;\n        },\n    };\n}\n", "// @ts-nocheck -- TODO: fix eventually\nimport { getGravityDirection } from \"../../game\";\nimport { Polygon, Vec2, vec2 } from \"../../math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { PosComp } from \"../transform\";\nimport type { AreaComp } from \"./area\";\nimport type { BodyComp } from \"./body\";\n\nexport type SurfaceEffectorCompOpt = {\n    speed: number;\n    speedVariation?: number;\n    forceScale?: number;\n};\n\nexport interface SurfaceEffectorComp extends Comp {\n    speed: number;\n    speedVariation: number;\n    forceScale: number;\n}\n\nexport function surfaceEffector(\n    opts: SurfaceEffectorCompOpt,\n): SurfaceEffectorComp {\n    return {\n        id: \"surfaceEffector\",\n        require: [\"area\"],\n        speed: opts.speed,\n        speedVariation: opts.speedVariation ?? 0,\n        forceScale: opts.speedVariation ?? 0.9,\n        add(this: GameObj<AreaComp | SurfaceEffectorComp>) {\n            this.onCollideUpdate(\"body\", (obj, col) => {\n                const dir = col?.normal.normal();\n                const currentVel = obj.vel.project(dir);\n                const wantedVel = dir?.scale(this.speed);\n                const force = wantedVel?.sub(currentVel);\n                obj.addForce(force?.scale(obj.mass * this.forceScale));\n            });\n        },\n    };\n}\n\nexport type AreaEffectorCompOpt = {\n    useGlobalAngle?: boolean;\n    forceAngle: number;\n    forceMagnitude: number;\n    forceVariation?: number;\n    linearDrag?: number;\n    // angularDrag?: number;\n};\n\nexport interface AreaEffectorComp extends Comp {\n    useGlobalAngle: boolean;\n    forceAngle: number;\n    forceMagnitude: number;\n    forceVariation: number;\n    linearDrag?: number;\n    // angularDrag?: number;\n}\n\nexport function areaEffector(opts: AreaEffectorCompOpt): AreaEffectorComp {\n    return {\n        id: \"areaEffector\",\n        require: [\"area\"],\n        useGlobalAngle: opts.useGlobalAngle || false,\n        forceAngle: opts.forceAngle,\n        forceMagnitude: opts.forceMagnitude,\n        forceVariation: opts.forceVariation ?? 0,\n        linearDrag: opts.linearDrag ?? 0,\n        // angularDrag: opts.angularDrag ?? 0,\n        add(this: GameObj<AreaComp | AreaEffectorComp>) {\n            this.onCollideUpdate(\"body\", (obj, col) => {\n                if (!obj.has(\"body\")) return;\n\n                const dir = Vec2.fromAngle(this.forceAngle);\n                const force = dir.scale(this.forceMagnitude);\n                obj.addForce(force);\n                if (this.linearDrag) {\n                    obj.addForce(obj.vel.scale(-this.linearDrag));\n                }\n            });\n        },\n    };\n}\n\nexport type ForceMode = \"constant\" | \"inverseLinear\" | \"inverseSquared\";\n\nexport type PointEffectorCompOpt = {\n    forceMagnitude: number;\n    forceVariation: number;\n    distanceScale?: number;\n    forceMode?: ForceMode;\n    linearDrag?: number;\n    // angularDrag?: number;\n};\n\nexport interface PointEffectorComp extends Comp {\n    forceMagnitude: number;\n    forceVariation: number;\n    distanceScale: number;\n    forceMode: ForceMode;\n    linearDrag: number;\n    // angularDrag: number;\n}\n\nexport function pointEffector(opts: PointEffectorCompOpt): PointEffectorComp {\n    return {\n        id: \"pointEffector\",\n        require: [\"area\", \"pos\"],\n        forceMagnitude: opts.forceMagnitude,\n        forceVariation: opts.forceVariation ?? 0,\n        distanceScale: opts.distanceScale ?? 1,\n        forceMode: opts.forceMode || \"inverseLinear\",\n        linearDrag: opts.linearDrag ?? 0,\n        // angularDrag: opts.angularDrag ?? 0,\n        add(this: GameObj<PointEffectorComp | AreaComp | PosComp>) {\n            this.onCollideUpdate(\"body\", (obj, col) => {\n                const dir = this.pos.sub(obj.pos);\n                const length = dir.len();\n                const distance = length * this.distanceScale / 10;\n                const forceScale = this.forceMode === \"constant\"\n                    ? 1\n                    : this.forceMode === \"inverseLinear\"\n                    ? 1 / distance\n                    : 1 / distance ** 2;\n                const force = dir.scale(\n                    this.forceMagnitude * forceScale / length,\n                );\n                obj.addForce(force);\n                if (this.linearDrag) {\n                    obj.addForce(obj.vel.scale(-this.linearDrag));\n                }\n            });\n        },\n    };\n}\n\nexport type ConstantForceCompOpt = {\n    force?: Vec2;\n};\n\nexport interface ConstantForceComp extends Comp {\n    force?: Vec2;\n}\n\nexport function constantForce(opts: ConstantForceCompOpt): ConstantForceComp {\n    return {\n        id: \"constantForce\",\n        require: [\"body\"],\n        force: opts.force,\n        update(this: GameObj<BodyComp | ConstantForceComp>) {\n            if (this.force) {\n                this.addForce(this.force);\n            }\n        },\n    };\n}\n\nexport type PlatformEffectorCompOpt = {\n    surfaceArc?: number;\n    useOneWay?: boolean;\n};\n\nexport interface PlatformEffectorComp extends Comp {\n    surfaceArc: number;\n    useOneWay: boolean;\n}\n\nexport function platformEffector(\n    opt: PlatformEffectorCompOpt,\n): PlatformEffectorComp {\n    return {\n        id: \"platformEffector\",\n        require: [\"area\", \"body\"],\n        surfaceArc: opt.surfaceArc ?? 180,\n        useOneWay: opt.useOneWay ?? false,\n        add(this: GameObj<BodyComp | AreaComp | PlatformEffectorComp>) {\n            this.onBeforePhysicsResolve(collision => {\n                const v = collision.target.vel;\n                const up = getGravityDirection().scale(-1);\n                const angle = up.angleBetween(v);\n                if (Math.abs(angle) > this.surfaceArc / 2) {\n                    collision.preventResolution();\n                }\n            });\n        },\n    };\n}\n\nexport type BuoyancyEffectorCompOpt = {\n    surfaceLevel: number;\n    density?: number;\n    linearDrag?: number;\n    angularDrag?: number;\n    flowAngle?: number;\n    flowMagnitude?: number;\n    flowVariation?: number;\n};\n\nexport interface BuoyancyEffectorComp extends Comp {\n    surfaceLevel: number;\n    density: number;\n    linearDrag: number;\n    angularDrag: number;\n    flowAngle: number;\n    flowMagnitude: number;\n    flowVariation: number;\n    applyBuoyancy(body: GameObj<BodyComp>, submergedArea: Polygon): void;\n    applyDrag(body: GameObj<BodyComp>, submergedArea: Polygon): void;\n}\n\nexport function buoyancyEffector(\n    opts: BuoyancyEffectorCompOpt,\n): BuoyancyEffectorComp {\n    return {\n        id: \"buoyancyEffector\",\n        require: [\"area\"],\n        surfaceLevel: opts.surfaceLevel,\n        density: opts.density ?? 1,\n        linearDrag: opts.linearDrag ?? 1,\n        angularDrag: opts.angularDrag ?? 0.2,\n        flowAngle: opts.flowAngle ?? 0,\n        flowMagnitude: opts.flowMagnitude ?? 0,\n        flowVariation: opts.flowVariation ?? 0,\n        add(this: GameObj<AreaComp | BuoyancyEffectorComp>) {\n            this.onCollideUpdate(\"body\", (obj, col) => {\n                const o = obj as GameObj<BodyComp | AreaComp>;\n                const polygon = o.worldArea();\n                const [submergedArea, _] = polygon.cut(\n                    vec2(-100, this.surfaceLevel),\n                    vec2(100, this.surfaceLevel),\n                );\n\n                if (submergedArea) {\n                    this.applyBuoyancy(o, submergedArea);\n                    this.applyDrag(o, submergedArea);\n                }\n\n                if (this.flowMagnitude) {\n                    o.addForce(\n                        Vec2.fromAngle(this.flowAngle).scale(\n                            this.flowMagnitude,\n                        ),\n                    );\n                }\n            });\n        },\n        applyBuoyancy(body: GameObj<BodyComp>, submergedArea: Polygon) {\n            const displacedMass = this.density * submergedArea.area();\n            const buoyancyForce = vec2(0, 1).scale(-displacedMass);\n            // console.log(\"buoyancyForce\", buoyancyForce)\n            // TODO: Should be applied to the center of submergedArea, but since there is no torque yet, this is OK\n            body.addForce(buoyancyForce);\n        },\n        applyDrag(body: GameObj<BodyComp>, submergedArea: Polygon) {\n            const velocity = body.vel;\n            const dragMagnitude = this.density * this.linearDrag;\n            const dragForce = velocity.scale(-dragMagnitude);\n            // console.log(\"dragForce\", dragForce)\n            // TODO: Should be applied to the center of submergedArea, but since there is no torque yet, this is OK\n            body.addForce(dragForce);\n            // const angularDrag = submergedArea.area() * -body.angularVelocity * this.angularDrag;\n            // object.addTorque(angularDrag);\n        },\n    };\n}\n", "import type { Vec2 } from \"../../math/math\";\nimport type { Anchor, Comp } from \"../../types\";\n\n/**\n * The {@link anchor `anchor()`} component.\n *\n * @group Component Types\n */\nexport interface AnchorComp extends Comp {\n    /**\n     * Anchor point for render.\n     */\n    anchor: Anchor | Vec2;\n}\n\nexport function anchor(o: Anchor | Vec2): AnchorComp {\n    if (!o) {\n        throw new Error(\"Please define an anchor\");\n    }\n    return {\n        id: \"anchor\",\n        anchor: o,\n        inspect() {\n            if (typeof this.anchor === \"string\") {\n                return `anchor: ` + this.anchor;\n            }\n            else {\n                return `anchor: ` + this.anchor.toString();\n            }\n        },\n    };\n}\n", "import type { Comp } from \"../../types\";\n\n/**\n * The {@link fixed `fixed()`} component.\n *\n * @group Component Types\n */\nexport interface FixedComp extends Comp {\n    /**\n     * If the obj is unaffected by camera\n     */\n    fixed: boolean;\n}\n\nexport function fixed(): FixedComp {\n    return {\n        id: \"fixed\",\n        fixed: true,\n    };\n}\n", "import { Vec2, vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { PosComp } from \"./pos\";\n\n/**\n * The {@link follow `follow()`} component.\n *\n * @group Component Types\n */\nexport interface FollowComp extends Comp {\n    follow: {\n        /**\n         * The object to follow.\n         */\n        obj: GameObj;\n        /**\n         * The offset to follow the object by.\n         */\n        offset: Vec2;\n    };\n}\n\nexport function follow(obj: GameObj, offset?: Vec2): FollowComp {\n    return {\n        id: \"follow\",\n        require: [\"pos\"],\n        follow: {\n            obj: obj,\n            offset: offset ?? vec2(0),\n        },\n        add(this: GameObj<FollowComp | PosComp>) {\n            if (obj.exists()) {\n                this.pos = this.follow.obj.pos.add(this.follow.offset);\n            }\n        },\n        update(this: GameObj<FollowComp | PosComp>) {\n            if (obj.exists()) {\n                this.pos = this.follow.obj.pos.add(this.follow.offset);\n            }\n        },\n    };\n}\n", "import { _k } from \"../../kaplay\";\nimport type { Comp } from \"../../types\";\n\n/**\n * The {@link layer `layer()`} component.\n *\n * @group Component Types\n */\nexport interface LayerComp extends Comp {\n    /**\n     * Get the index of the current layer the object is assigned to.\n     *\n     * @returns The index of the layer the object is assigned to, or `null` if the layer does not exist.\n     */\n    get layerIndex(): number | null;\n    /**\n     * Get the name of the current layer the object is assigned to.\n     *\n     * @returns The name of the layer the object is assigned to.\n     */\n    get layer(): string | null;\n    /**\n     * Set the name of the layer the object should be assigned to.\n     */\n    set layer(name: string);\n}\n\nexport function layer(layer: string): LayerComp {\n    let _layerIndex = _k.game.layers?.indexOf(layer);\n\n    return {\n        id: \"layer\",\n        get layerIndex() {\n            return _layerIndex ?? null;\n        },\n        get layer(): string | null {\n            if (!_layerIndex) return null;\n\n            return _k.game.layers?.[_layerIndex] ?? null;\n        },\n        set layer(value: string) {\n            _layerIndex = _k.game.layers?.indexOf(value);\n\n            if (_layerIndex == -1) throw Error(\"Invalid layer name\");\n        },\n        inspect() {\n            return `layer: ${this.layer}`;\n        },\n    };\n}\n", "import { Vec2 } from \"../../math/math\";\nimport type { EmptyComp, GameObj } from \"../../types\";\nimport type { PosComp } from \"./pos\";\n\nexport function move(dir: number | Vec2, speed: number): EmptyComp {\n    const d = typeof dir === \"number\" ? Vec2.fromAngle(dir) : dir.unit();\n    return {\n        id: \"move\",\n        require: [\"pos\"],\n        update(this: GameObj<PosComp>) {\n            this.move(d.scale(speed));\n        },\n    };\n}\n", "import { DEF_OFFSCREEN_DIS } from \"../../constants\";\nimport type { KEventController } from \"../../events/events\";\nimport { onUpdate } from \"../../events/globalEvents\";\nimport { height, width } from \"../../gfx/stack\";\nimport { Rect, testRectPoint, vec2 } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { RectComp } from \"../draw/rect\";\nimport type { PosComp } from \"./pos\";\n\n/**\n * The {@link offscreen `offscreen()`} component.\n *\n * @group Component Types\n */\nexport interface OffScreenComp extends Comp {\n    /**\n     * The minimum distance that the object must be off the screen by to be considered \"offscreen\".\n     *\n     * If it is undefined, it means that the object will be considered to be offscreen when its bounding rectangle\n     * (defined by width and height) is not intersecting with the screen rectangle.\n     */\n    offscreenDistance: number | undefined;\n    /**\n     * If object is currently out of view.\n     */\n    isOffScreen(): boolean;\n    /**\n     * Register an event that runs when object goes out of view.\n     */\n    onExitScreen(action: () => void): KEventController;\n    /**\n     * Register an event that runs when object enters view.\n     */\n    onEnterScreen(action: () => void): KEventController;\n}\n\n/**\n * Options for {@link offscreen `offscreen()`} component.\n *\n * @group Component Types\n */\nexport interface OffScreenCompOpt {\n    /**\n     * If hide object when out of view.\n     */\n    hide?: boolean;\n    /**\n     * If pause object when out of view.\n     */\n    pause?: boolean;\n    /**\n     * If unpause object when back in view.\n     */\n    unpause?: boolean;\n    /**\n     * If destroy object when out of view.\n     */\n    destroy?: boolean;\n    /**\n     * The distance when out of view is triggered (default 200).\n     *\n     * @since v3000.0\n     */\n    distance?: number;\n}\n\nexport function offscreen(opt: OffScreenCompOpt = {}): OffScreenComp {\n    let isOut = false;\n    const screenRect = new Rect(vec2(0), width(), height());\n    const selfRect = new Rect(vec2(0), 0, 0);\n\n    const check = (self: GameObj<OffScreenComp>) => {\n        if (self.isOffScreen()) {\n            if (!isOut) {\n                self.trigger(\"exitView\");\n                isOut = true;\n            }\n            if (opt.hide) self.hidden = true;\n            if (opt.pause) self.paused = true;\n            if (opt.destroy) self.destroy();\n        }\n        else {\n            if (isOut) {\n                self.trigger(\"enterView\");\n                isOut = false;\n            }\n            if (opt.hide) self.hidden = false;\n            if (opt.pause) self.paused = false;\n        }\n    };\n\n    return {\n        id: \"offscreen\",\n        require: [\"pos\"],\n        offscreenDistance: opt.distance ?? DEF_OFFSCREEN_DIS,\n        isOffScreen(\n            this: GameObj<PosComp | OffScreenComp | RectComp>,\n        ): boolean {\n            const pos = this.screenPos();\n\n            // This is not possible, screenPos() without arguments returns the pos\n            if (!pos) return false;\n\n            screenRect.width = width();\n            screenRect.height = height();\n            if (!this.offscreenDistance && this.width && this.height) {\n                selfRect.width = this.width;\n                selfRect.height = this.height;\n                selfRect.pos = this.pos;\n                return selfRect.collides(screenRect);\n            }\n            const dist = this.offscreenDistance\n                ? this.offscreenDistance\n                : DEF_OFFSCREEN_DIS;\n            return !testRectPoint(screenRect, pos)\n                && screenRect.sdistToPoint(pos) > (dist * dist);\n        },\n        onExitScreen(this: GameObj, action: () => void): KEventController {\n            return this.on(\"exitView\", action);\n        },\n        onEnterScreen(this: GameObj, action: () => void): KEventController {\n            return this.on(\"enterView\", action);\n        },\n        add(this: GameObj<OffScreenComp>) {\n            if (opt.pause && opt.unpause) onUpdate(() => check(this));\n            else this.onUpdate(() => check(this));\n        },\n    };\n}\n", "import { dt } from \"../../app\";\nimport { toScreen, toWorld } from \"../../game\";\nimport { isFixed } from \"../../game/utils\";\nimport { drawCircle, getViewportScale } from \"../../gfx\";\nimport { rgb } from \"../../math\";\nimport { Vec2, vec2, type Vec2Args } from \"../../math/math\";\nimport type { Comp, GameObj } from \"../../types\";\nimport type { FixedComp } from \"./fixed\";\n\n/**\n * The {@link pos `pos()`} component.\n *\n * @group Component Types\n */\nexport interface PosComp extends Comp {\n    /**\n     * Object's current world position.\n     */\n    pos: Vec2;\n    /**\n     * Move how many pixels per second. If object is 'solid', it won't move into other 'solid' objects.\n     */\n    move(xVel: number, yVel: number): void;\n    move(vel: Vec2): void;\n    /**\n     * Move how many pixels, without multiplying dt, but still checking for 'solid'.\n     */\n    moveBy(dx: number, dy: number): void;\n    moveBy(d: Vec2): void;\n    /**\n     * Move to a spot with a speed (pixels per second), teleports if speed is not given.\n     */\n    moveTo(dest: Vec2, speed?: number): void;\n    moveTo(x: number, y: number, speed?: number): void;\n    /**\n     * Get / Set the position of the object on the screen.\n     *\n     * @since v2000.0\n     */\n    screenPos(newPos?: Vec2): Vec2 | null;\n    /**\n     * Get / Set the position of the object relative to the root.\n     *\n     * @since v2000.0\n     */\n    worldPos(newPos?: Vec2): Vec2 | null;\n    /**\n     * Transform a local point (relative to this) to a screen point (relative to the camera)\n     */\n    toScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): Vec2;\n    /**\n     * Transform a local point (relative to this) to a world point (relative to the root)\n     *\n     * @since v3001.0\n     */\n    toWorld(this: GameObj<PosComp>, p: Vec2): Vec2;\n    /**\n     * Transform a screen point (relative to the camera) to a local point (relative to this)\n     *\n     * @since v3001.0\n     */\n    fromScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): Vec2;\n    /**\n     * Transform a world point (relative to the root) to a local point (relative to this)\n     *\n     * @since v3001.0\n     */\n    fromWorld(this: GameObj<PosComp>, p: Vec2): Vec2;\n    /**\n     * Transform a point relative to this to a point relative to other\n     *\n     * @since v3001.0\n     */\n    toOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2): Vec2;\n    /**\n     * Transform a point relative to other to a point relative to this\n     *\n     * @since v3001.0\n     */\n    fromOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2): Vec2;\n}\n\nexport function pos(...args: Vec2Args): PosComp {\n    return {\n        id: \"pos\",\n        pos: vec2(...args),\n\n        moveBy(...args: Vec2Args) {\n            this.pos = this.pos.add(vec2(...args));\n        },\n\n        // move with velocity (pixels per second)\n        move(...args: Vec2Args) {\n            this.moveBy(vec2(...args).scale(dt()));\n        },\n\n        // move to a destination, with optional speed\n        // Adress all ts ignores\n        moveTo(...args) {\n            if (\n                typeof args[0] === \"number\" && typeof args[1] === \"number\"\n            ) {\n                // @ts-ignore Use overload functions here?\n                return this.moveTo(vec2(args[0], args[1]), args[2]);\n            }\n            const dest = args[0];\n            const speed = args[1];\n            if (speed === undefined) {\n                this.pos = vec2(dest);\n                return;\n            }\n            // @ts-ignore\n            const diff = dest.sub(this.pos);\n            if (diff.len() <= speed * dt()) {\n                this.pos = vec2(dest);\n                return;\n            }\n            this.move(diff.unit().scale(speed));\n        },\n\n        // Get the position of the object relative to the root\n        worldPos(this: GameObj<PosComp>, pos: Vec2 | null = null) {\n            if (pos) {\n                this.pos = this.pos.add(this.fromWorld(pos));\n                return null;\n            }\n            else {\n                return this.parent\n                    ? this.parent.transform.multVec2(this.pos)\n                    : this.pos;\n            }\n        },\n\n        // Transform a local point to a world point\n        toWorld(this: GameObj<PosComp>, p: Vec2): Vec2 {\n            return this.parent\n                ? this.parent.transform.multVec2(this.pos.add(p))\n                : this.pos.add(p);\n        },\n\n        // Transform a world point (relative to the root) to a local point (relative to this)\n        fromWorld(this: GameObj<PosComp>, p: Vec2): Vec2 {\n            return this.parent\n                ? this.parent.transform.invert().multVec2(p).sub(this.pos)\n                : p.sub(this.pos);\n        },\n\n        // Transform a screen point (relative to the camera) to a local point (relative to this)\n        screenPos(\n            this: GameObj<PosComp | FixedComp>,\n            pos: Vec2 | null = null,\n        ) {\n            if (pos) {\n                this.pos = this.pos.add(this.fromScreen(pos));\n                return null;\n            }\n            else {\n                const pos = this.worldPos();\n\n                // This is not really possible, because worldPos() will always return a value\n                // if it doesn't have arguments\n\n                // I left this like that for compatibility, maybe if it returns a value\n                // will break something?\n\n                if (!pos) {\n                    return null;\n                }\n\n                return isFixed(this)\n                    ? pos\n                    : toScreen(pos);\n            }\n        },\n\n        // Transform a local point (relative to this) to a screen point (relative to the camera)\n        toScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): Vec2 {\n            const pos = this.toWorld(p);\n            return isFixed(this)\n                ? pos\n                : toScreen(pos);\n        },\n\n        // Transform a screen point (relative to the camera) to a local point (relative to this)\n        fromScreen(this: GameObj<PosComp>, p: Vec2): Vec2 {\n            return isFixed(this)\n                ? this.fromWorld(p)\n                : this.fromWorld(toWorld(p));\n        },\n\n        // Transform a point relative to this to a point relative to other\n        toOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2) {\n            return other.fromWorld(this.toWorld(p));\n        },\n\n        // Transform a point relative to other to a point relative to this\n        fromOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2) {\n            return other.toOther(this, p);\n        },\n\n        inspect() {\n            return `pos: (${Math.round(this.pos.x)}x, ${\n                Math.round(this.pos.y)\n            }y)`;\n        },\n\n        drawInspect() {\n            drawCircle({\n                color: rgb(255, 0, 0),\n                radius: 4 / getViewportScale(),\n            });\n        },\n    };\n}\n", "import type { Comp } from \"../../types\";\n\n/**\n * The {@link rotate `rotate()`} component.\n *\n * @group Component Types\n */\nexport interface RotateComp extends Comp {\n    /**\n     * Angle in degrees.\n     */\n    angle: number;\n    /**\n     * Rotate in degrees.\n     */\n    rotateBy(angle: number): void;\n    /**\n     * Rotate to a degree (like directly assign to .angle)\n     *\n     * @since v3000.0\n     */\n    rotateTo(s: number): void;\n}\n\nexport function rotate(a?: number): RotateComp {\n    return {\n        id: \"rotate\",\n        angle: a ?? 0,\n        rotateBy(angle: number) {\n            this.angle += angle;\n        },\n        rotateTo(angle: number) {\n            this.angle = angle;\n        },\n        inspect() {\n            return `angle: ${Math.round(this.angle)}`;\n        },\n    };\n}\n", "import { Vec2, vec2, type Vec2Args } from \"../../math/math\";\nimport type { Comp } from \"../../types\";\n\n/**\n * The {@link scale `scale()`} component.\n *\n * @group Component Types\n */\nexport interface ScaleComp extends Comp {\n    /**\n     * The current scale of the object\n     *\n     * @returns The current scale of the object as a {@link Vec2 `Vec2`}\n     */\n    scale: Vec2;\n    /**\n     * Set the scale of the object to a number\n     */\n    scaleTo(s: number): void;\n    /**\n     * Set the scale of the object to a Vec2\n     */\n    scaleTo(s: Vec2): void;\n    /**\n     * Set the scale of the object to a number for x and y\n     */\n    scaleTo(sx: number, sy: number): void;\n    /**\n     * Scale the object by a number\n     */\n    scaleBy(s: number): void;\n    /**\n     * Scale the object by a Vec2\n     */\n    scaleBy(s: Vec2): void;\n    /**\n     * Scale the object by a number for x and y\n     */\n    scaleBy(sx: number, sy: number): void;\n}\n\nexport function scale(...args: Vec2Args): ScaleComp {\n    if (args.length === 0) {\n        return scale(1);\n    }\n\n    let _scale = vec2(...args);\n\n    return {\n        id: \"scale\",\n        set scale(value: Vec2) {\n            if (value instanceof Vec2 === false) {\n                throw Error(\n                    \"The scale property on scale is a vector. Use scaleTo or scaleBy to set the scale with a number.\",\n                );\n            }\n\n            _scale = vec2(value);\n        },\n        get scale() {\n            return _scale;\n        },\n        scaleTo(...args: Vec2Args) {\n            _scale = vec2(...args);\n        },\n        scaleBy(...args: Vec2Args) {\n            _scale = _scale.scale(vec2(...args));\n        },\n        inspect() {\n            if (_scale.x == _scale.y) {\n                return `scale: ${_scale.x.toFixed(1)}x`;\n            }\n            else {return `scale: (${_scale.x.toFixed(1)}x, ${\n                    _scale.y.toFixed(1)\n                }y)`;}\n        },\n    };\n}\n", "import type { Comp } from \"../../types\";\n\n/**\n * The {@link z `z()`} component.\n *\n * @group Component Types\n */\nexport interface ZComp extends Comp {\n    /**\n     * Defines the z-index of this game obj\n     */\n    z: number;\n}\n\nexport function z(z: number): ZComp {\n    return {\n        id: \"z\",\n        z: z,\n        inspect() {\n            return `z: ${this.z}`;\n        },\n    };\n}\n", "import packageJsonData from \"../package.json\";\n\nconst VERSION = packageJsonData.version;\n\nimport { type ButtonsDef, initApp } from \"./app\";\n\nimport {\n    center,\n    drawBezier,\n    drawCircle,\n    drawCurve,\n    drawDebug,\n    drawEllipse,\n    drawFormattedText,\n    drawFrame,\n    drawLine,\n    drawLines,\n    drawLoadScreen,\n    drawMasked,\n    drawPolygon,\n    drawRect,\n    drawSprite,\n    drawSubtracted,\n    drawText,\n    drawTexture,\n    drawTriangle,\n    drawUnscaled,\n    drawUVQuad,\n    flush,\n    formatText,\n    FrameBuffer,\n    getBackground,\n    height,\n    initAppGfx,\n    initGfx,\n    popTransform,\n    pushMatrix,\n    pushRotate,\n    pushScale,\n    pushTransform,\n    pushTranslate,\n    setBackground,\n    updateViewport,\n    width,\n} from \"./gfx\";\n\nimport {\n    Asset,\n    getAsset,\n    getBitmapFont,\n    getFailedAssets,\n    getFont,\n    getShader,\n    getSound,\n    getSprite,\n    initAssets,\n    load,\n    loadAseprite,\n    loadBean,\n    loadBitmapFont,\n    loadFont,\n    loadJSON,\n    loadMusic,\n    loadPedit,\n    loadProgress,\n    loadRoot,\n    loadShader,\n    loadShaderURL,\n    loadSound,\n    loadSprite,\n    loadSpriteAtlas,\n    SoundData,\n    SpriteData,\n    type Uniform,\n} from \"./assets\";\n\nimport {\n    ASCII_CHARS,\n    BG_GRID_SIZE,\n    DBG_FONT,\n    DEF_HASH_GRID_SIZE,\n    EVENT_CANCEL_SYMBOL,\n    LOG_MAX,\n    MAX_TEXT_CACHE_SIZE,\n} from \"./constants\";\n\nimport {\n    bezier,\n    cardinal,\n    catmullRom,\n    chance,\n    choose,\n    chooseMultiple,\n    Circle,\n    Color,\n    curveLengthApproximation,\n    deg2rad,\n    easingCubicBezier,\n    easingLinear,\n    easingSteps,\n    Ellipse,\n    evaluateBezier,\n    evaluateBezierFirstDerivative,\n    evaluateBezierSecondDerivative,\n    evaluateCatmullRom,\n    evaluateCatmullRomFirstDerivative,\n    evaluateQuadratic,\n    evaluateQuadraticFirstDerivative,\n    evaluateQuadraticSecondDerivative,\n    hermite,\n    hsl2rgb,\n    isConvex,\n    kochanekBartels,\n    lerp,\n    Line,\n    map,\n    mapc,\n    Mat4,\n    NavMesh,\n    normalizedCurve,\n    Point,\n    Polygon,\n    Quad,\n    quad,\n    rad2deg,\n    rand,\n    randi,\n    randSeed,\n    Rect,\n    rgb,\n    RNG,\n    sat,\n    shuffle,\n    testCirclePolygon,\n    testLineCircle,\n    testLineLine,\n    testLinePoint,\n    testRectLine,\n    testRectPoint,\n    testRectRect,\n    triangulate,\n    Vec2,\n    vec2,\n    wave,\n} from \"./math\";\n\nimport easings from \"./math/easings\";\n\nimport {\n    download,\n    downloadBlob,\n    downloadJSON,\n    downloadText,\n    KEvent,\n    KEventController,\n    KEventHandler,\n} from \"./utils\";\n\nimport type {\n    Debug,\n    GameObj,\n    KAPLAYCtx,\n    KAPLAYInternal,\n    KAPLAYOpt,\n    KAPLAYPlugin,\n    MergePlugins,\n    PluginList,\n    Recording,\n} from \"./types\";\n\nimport {\n    agent,\n    anchor,\n    animate,\n    area,\n    type AreaComp,\n    areaEffector,\n    body,\n    buoyancyEffector,\n    circle,\n    color,\n    constantForce,\n    doubleJump,\n    drawon,\n    fadeIn,\n    fixed,\n    follow,\n    health,\n    layer,\n    lifespan,\n    mask,\n    move,\n    named,\n    offscreen,\n    opacity,\n    outline,\n    particles,\n    pathfinder,\n    patrol,\n    platformEffector,\n    pointEffector,\n    polygon,\n    pos,\n    raycast,\n    rect,\n    rotate,\n    scale,\n    sentry,\n    serializeAnimation,\n    shader,\n    sprite,\n    state,\n    stay,\n    surfaceEffector,\n    text,\n    textInput,\n    tile,\n    timer,\n    usesArea,\n    uvquad,\n    z,\n} from \"./components\";\n\nimport { dt, fixedDt, restDt } from \"./app\";\nimport { burp, getVolume, initAudio, play, setVolume, volume } from \"./audio\";\n\nimport {\n    addKaboom,\n    addLevel,\n    camFlash,\n    camPos,\n    camRot,\n    camScale,\n    camTransform,\n    destroy,\n    flash,\n    getCamPos,\n    getCamRot,\n    getCamScale,\n    getCamTransform,\n    getDefaultLayer,\n    getGravity,\n    getGravityDirection,\n    getLayers,\n    getSceneName,\n    getTreeRoot,\n    go,\n    initEvents,\n    initGame,\n    layers,\n    make,\n    on,\n    onAdd,\n    onClick,\n    onCollide,\n    onCollideEnd,\n    onCollideUpdate,\n    onDestroy,\n    onDraw,\n    onError,\n    onFixedUpdate,\n    onHover,\n    onHoverEnd,\n    onHoverUpdate,\n    onLoad,\n    onLoadError,\n    onLoading,\n    onResize,\n    onSceneLeave,\n    onTag,\n    onUntag,\n    onUnuse,\n    onUpdate,\n    onUse,\n    scene,\n    setCamPos,\n    setCamRot,\n    setCamScale,\n    setGravity,\n    setGravityDirection,\n    setLayers,\n    shake,\n    toScreen,\n    toWorld,\n    trigger,\n} from \"./game\";\n\nimport boomSpriteSrc from \"./kassets/boom.png\";\nimport kaSpriteSrc from \"./kassets/ka.png\";\nimport { clamp } from \"./math/clamp.js\";\n\n// Internal data, shared between all modules\nexport const _k = {\n    k: null,\n    globalOpt: null,\n    gfx: null,\n    game: null,\n    app: null,\n    assets: null,\n    fontCacheCanvas: null,\n    fontCacheC2d: null,\n    debug: null,\n    audio: null,\n    pixelDensity: null,\n    canvas: null,\n    gscale: null,\n    kaSprite: null,\n    boomSprite: null,\n} as unknown as KAPLAYInternal;\n\n/**\n * Initialize KAPLAY context. The starting point of all KAPLAY games.\n *\n * @example\n * ```js\n * // Start KAPLAY with default options (will create a fullscreen canvas under <body>)\n * kaplay()\n *\n * // Init with some options\n * kaplay({\n *     width: 320,\n *     height: 240,\n *     font: \"sans-serif\",\n *     canvas: document.querySelector(\"#mycanvas\"),\n *     background: [ 0, 0, 255, ],\n * })\n *\n * // All KAPLAY functions are imported to global after calling kaplay()\n * add()\n * onUpdate()\n * onKeyPress()\n * vec2()\n *\n * // If you want to prevent KAPLAY from importing all functions to global and use a context handle for all KAPLAY functions\n * const k = kaplay({ global: false })\n *\n * k.add(...)\n * k.onUpdate(...)\n * k.onKeyPress(...)\n * k.vec2(...)\n * ```\n *\n * @group Start\n */\nconst kaplay = <\n    TPlugins extends PluginList<unknown> = [undefined],\n    TButtons extends ButtonsDef = {},\n    TButtonsName extends string = keyof TButtons & string,\n>(\n    gopt: KAPLAYOpt<TPlugins, TButtons> = {\n        tagsAsComponents: true,\n    },\n): TPlugins extends [undefined] ? KAPLAYCtx<TButtons, TButtonsName>\n    : KAPLAYCtx<TButtons, TButtonsName> & MergePlugins<TPlugins> =>\n{\n    if (_k.k) {\n        console.warn(\n            \"KAPLAY already initialized, you are calling kaplay() multiple times, it may lead bugs!\",\n        );\n        _k.k.quit();\n    }\n\n    _k.globalOpt = gopt;\n    const root = gopt.root ?? document.body;\n\n    // if root is not defined (which falls back to <body>) we assume user is using kaboom on a clean page, and modify <body> to better fit a full screen canvas\n    if (root === document.body) {\n        document.body.style[\"width\"] = \"100%\";\n        document.body.style[\"height\"] = \"100%\";\n        document.body.style[\"margin\"] = \"0px\";\n        document.documentElement.style[\"width\"] = \"100%\";\n        document.documentElement.style[\"height\"] = \"100%\";\n    }\n\n    // create a <canvas> if user didn't provide one\n    const canvas = gopt.canvas\n        ?? root.appendChild(document.createElement(\"canvas\"));\n    _k.canvas = canvas;\n\n    // global pixel scale\n    const gscale = gopt.scale ?? 1;\n    _k.gscale = gscale;\n    const fixedSize = gopt.width && gopt.height && !gopt.stretch\n        && !gopt.letterbox;\n\n    // adjust canvas size according to user size / viewport settings\n    if (fixedSize) {\n        canvas.width = gopt.width! * gscale;\n        canvas.height = gopt.height! * gscale;\n    }\n    else {\n        canvas.width = canvas.parentElement!.offsetWidth;\n        canvas.height = canvas.parentElement!.offsetHeight;\n    }\n\n    // canvas css styles\n    const styles = [\n        \"outline: none\",\n        \"cursor: default\",\n    ];\n\n    if (fixedSize) {\n        const cw = canvas.width;\n        const ch = canvas.height;\n        styles.push(`width: ${cw}px`);\n        styles.push(`height: ${ch}px`);\n    }\n    else {\n        styles.push(\"width: 100%\");\n        styles.push(\"height: 100%\");\n    }\n\n    if (gopt.crisp) {\n        // chrome only supports pixelated and firefox only supports crisp-edges\n        styles.push(\"image-rendering: pixelated\");\n        styles.push(\"image-rendering: crisp-edges\");\n    }\n\n    canvas.style.cssText = styles.join(\";\");\n\n    const pixelDensity = gopt.pixelDensity || 1;\n    _k.pixelDensity = pixelDensity;\n\n    canvas.width *= pixelDensity;\n    canvas.height *= pixelDensity;\n    // make canvas focusable\n    canvas.tabIndex = 0;\n\n    const fontCacheCanvas = document.createElement(\"canvas\");\n    fontCacheCanvas.width = MAX_TEXT_CACHE_SIZE;\n    fontCacheCanvas.height = MAX_TEXT_CACHE_SIZE;\n    _k.fontCacheCanvas = fontCacheCanvas;\n    const fontCacheC2d = fontCacheCanvas.getContext(\"2d\", {\n        willReadFrequently: true,\n    });\n    _k.fontCacheC2d = fontCacheC2d;\n\n    const app = initApp({\n        canvas: canvas,\n        touchToMouse: gopt.touchToMouse,\n        gamepads: gopt.gamepads,\n        pixelDensity: gopt.pixelDensity,\n        maxFPS: gopt.maxFPS,\n        buttons: gopt.buttons,\n    });\n    _k.app = app;\n\n    const gc: Array<() => void> = [];\n\n    const canvasContext = app.canvas\n        .getContext(\"webgl\", {\n            antialias: true,\n            depth: true,\n            stencil: true,\n            alpha: true,\n            preserveDrawingBuffer: true,\n        });\n\n    if (!canvasContext) throw new Error(\"WebGL not supported\");\n\n    const gl = canvasContext;\n\n    const ggl = initGfx(gl, {\n        texFilter: gopt.texFilter,\n    });\n\n    const gfx = initAppGfx(gopt, ggl);\n    _k.gfx = gfx;\n    const audio = initAudio();\n    _k.audio = audio;\n    const assets = initAssets(ggl, gopt.spriteAtlasPadding ?? 0);\n    _k.assets = assets;\n    const game = initGame();\n    _k.game = game;\n\n    game.root.use(timer());\n\n    function makeCanvas(w: number, h: number) {\n        const fb = new FrameBuffer(ggl, w, h);\n        return {\n            clear: () => fb.clear(),\n            free: () => fb.free(),\n            toDataURL: () => fb.toDataURL(),\n            toImageData: () => fb.toImageData(),\n            width: fb.width,\n            height: fb.height,\n            draw: (action: () => void) => {\n                flush();\n                fb.bind();\n                action();\n                flush();\n                fb.unbind();\n            },\n            get fb() {\n                return fb;\n            },\n        };\n    }\n\n    // start a rendering frame, reset some states\n    function frameStart() {\n        // clear backbuffer\n        gl.clear(gl.COLOR_BUFFER_BIT);\n        gfx.frameBuffer.bind();\n        // clear framebuffer\n        gl.clear(gl.COLOR_BUFFER_BIT);\n\n        if (!gfx.bgColor) {\n            drawUnscaled(() => {\n                drawUVQuad({\n                    width: width(),\n                    height: height(),\n                    quad: new Quad(\n                        0,\n                        0,\n                        width() / BG_GRID_SIZE,\n                        height() / BG_GRID_SIZE,\n                    ),\n                    tex: gfx.bgTex,\n                    fixed: true,\n                });\n            });\n        }\n\n        gfx.renderer.numDraws = 0;\n        gfx.fixed = false;\n        gfx.transformStack.length = 0;\n        gfx.transform = new Mat4();\n    }\n\n    function usePostEffect(name: string, uniform?: Uniform | (() => Uniform)) {\n        gfx.postShader = name;\n        gfx.postShaderUniform = uniform ?? null;\n    }\n\n    function frameEnd() {\n        // TODO: don't render debug UI with framebuffer\n        // TODO: polish framebuffer rendering / sizing issues\n        flush();\n        gfx.lastDrawCalls = gfx.renderer.numDraws;\n        gfx.frameBuffer.unbind();\n        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n        const ow = gfx.width;\n        const oh = gfx.height;\n        gfx.width = gl.drawingBufferWidth / pixelDensity;\n        gfx.height = gl.drawingBufferHeight / pixelDensity;\n\n        drawTexture({\n            flipY: true,\n            tex: gfx.frameBuffer.tex,\n            pos: new Vec2(gfx.viewport.x, gfx.viewport.y),\n            width: gfx.viewport.width,\n            height: gfx.viewport.height,\n            shader: gfx.postShader,\n            uniform: typeof gfx.postShaderUniform === \"function\"\n                ? gfx.postShaderUniform()\n                : gfx.postShaderUniform,\n            fixed: true,\n        });\n\n        flush();\n        gfx.width = ow;\n        gfx.height = oh;\n    }\n\n    // TODO: cache formatted text\n    // format text and return a list of chars with their calculated position\n\n    // get game root\n\n    let debugPaused = false;\n\n    const debug: Debug = {\n        inspect: false,\n        set timeScale(timeScale: number) {\n            _k.app.state.timeScale = timeScale;\n        },\n        get timeScale() {\n            return _k.app.state.timeScale;\n        },\n        showLog: true,\n        fps: () => app.fps(),\n        numFrames: () => app.numFrames(),\n        stepFrame: updateFrame,\n        drawCalls: () => gfx.lastDrawCalls,\n        clearLog: () => game.logs = [],\n        log: (...msgs) => {\n            const max = gopt.logMax ?? LOG_MAX;\n            const msg = msgs.length > 1 ? msgs.concat(\" \").join(\" \") : msgs[0];\n\n            game.logs.unshift({\n                msg: msg,\n                time: app.time(),\n            });\n            if (game.logs.length > max) {\n                game.logs = game.logs.slice(0, max);\n            }\n        },\n        error: (msg) =>\n            debug.log(new Error(msg.toString ? msg.toString() : msg as string)),\n        curRecording: null,\n        numObjects: () => get(\"*\", { recursive: true }).length,\n        get paused() {\n            return debugPaused;\n        },\n        set paused(v) {\n            debugPaused = v;\n            if (v) {\n                audio.ctx.suspend();\n            }\n            else {\n                audio.ctx.resume();\n            }\n        },\n    };\n\n    _k.debug = debug;\n\n    function getData<T>(key: string, def?: T): T | null {\n        try {\n            return JSON.parse(window.localStorage[key]);\n        } catch {\n            if (def) {\n                setData(key, def);\n                return def;\n            }\n            else {\n                return null;\n            }\n        }\n    }\n\n    function setData(key: string, data: any) {\n        window.localStorage[key] = JSON.stringify(data);\n    }\n\n    function plug<T extends Record<string, any>>(\n        plugin: KAPLAYPlugin<T>,\n        ...args: any\n    ): KAPLAYCtx & T {\n        const funcs = plugin(ctx);\n        let funcsObj: T;\n        if (typeof funcs === \"function\") {\n            const plugWithOptions = funcs(...args);\n            funcsObj = plugWithOptions(ctx);\n        }\n        else {\n            funcsObj = funcs;\n        }\n\n        for (const key in funcsObj) {\n            ctx[key as keyof typeof ctx] = funcsObj[key];\n\n            if (gopt.global !== false) {\n                window[key as any] = funcsObj[key];\n            }\n        }\n        return ctx as unknown as KAPLAYCtx & T;\n    }\n\n    function record(frameRate?: number): Recording {\n        const stream = app.canvas.captureStream(frameRate);\n        const audioDest = audio.ctx.createMediaStreamDestination();\n\n        audio.masterNode.connect(audioDest);\n\n        // TODO: Enabling audio results in empty video if no audio received\n        // const audioStream = audioDest.stream\n        // const [firstAudioTrack] = audioStream.getAudioTracks()\n\n        // stream.addTrack(firstAudioTrack);\n\n        const recorder = new MediaRecorder(stream);\n        const chunks: any[] = [];\n\n        recorder.ondataavailable = (e) => {\n            if (e.data.size > 0) {\n                chunks.push(e.data);\n            }\n        };\n\n        recorder.onerror = () => {\n            audio.masterNode.disconnect(audioDest);\n            stream.getTracks().forEach(t => t.stop());\n        };\n\n        recorder.start();\n\n        return {\n            resume() {\n                recorder.resume();\n            },\n\n            pause() {\n                recorder.pause();\n            },\n\n            stop(): Promise<Blob> {\n                recorder.stop();\n                // cleanup\n                audio.masterNode.disconnect(audioDest);\n                stream.getTracks().forEach(t => t.stop());\n                return new Promise((resolve) => {\n                    recorder.onstop = () => {\n                        resolve(\n                            new Blob(chunks, {\n                                type: \"video/mp4\",\n                            }),\n                        );\n                    };\n                });\n            },\n\n            download(filename = \"kaboom.mp4\") {\n                this.stop().then((blob) => downloadBlob(filename, blob));\n            },\n        };\n    }\n\n    function isFocused(): boolean {\n        return document.activeElement === app.canvas;\n    }\n\n    // aliases for root game obj operations\n    const add = game.root.add.bind(game.root);\n    const readd = game.root.readd.bind(game.root);\n    const destroyAll = game.root.removeAll.bind(game.root);\n    const get = game.root.get.bind(game.root);\n    const wait = game.root.wait.bind(game.root);\n    const loop = game.root.loop.bind(game.root);\n    const query = game.root.query.bind(game.root);\n    const tween = game.root.tween.bind(game.root);\n\n    const kaSprite = loadSprite(null, kaSpriteSrc);\n    const boomSprite = loadSprite(null, boomSpriteSrc);\n\n    _k.kaSprite = kaSprite;\n    _k.boomSprite = boomSprite;\n\n    function fixedUpdateFrame() {\n        // update every obj\n        game.root.fixedUpdate();\n    }\n\n    function updateFrame() {\n        // update every obj\n        game.root.update();\n    }\n\n    class Collision {\n        source: GameObj;\n        target: GameObj;\n        normal: Vec2;\n        distance: number;\n        resolved: boolean = false;\n        constructor(\n            source: GameObj,\n            target: GameObj,\n            normal: Vec2,\n            distance: number,\n            resolved = false,\n        ) {\n            this.source = source;\n            this.target = target;\n            this.normal = normal;\n            this.distance = distance;\n            this.resolved = resolved;\n        }\n        get displacement() {\n            return this.normal.scale(this.distance);\n        }\n        reverse() {\n            return new Collision(\n                this.target,\n                this.source,\n                this.normal.scale(-1),\n                this.distance,\n                this.resolved,\n            );\n        }\n        hasOverlap() {\n            return !this.displacement.isZero();\n        }\n        isLeft() {\n            return this.displacement.cross(game.gravity || vec2(0, 1)) > 0;\n        }\n        isRight() {\n            return this.displacement.cross(game.gravity || vec2(0, 1)) < 0;\n        }\n        isTop() {\n            return this.displacement.dot(game.gravity || vec2(0, 1)) > 0;\n        }\n        isBottom() {\n            return this.displacement.dot(game.gravity || vec2(0, 1)) < 0;\n        }\n        preventResolution() {\n            this.resolved = true;\n        }\n    }\n\n    function checkFrame() {\n        if (!usesArea()) {\n            return;\n        }\n\n        // TODO: persistent grid?\n        // start a spatial hash grid for more efficient collision detection\n        const grid: Record<number, Record<number, GameObj<AreaComp>[]>> = {};\n        const cellSize = gopt.hashGridSize || DEF_HASH_GRID_SIZE;\n\n        // current transform\n        let tr = new Mat4();\n\n        // a local transform stack\n        const stack: any[] = [];\n\n        function checkObj(obj: GameObj) {\n            stack.push(tr.clone());\n\n            // Update object transform here. This will be the transform later used in rendering.\n            if (obj.pos) tr.translate(obj.pos);\n            if (obj.scale) tr.scale(obj.scale);\n            if (obj.angle) tr.rotate(obj.angle);\n            obj.transform = tr.clone();\n\n            if (obj.c(\"area\") && !obj.paused) {\n                // TODO: only update worldArea if transform changed\n                const aobj = obj as GameObj<AreaComp>;\n                const area = aobj.worldArea();\n                const bbox = area.bbox();\n\n                // Get spatial hash grid coverage\n                const xmin = Math.floor(bbox.pos.x / cellSize);\n                const ymin = Math.floor(bbox.pos.y / cellSize);\n                const xmax = Math.ceil((bbox.pos.x + bbox.width) / cellSize);\n                const ymax = Math.ceil((bbox.pos.y + bbox.height) / cellSize);\n\n                // Cache objs that are already checked\n                const checked = new Set();\n\n                // insert & check against all covered grids\n                for (let x = xmin; x <= xmax; x++) {\n                    for (let y = ymin; y <= ymax; y++) {\n                        if (!grid[x]) {\n                            grid[x] = {};\n                            grid[x][y] = [aobj];\n                        }\n                        else if (!grid[x][y]) {\n                            grid[x][y] = [aobj];\n                        }\n                        else {\n                            const cell = grid[x][y];\n                            check: for (const other of cell) {\n                                if (other.paused) continue;\n                                if (!other.exists()) continue;\n                                if (checked.has(other.id)) continue;\n                                for (const tag of aobj.collisionIgnore) {\n                                    if (other.is(tag)) {\n                                        continue check;\n                                    }\n                                }\n                                for (const tag of other.collisionIgnore) {\n                                    if (aobj.is(tag)) {\n                                        continue check;\n                                    }\n                                }\n                                // TODO: cache the world area here\n                                const res = sat(\n                                    aobj.worldArea(),\n                                    other.worldArea(),\n                                );\n                                if (res) {\n                                    // TODO: rehash if the object position is changed after resolution?\n                                    const col1 = new Collision(\n                                        aobj,\n                                        other,\n                                        res.normal,\n                                        res.distance,\n                                    );\n                                    aobj.trigger(\"collideUpdate\", other, col1);\n                                    const col2 = col1.reverse();\n                                    // resolution only has to happen once\n                                    col2.resolved = col1.resolved;\n                                    other.trigger(\"collideUpdate\", aobj, col2);\n                                }\n                                checked.add(other.id);\n                            }\n                            cell.push(aobj);\n                        }\n                    }\n                }\n            }\n\n            obj.children.forEach(checkObj);\n            tr = stack.pop();\n        }\n\n        checkObj(game.root);\n    }\n\n    function handleErr(err: Error) {\n        console.error(err);\n        audio.ctx.suspend();\n        const errorMessage = err.message ?? String(err)\n            ?? \"Unknown error, check console for more info\";\n\n        // TODO: this should only run once\n        app.run(\n            () => {},\n            () => {\n                frameStart();\n\n                drawUnscaled(() => {\n                    const pad = 32;\n                    const gap = 16;\n                    const gw = width();\n                    const gh = height();\n\n                    const textStyle = {\n                        size: 36,\n                        width: gw - pad * 2,\n                        letterSpacing: 4,\n                        lineSpacing: 4,\n                        font: DBG_FONT,\n                        fixed: true,\n                    };\n\n                    drawRect({\n                        width: gw,\n                        height: gh,\n                        color: rgb(0, 0, 255),\n                        fixed: true,\n                    });\n\n                    const title = formatText({\n                        ...textStyle,\n                        text: \"Error\",\n                        pos: vec2(pad),\n                        color: rgb(255, 128, 0),\n                        fixed: true,\n                    });\n\n                    drawFormattedText(title);\n\n                    drawText({\n                        ...textStyle,\n                        text: errorMessage,\n                        pos: vec2(pad, pad + title.height + gap),\n                        fixed: true,\n                    });\n\n                    popTransform();\n                    game.events.trigger(\"error\", err);\n                });\n\n                frameEnd();\n            },\n        );\n    }\n\n    function onCleanup(action: () => void) {\n        gc.push(action);\n    }\n\n    function quit() {\n        game.events.onOnce(\"frameEnd\", () => {\n            app.quit();\n\n            // clear canvas\n            gl.clear(\n                gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT\n                    | gl.STENCIL_BUFFER_BIT,\n            );\n\n            // unbind everything\n            const numTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);\n\n            for (let unit = 0; unit < numTextureUnits; unit++) {\n                gl.activeTexture(gl.TEXTURE0 + unit);\n                gl.bindTexture(gl.TEXTURE_2D, null);\n                gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);\n            }\n\n            gl.bindBuffer(gl.ARRAY_BUFFER, null);\n            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n            gl.bindRenderbuffer(gl.RENDERBUFFER, null);\n            gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n            // run all scattered gc events\n            ggl.destroy();\n            gc.forEach((f) => f());\n        });\n    }\n\n    let isFirstFrame = true;\n\n    // main game loop\n    app.run(\n        () => {\n            try {\n                if (assets.loaded) {\n                    if (!debug.paused) fixedUpdateFrame();\n                    checkFrame();\n                }\n            } catch (e) {\n                handleErr(e as Error);\n            }\n        },\n        (processInput, resetInput) => {\n            try {\n                processInput();\n\n                if (!assets.loaded) {\n                    if (loadProgress() === 1 && !isFirstFrame) {\n                        assets.loaded = true;\n                        getFailedAssets().forEach(details =>\n                            game.events.trigger(\"loadError\", ...details)\n                        );\n                        game.events.trigger(\"load\");\n                    }\n                }\n\n                if (\n                    !assets.loaded && gopt.loadingScreen !== false\n                    || isFirstFrame\n                ) {\n                    frameStart();\n                    // TODO: Currently if assets are not initially loaded no updates or timers will be run, however they will run if loadingScreen is set to false. What's the desired behavior or should we make them consistent?\n                    drawLoadScreen();\n                    frameEnd();\n                }\n                else {\n                    if (!debug.paused) updateFrame();\n                    checkFrame();\n                    frameStart();\n                    drawFrame();\n                    if (gopt.debug !== false) drawDebug();\n                    frameEnd();\n                }\n\n                if (isFirstFrame) {\n                    isFirstFrame = false;\n                }\n\n                game.events.trigger(\"frameEnd\");\n\n                resetInput();\n            } catch (e) {\n                handleErr(e as Error);\n            }\n        },\n    );\n\n    updateViewport();\n    initEvents();\n\n    // the exported ctx handle\n    const ctx: KAPLAYCtx = {\n        _k,\n        VERSION,\n        // asset load\n        loadRoot,\n        loadProgress,\n        loadSprite,\n        loadSpriteAtlas,\n        loadSound,\n        loadMusic,\n        loadBitmapFont,\n        loadFont,\n        loadShader,\n        loadShaderURL,\n        loadAseprite,\n        loadPedit,\n        loadBean,\n        loadJSON,\n        load,\n        getSound,\n        getFont,\n        getBitmapFont,\n        getSprite,\n        getShader,\n        getAsset,\n        Asset,\n        SpriteData,\n        SoundData,\n        // query\n        width,\n        height,\n        center,\n        dt,\n        fixedDt,\n        restDt,\n        time: app.time,\n        screenshot: app.screenshot,\n        record,\n        isFocused,\n        setCursor: app.setCursor,\n        getCursor: app.getCursor,\n        setCursorLocked: app.setCursorLocked,\n        isCursorLocked: app.isCursorLocked,\n        setFullscreen: app.setFullscreen,\n        isFullscreen: app.isFullscreen,\n        isTouchscreen: app.isTouchscreen,\n        onLoad,\n        onLoadError,\n        onLoading,\n        onResize,\n        onGamepadConnect: app.onGamepadConnect,\n        onGamepadDisconnect: app.onGamepadDisconnect,\n        onError,\n        onCleanup,\n        // misc\n        flash: flash,\n        setCamPos: setCamPos,\n        getCamPos: getCamPos,\n        setCamRot: setCamRot,\n        getCamRot: getCamRot,\n        setCamScale: setCamScale,\n        getCamScale: getCamScale,\n        getCamTransform: getCamTransform,\n        camPos,\n        camScale,\n        camFlash,\n        camRot,\n        camTransform,\n        shake,\n        toScreen,\n        toWorld,\n        setGravity,\n        getGravity,\n        setGravityDirection,\n        getGravityDirection,\n        setBackground,\n        getBackground,\n        getGamepads: app.getGamepads,\n        // obj\n        getTreeRoot,\n        add,\n        make,\n        destroy,\n        destroyAll,\n        get,\n        query,\n        readd,\n        // comps\n        pos,\n        scale,\n        rotate,\n        color,\n        opacity,\n        anchor,\n        area,\n        sprite,\n        text,\n        polygon,\n        rect,\n        circle,\n        uvquad,\n        outline,\n        particles,\n        body,\n        platformEffector: platformEffector,\n        surfaceEffector,\n        areaEffector,\n        pointEffector,\n        buoyancyEffector,\n        constantForce,\n        doubleJump,\n        shader,\n        textInput,\n        timer,\n        fixed,\n        stay,\n        health,\n        lifespan,\n        named,\n        state,\n        z,\n        layer,\n        move,\n        offscreen,\n        follow,\n        fadeIn,\n        mask,\n        drawon,\n        raycast,\n        tile,\n        animate,\n        serializeAnimation,\n        agent,\n        sentry,\n        patrol,\n        pathfinder,\n        // group events\n        trigger,\n        on: on as KAPLAYCtx[\"on\"], // our internal on should be strict, user shouldn't\n        onFixedUpdate,\n        onUpdate,\n        onDraw,\n        onAdd,\n        onDestroy,\n        onTag,\n        onUntag,\n        onUse,\n        onUnuse,\n        onClick,\n        onCollide,\n        onCollideUpdate,\n        onCollideEnd,\n        onHover,\n        onHoverUpdate,\n        onHoverEnd,\n        // input\n        onKeyDown: app.onKeyDown,\n        onKeyPress: app.onKeyPress,\n        onKeyPressRepeat: app.onKeyPressRepeat,\n        onKeyRelease: app.onKeyRelease,\n        onMouseDown: app.onMouseDown,\n        onMousePress: app.onMousePress,\n        onMouseRelease: app.onMouseRelease,\n        onMouseMove: app.onMouseMove,\n        onCharInput: app.onCharInput,\n        onTouchStart: app.onTouchStart,\n        onTouchMove: app.onTouchMove,\n        onTouchEnd: app.onTouchEnd,\n        onScroll: app.onScroll,\n        onHide: app.onHide,\n        onShow: app.onShow,\n        onGamepadButtonDown: app.onGamepadButtonDown,\n        onGamepadButtonPress: app.onGamepadButtonPress,\n        onGamepadButtonRelease: app.onGamepadButtonRelease,\n        onGamepadStick: app.onGamepadStick,\n        onButtonPress: app.onButtonPress,\n        onButtonDown: app.onButtonDown,\n        onButtonRelease: app.onButtonRelease,\n        mousePos: app.mousePos,\n        mouseDeltaPos: app.mouseDeltaPos,\n        isKeyDown: app.isKeyDown,\n        isKeyPressed: app.isKeyPressed,\n        isKeyPressedRepeat: app.isKeyPressedRepeat,\n        isKeyReleased: app.isKeyReleased,\n        isMouseDown: app.isMouseDown,\n        isMousePressed: app.isMousePressed,\n        isMouseReleased: app.isMouseReleased,\n        isMouseMoved: app.isMouseMoved,\n        isGamepadButtonPressed: app.isGamepadButtonPressed,\n        isGamepadButtonDown: app.isGamepadButtonDown,\n        isGamepadButtonReleased: app.isGamepadButtonReleased,\n        getGamepadStick: app.getGamepadStick,\n        isButtonPressed: app.isButtonPressed,\n        isButtonDown: app.isButtonDown,\n        isButtonReleased: app.isButtonReleased,\n        setButton: app.setButton,\n        getButton: app.getButton,\n        pressButton: app.pressButton,\n        releaseButton: app.releaseButton,\n        getLastInputDeviceType: app.getLastInputDeviceType,\n        charInputted: app.charInputted,\n        // timer\n        loop,\n        wait,\n        // audio\n        play,\n        setVolume: setVolume,\n        getVolume: getVolume,\n        volume,\n        burp,\n        audioCtx: audio.ctx,\n        // math\n        Line,\n        Rect,\n        Circle,\n        Ellipse,\n        Point,\n        Polygon,\n        Vec2,\n        Color,\n        Mat4,\n        Quad,\n        RNG,\n        rand,\n        randi,\n        randSeed,\n        vec2,\n        rgb,\n        hsl2rgb,\n        quad,\n        choose,\n        chooseMultiple,\n        shuffle,\n        chance,\n        lerp,\n        tween,\n        easings,\n        map,\n        mapc,\n        wave,\n        deg2rad,\n        rad2deg,\n        clamp,\n        evaluateQuadratic,\n        evaluateQuadraticFirstDerivative,\n        evaluateQuadraticSecondDerivative,\n        evaluateBezier,\n        evaluateBezierFirstDerivative,\n        evaluateBezierSecondDerivative,\n        evaluateCatmullRom,\n        evaluateCatmullRomFirstDerivative,\n        curveLengthApproximation,\n        normalizedCurve,\n        hermite,\n        cardinal,\n        catmullRom,\n        bezier,\n        kochanekBartels,\n        easingSteps,\n        easingLinear,\n        easingCubicBezier,\n        testLineLine,\n        testRectRect,\n        testRectLine,\n        testRectPoint,\n        testCirclePolygon,\n        testLinePoint,\n        testLineCircle,\n        isConvex,\n        triangulate,\n        NavMesh,\n        // raw draw\n        drawSprite,\n        drawText,\n        formatText,\n        drawRect,\n        drawLine,\n        drawLines,\n        drawTriangle,\n        drawCircle,\n        drawEllipse,\n        drawUVQuad,\n        drawPolygon,\n        drawCurve,\n        drawBezier,\n        drawFormattedText,\n        drawMasked,\n        drawSubtracted,\n        pushTransform,\n        popTransform,\n        pushTranslate,\n        pushScale,\n        pushRotate,\n        pushMatrix,\n        usePostEffect,\n        makeCanvas,\n        // debug\n        debug,\n        // scene\n        scene,\n        getSceneName,\n        go,\n        onSceneLeave,\n        // layers\n        layers: layers,\n        getLayers: getLayers,\n        setLayers: setLayers,\n        getDefaultLayer: getDefaultLayer,\n        // level\n        addLevel,\n        // storage\n        getData,\n        setData,\n        download,\n        downloadJSON,\n        downloadText,\n        downloadBlob,\n        // plugin\n        plug,\n        // char sets\n        ASCII_CHARS,\n        // dom\n        canvas: app.canvas,\n        // misc\n        addKaboom,\n        // dirs\n        LEFT: Vec2.LEFT,\n        RIGHT: Vec2.RIGHT,\n        UP: Vec2.UP,\n        DOWN: Vec2.DOWN,\n        // colors\n        RED: Color.RED,\n        GREEN: Color.GREEN,\n        BLUE: Color.BLUE,\n        YELLOW: Color.YELLOW,\n        MAGENTA: Color.MAGENTA,\n        CYAN: Color.CYAN,\n        WHITE: Color.WHITE,\n        BLACK: Color.BLACK,\n        quit,\n        // helpers\n        KEvent,\n        KEventHandler,\n        KEventController,\n        cancel: () => EVENT_CANCEL_SYMBOL,\n    };\n\n    _k.k = ctx;\n\n    const plugins = gopt.plugins as KAPLAYPlugin<Record<string, unknown>>[];\n\n    if (plugins) {\n        plugins.forEach(plug);\n    }\n\n    // export everything to window if global is set\n    if (gopt.global !== false) {\n        for (const key in ctx) {\n            (<any> window[<any> key]) = ctx[key as keyof KAPLAYCtx];\n        }\n    }\n\n    if (gopt.focus !== false) {\n        app.canvas.focus();\n    }\n\n    return ctx as unknown as TPlugins extends [undefined]\n        ? KAPLAYCtx<TButtons, TButtonsName>\n        : KAPLAYCtx<TButtons, TButtonsName> & MergePlugins<TPlugins>;\n};\n\nexport { kaplay };\nexport default kaplay;\n"],
  "mappings": "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",
  "names": ["package_default", "clamp", "val", "min", "max", "Color", "_Color", "r", "g", "b", "clamp", "arr", "hex", "result", "h", "s", "l", "hue2rgb", "q", "t", "p", "a", "other", "dest", "lerp", "max", "min", "d", "rgb", "args", "hsl2rgb", "deg2rad", "deg", "rad2deg", "rad", "lerp", "a", "b", "t", "Vec2", "Color", "map", "v", "l1", "h1", "l2", "h2", "mapc", "clamp", "Vec2", "_Vec2", "x", "y", "deg", "angle", "deg2rad", "arr", "args", "p2", "vec2", "s", "v", "other", "len", "normal", "on", "rad2deg", "dest", "t", "lerp", "cos", "sin", "n", "m", "Rect", "Quad", "_Quad", "w", "h", "quad", "Mat2", "_Mat2", "a", "b", "c", "d", "point", "det", "e1", "e2", "radians", "Mat3", "_Mat3", "m11", "m12", "m13", "m21", "m22", "m23", "m31", "m32", "m33", "m", "Mat2", "other", "radians", "c", "s", "oldA", "oldB", "x", "y", "det", "Mat4", "_Mat4", "p", "a", "deg2rad", "m0", "m1", "m4", "m5", "out", "i", "j", "Vec2", "r", "rad2deg", "f00", "f01", "f02", "f03", "f04", "f05", "f06", "f07", "f08", "f09", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "wave", "lo", "hi", "t", "f", "A", "C", "M", "RNG", "seed", "b", "Color", "args", "vec2", "rgb", "defRNG", "randSeed", "rand", "randi", "chance", "shuffle", "list", "chooseMultiple", "count", "choose", "testRectRect", "r1", "r2", "testLineLineT", "l1", "l2", "denom", "ua", "ub", "testLineLine", "t", "vec2", "testRectLine", "r", "l", "dir", "tmin", "tmax", "tx1", "tx2", "ty1", "ty2", "testRectPoint", "r", "pt", "testRectCircle", "c", "nx", "ny", "vec2", "testRectPolygon", "p", "testPolygonPolygon", "Polygon", "testLinePoint", "l", "v1", "v2", "t", "testLineCircle", "circle", "v", "a", "centerToOrigin", "b", "dis", "t1", "t2", "testCirclePoint", "testLinePolygon", "testPolygonPoint", "i", "p1", "p2", "testLineLine", "Line", "testCircleCircle", "c1", "c2", "testCirclePolygon", "prev", "cur", "poly", "j", "testEllipsePoint", "ellipse", "angle", "deg2rad", "s", "vx", "vy", "testEllipseCircle", "center", "cx", "cy", "Ellipse", "testEllipseLine", "line", "T", "Circle", "testEllipseEllipse", "ellipse1", "ellipse2", "A1", "Mat3", "A2", "x1", "y1", "x2", "y2", "theta1", "theta2", "M1", "M2", "M1inv", "M2inv", "A", "B", "a11", "a12", "a13", "a21", "a22", "a23", "a31", "a32", "a33", "b11", "b12", "b13", "b21", "b22", "b23", "b31", "b32", "b33", "factor", "condition1", "condition2", "condition3", "testEllipseRect", "rect", "testEllipsePolygon", "testPointPoint", "testPointShape", "point", "shape", "Vec2", "Rect", "testLineShape", "testRectLine", "testCircleShape", "testRectShape", "testRectRect", "testPolygonShape", "polygon", "testEllipseShape", "raycastLine", "origin", "direction", "line", "a", "c", "d", "ab", "cd", "abxcd", "ac", "s", "t", "normal", "raycastRect", "rect", "tmin", "tmax", "tx1", "tx2", "vec2", "ty1", "ty2", "raycastCircle", "circle", "A", "centerToOrigin", "B", "C", "disc", "point", "t1", "t2", "raycastPolygon", "polygon", "points", "minHit", "prev", "cur", "hit", "Line", "raycastEllipse", "ellipse", "T", "TI", "Torigin", "Tdirection", "result", "Circle", "R", "Mat2", "deg2rad", "fraction", "raycastGrid", "gridPosHit", "maxDistance", "pos", "len", "dir", "gridPos", "step", "tDelta", "dist", "tMax", "steppedIndex", "Point", "_Point", "pt", "m", "Rect", "shape", "testPointShape", "_Line", "p1", "p2", "testLineShape", "rand", "_Rect", "width", "height", "Vec2", "Polygon", "p", "min", "max", "dx", "dy", "testRectShape", "_Circle", "center", "radius", "tr", "Ellipse", "testCircleShape", "_Ellipse", "rx", "ry", "degrees", "inv", "M", "e1", "e2", "v1", "v2", "b", "rad2deg", "angle", "scale", "Mat3", "ux", "uy", "vx", "vy", "halfwidth", "halfheight", "testEllipseShape", "segmentLineIntersection", "_Polygon", "pts", "total", "l", "i", "testPolygonShape", "surfaceLine", "left", "right", "ap", "wasLeft", "isLeft", "intersection", "evaluateQuadratic", "pt1", "pt2", "pt3", "mt", "mt2", "evaluateQuadraticFirstDerivative", "evaluateQuadraticSecondDerivative", "evaluateBezier", "pt4", "t3", "mt3", "evaluateBezierFirstDerivative", "evaluateBezierSecondDerivative", "evaluateCatmullRom", "D", "evaluateCatmullRomFirstDerivative", "normalizedCurve", "curve", "curveLength", "curveLengthApproximation", "length", "entries", "detail", "llut", "tlut", "ddt", "pp", "e", "inverse", "index", "l1", "l2", "hermite", "m1", "m2", "cardinal", "tension", "h", "hx", "hy", "catmullRom", "bezier", "kochanekBartels", "continuity", "bias", "hermiteFirstDerivative", "inZeroOneDomain", "approximately", "cubeRoot", "v", "getCubicRoots", "pa", "pb", "pc", "pd", "q", "a2", "p3", "q2", "discriminant", "mp3", "mp33", "r", "cosphi", "phi", "root1", "root2", "root3", "u1", "sd", "cubicBezierYforX", "x", "easingLinear", "keys", "map", "easingCubicBezier", "easingSteps", "steps", "position", "xdist", "jumpStart", "jumpEnd", "ydist", "startY", "sat", "overlap", "poly", "axisProj", "min1", "max1", "j", "min2", "max2", "o", "o1", "o2", "isOrientedCcw", "isOrientedCcwPolygon", "onSameSide", "px", "py", "pointInTriangle", "someInTriangle", "vertices", "isEar", "triangulate", "nextIdx", "prevIdx", "idx", "lm", "concaveVertices", "triangles", "nVertices", "current", "skipped", "next", "isConvex", "k", "winding", "ASCII_CHARS", "DEF_ANCHOR", "DEF_FONT", "DBG_FONT", "DEF_FONT_FILTER", "VERTEX_FORMAT", "STRIDE", "sum", "f", "MAX_BATCHED_QUAD", "MAX_BATCHED_VERTS", "MAX_BATCHED_INDICES", "VERT_TEMPLATE", "FRAG_TEMPLATE", "DEF_VERT", "DEF_FRAG", "COMP_DESC", "COMP_EVENTS", "DEF_OFFSCREEN_DIS", "DEF_JUMP_FORCE", "MAX_VEL", "EVENT_CANCEL_SYMBOL", "Registry", "v", "id", "KEventController", "_KEventController", "cancel", "events", "ev", "e", "p", "oldEv", "newEv", "KEvent", "action", "handler", "args", "res", "result", "EVENT_CANCEL_SYMBOL", "KEventHandler", "name", "arrayIsColor", "arr", "Color", "arrayIsVec2", "Vec2", "arrayIsNumber", "BinaryHeap", "compareFn", "a", "b", "item", "lastItem", "pos", "parent", "child", "index1", "index2", "base64ToArrayBuffer", "base64", "binstr", "len", "bytes", "i", "dataURLToArrayBuffer", "url", "download", "filename", "a", "downloadText", "text", "downloadJSON", "data", "downloadBlob", "blob", "isDataURL", "str", "getFileName", "p", "deepEq", "o1", "o2", "t1", "t2", "k1", "k2", "k", "v1", "v2", "warned", "getErrorMessage", "error", "warn", "msg", "warned", "deprecateMsg", "oldName", "newName", "toFixed", "n", "f", "overload2", "fn1", "fn2", "args", "al", "GRAPHEMES", "runes", "string", "result", "i", "increment", "nextUnits", "isGrapheme", "isVariationSelector", "isDiacriticalMark", "isZeroWidthJoiner", "current", "isFirstOfSurrogatePair", "currentPair", "nextPair", "isRegionalIndicator", "isSubdivisionFlag", "isSupplementarySpecialpurposePlane", "isFitzpatrickModifier", "betweenInclusive", "codePointFromSurrogatePair", "codePoint", "GRAPHEMES", "pair", "highOffset", "lowOffset", "value", "lower", "upper", "isEqOrIncludes", "listOrSmt", "el", "setHasOrIncludes", "set", "key", "k", "mapAddOrPush", "map", "value", "uid", "id", "gamepad_default", "updateViewport", "pixelDensity", "_k", "desiredWidth", "desiredHeight", "drawingBufferWidth", "drawingBufferHeight", "canvasWidth", "canvasHeight", "x", "y", "viewportWidth", "viewportHeight", "canvasAspectRatio", "disairedAspectRatio", "scaledWidth", "scaledHeight", "viewportToCanvas", "pt", "Vec2", "canvasToViewport", "getLastInputDeviceType", "appState", "parseButtonBindings", "btns", "b", "keyboardBtns", "keyboardCodes", "gamepadBtns", "mouseBtns", "k", "mapAddOrPush", "g", "m", "ButtonState", "btn", "GamepadState", "FPSCounter", "dt", "a", "b", "appState", "GP_MAP", "gamepad_default", "initAppState", "opt", "buttons", "Vec2", "KEventHandler", "initApp", "state", "parseButtonBindings", "fixedDt", "restDt", "isHidden", "time", "fps", "numFrames", "screenshot", "setCursor", "c", "getCursor", "setCursorLocked", "res", "e", "isCursorLocked", "enterFullscreen", "el", "exitFullscreen", "setFullscreen", "isFullscreen", "quit", "ce", "canvasEvents", "de", "docEvents", "we", "winEvents", "name", "val", "resizeObserver", "run", "fixedUpdate", "update", "fixedAccumulatedDt", "accumulatedDt", "frame", "t", "loopTime", "realDt", "desiredDt", "processInput", "resetInput", "isTouchscreen", "mousePos", "mouseDeltaPos", "isMousePressed", "m", "isMouseDown", "isMouseReleased", "isMouseMoved", "isKeyPressed", "k", "setHasOrIncludes", "isKeyPressedRepeat", "isKeyDown", "isKeyReleased", "isGamepadButtonPressed", "isGamepadButtonDown", "isGamepadButtonReleased", "isButtonPressed", "isButtonDown", "isButtonReleased", "getButton", "setButton", "binding", "pressButton", "releaseButton", "onResize", "action", "onKeyDown", "overload2", "key", "isEqOrIncludes", "onKeyPress", "onKeyPressRepeat", "onKeyRelease", "onMouseDown", "mouse", "onMousePress", "onMouseRelease", "onMouseMove", "onCharInput", "onTouchStart", "onTouchMove", "onTouchEnd", "onScroll", "onHide", "onShow", "onGamepadButtonPress", "gp", "onGamepadButtonDown", "onGamepadButtonRelease", "onGamepadStick", "stick", "v", "onGamepadConnect", "onGamepadDisconnect", "getGamepadStick", "charInputted", "getGamepads", "onButtonPress", "onButtonDown", "onButtonRelease", "processGamepad", "s", "registerGamepad", "browserGamepad", "gamepad", "vec2", "removeGamepad", "g", "map", "gamepadState", "i", "gamepadBtn", "browserGamepadBtn", "isGamepadButtonBind", "stickName", "value", "pd", "canvasToViewport", "cw", "ch", "ww", "wh", "rw", "rc", "ratio", "offset", "MOUSE_BUTTONS", "PREVENT_DEFAULT_KEYS", "KEY_ALIAS", "code", "touches", "box", "lastMousePos", "kbGamepad", "entries", "entry", "getLastInputDeviceType", "dt", "_k", "fixedDt", "restDt", "TOP_LEFT", "Vec2", "TOP", "TOP_RIGHT", "LEFT", "CENTER", "RIGHT", "BOTTOM_LEFT", "BOTTOM", "BOTTOM_RIGHT", "anchorPt", "orig", "alignPt", "align", "createEmptyAudioBuffer", "ctx", "c2", "c3", "c4", "c5", "easings", "x", "easings_default", "buildPath", "start", "goal", "cameFrom", "path", "node", "aStarSearch", "graph", "start", "goal", "frontier", "BinaryHeap", "a", "b", "cameFrom", "costSoFar", "current", "neighbours", "next", "newCost", "buildPath", "NavEdge", "a", "b", "polygon", "x", "y", "NavPolygon", "id", "edges", "centerX", "centerY", "area", "edge", "cross", "vec2", "p", "c", "e", "NavMesh", "point", "key", "vertices", "v", "index", "pos", "size", "d", "neighbours", "pairEdge", "pairPolygon", "indexA", "indexB", "start", "goal", "aStarSearch", "opt", "type", "startPolygon", "goalPolygon", "path", "i", "p1", "p2", "calcTransform", "obj", "tr", "Mat4", "screen2ndc", "pt", "Vec2", "width", "height", "getArcPts", "pos", "radiusX", "radiusY", "start", "end", "res", "deg2rad", "pts", "nverts", "step", "v", "vec2", "r", "i", "setBackground", "args", "color", "rgb", "alpha", "_k", "getBackground", "pushTranslate", "args", "p", "vec2", "_k", "pushTransform", "pushMatrix", "m", "pushScale", "pushRotate", "a", "popTransform", "flush", "width", "height", "getViewportScale", "center", "vec2", "width", "height", "TexPacker", "gfx", "w", "h", "padding", "Texture", "context2D", "img", "tex", "Quad", "paddedWidth", "paddedHeight", "curTex", "pos", "Vec2", "fixURL", "url", "isDataURL", "_k", "Asset", "_Asset", "KEvent", "loader", "data", "err", "asset", "action", "AssetBucket", "name", "id", "handle", "loaded", "a", "fetchURL", "url", "res", "fetchJSON", "path", "fetchText", "fetchArrayBuffer", "loadRoot", "_k", "loadJSON", "fixURL", "loadImg", "src", "img", "resolve", "reject", "loadProgress", "buckets", "n", "bucket", "getFailedAssets", "fails", "getAsset", "load", "prom", "initAssets", "ggl", "spriteAtlasPadding", "TexPacker", "SpriteData", "_SpriteData", "Quad", "tex", "frames", "anims", "slice9", "src", "opt", "data", "quad", "_k", "f", "slice", "url", "loadImg", "img", "resolveSprite", "spr", "getSprite", "loadProgress", "Asset", "name", "loadSprite", "fixURL", "s", "images", "createSpriteSheet", "x", "y", "dx", "dy", "w", "h", "qw", "qh", "j", "i", "canvas", "width", "height", "c2d", "merged", "loadBean", "bean_default", "loadAseprite", "name", "imgSrc", "jsonSrc", "fixURL", "getFileName", "resolveJSON", "fetchJSON", "_k", "data", "size", "frames", "f", "Quad", "anims", "anim", "SpriteData", "FontData", "DEF_FONT_FILTER", "face", "opt", "rgb", "resolveFont", "src", "_k", "DEF_FONT", "bfont", "getBitmapFont", "font", "getFont", "loadProgress", "Asset", "name", "loadFont", "fontSrc", "fixURL", "err", "makeFont", "tex", "gw", "gh", "chars", "cols", "map", "charMap", "i", "ch", "Quad", "getBitmapFont", "name", "_k", "loadBitmapFont", "src", "gw", "gh", "opt", "fontSrc", "fixURL", "loadImg", "img", "makeFont", "Texture", "ASCII_CHARS", "loadPedit", "name", "src", "fixURL", "_k", "resolve", "data", "fetchJSON", "images", "loadImg", "canvas", "c2d", "img", "i", "spr", "loadSprite", "Shader", "ctx", "vert", "frag", "attribs", "gl", "vertShader", "fragShader", "prog", "attrib", "i", "vertError", "fragError", "uniform", "name", "val", "loc", "Mat4", "Color", "Vec2", "first", "arrayIsNumber", "arrayIsVec2", "v", "arrayIsColor", "makeShader", "ggl", "vertSrc", "DEF_VERT", "fragSrc", "DEF_FRAG", "vcode", "VERT_TEMPLATE", "fcode", "FRAG_TEMPLATE", "VERTEX_FORMAT", "e", "fmt", "match", "getErrorMessage", "line", "msg", "ty", "resolveShader", "src", "_k", "shader", "getShader", "loadProgress", "Asset", "loadShader", "loadShaderURL", "fixURL", "resolveUrl", "url", "fetchText", "load", "SoundData", "_SoundData", "buf", "resolve", "reject", "_k", "url", "isDataURL", "dataURLToArrayBuffer", "fetchArrayBuffer", "resolveSound", "src", "snd", "getSound", "loadProgress", "Asset", "name", "loadSound", "fixURL", "loadMusic", "musicUrl", "a", "loadSpriteAtlas", "src", "data", "fixURL", "load", "res", "rej", "fetchJSON", "json", "SpriteData", "atlas", "map", "name", "info", "quad", "w", "h", "frames", "f", "Quad", "slice", "spr", "_k", "drawRaw", "verts", "indices", "fixed", "tex", "shaderSrc", "uniform", "parsedTex", "_k", "parsedShader", "shader", "resolveShader", "Asset", "transform", "vv", "v", "pt", "screen2ndc", "drawPolygon", "opt", "npts", "pushTransform", "pushTranslate", "pushScale", "pushRotate", "color", "Color", "verts", "pt", "Vec2", "indices", "triangulate", "t", "p", "n", "drawRaw", "_k", "drawLines", "popTransform", "drawEllipse", "opt", "start", "end", "offset", "anchorPt", "Vec2", "pts", "getArcPts", "polyOpt", "drawPolygon", "drawCircle", "opt", "drawEllipse", "drawLine", "opt", "p1", "p2", "w", "dis", "verts", "p", "Vec2", "Color", "drawRaw", "_k", "_drawLinesBevel", "pts", "vertices", "halfWidth", "isLoop", "offset", "vec2", "segment", "length", "normal", "pt1", "pt2", "dir", "n", "angle", "vector", "cs", "sn", "j", "i", "nextSegment", "nextLength", "nextNormal", "det", "lambda", "d", "v", "indices", "index", "_drawLinesRound", "fixedPoint", "deg2rad", "_drawLinesMiter", "drawLines", "width", "drawCircle", "drawCurve", "curve", "opt", "segments", "p", "i", "drawLines", "drawBezier", "opt", "drawCurve", "t", "evaluateBezier", "Texture", "_Texture", "ctx", "w", "h", "opt", "gl", "glText", "filter", "wrap", "img", "tex", "x", "y", "FrameBuffer", "frameBuffer", "renderBuffer", "data", "bytesPerRow", "temp", "topOffset", "bottomOffset", "canvas", "action", "BatchRenderer", "format", "maxVertices", "maxIndices", "sum", "f", "glVBuf", "primitive", "verts", "indices", "shader", "uniform", "deepEq", "indexOffset", "v", "i", "genStack", "setFunc", "stack", "push", "item", "pop", "cur", "initGfx", "gl", "opts", "gc", "onDestroy", "action", "destroy", "extension", "curVertexFormat", "setVertexFormat", "fmt", "deepEq", "stride", "sum", "f", "offset", "i", "pushTexture2D", "popTexture2D", "t", "pushArrayBuffer", "popArrayBuffer", "b", "pushElementArrayBuffer", "popElementArrayBuffer", "pushFramebuffer", "popFramebuffer", "pushRenderbuffer", "popRenderbuffer", "pushViewport", "popViewport", "y", "w", "h", "pushProgram", "popProgram", "p", "fontAtlases", "applyCharTransform", "fchar", "tr", "vec2", "compileStyledText", "txt", "charStyleMap", "renderText", "styleStack", "text", "emit", "ch", "execResult", "e", "gn", "x", "formatText", "opt", "font", "resolveFont", "Asset", "chars", "runes", "FontData", "fontName", "opts", "DEF_FONT_FILTER", "atlas", "Texture", "_k", "Vec2", "c2d", "m", "w", "h", "img", "Quad", "size", "scale", "lineSpacing", "letterSpacing", "curX", "tw", "th", "lines", "curLine", "cursor", "lastSpace", "lastSpaceWidth", "paraIndentX", "q", "gw", "Color", "fchars", "i", "ox", "alignPt", "idx", "styles", "name", "style", "drawUVQuad", "opt", "w", "h", "offset", "anchorPt", "DEF_ANCHOR", "Vec2", "q", "Quad", "color", "rgb", "opacity", "uvPadX", "uvPadY", "qx", "qy", "qw", "qh", "pushTransform", "pushTranslate", "pushRotate", "pushScale", "drawRaw", "popTransform", "drawFormattedText", "ftext", "pushTransform", "pushTranslate", "pushRotate", "anchorPt", "ch", "drawUVQuad", "popTransform", "drawRect", "opt", "w", "h", "offset", "anchorPt", "DEF_ANCHOR", "Vec2", "pts", "maxRadius", "r", "getArcPts", "vec2", "drawPolygon", "drawUnscaled", "content", "flush", "ow", "_k", "oh", "drawInspectText", "pos", "txt", "drawUnscaled", "pad", "vec2", "pushTransform", "pushTranslate", "ftxt", "formatText", "DBG_FONT", "rgb", "bw", "bh", "width", "height", "drawRect", "drawFormattedText", "popTransform", "drawTriangle", "opt", "drawPolygon", "drawDebug", "_k", "inspecting", "obj", "lines", "data", "tag", "drawInspectText", "viewportToCanvas", "vec2", "drawUnscaled", "pushTransform", "pushTranslate", "width", "size", "drawRect", "rgb", "i", "popTransform", "height", "pad", "ftxt", "formatText", "DBG_FONT", "flipped", "drawTriangle", "drawFormattedText", "drawCircle", "wave", "logs", "log", "str", "style", "prettyDebug", "ftext", "object", "inside", "seen", "outStr", "tmp", "e", "p", "drawFrame", "cam", "_k", "shake", "Vec2", "rand", "lerp", "dt", "Mat4", "center", "flush", "drawLoadScreen", "progress", "loadProgress", "_k", "drawUnscaled", "w", "width", "h", "pos", "vec2", "height", "drawRect", "rgb", "drawStenciled", "content", "mask", "test", "gl", "_k", "flush", "drawMasked", "content", "mask", "gl", "_k", "drawStenciled", "drawTexture", "opt", "q", "Quad", "w", "h", "scale", "Vec2", "offset", "anchorPt", "DEF_ANCHOR", "offsetX", "offsetY", "fcols", "frows", "cols", "rows", "fracX", "fracY", "n", "indices", "vertices", "index", "addQuad", "x", "y", "Color", "j", "i", "drawRaw", "drawUVQuad", "drawSprite", "opt", "spr", "resolveSprite", "q", "drawTexture", "Quad", "drawSubtracted", "content", "mask", "gl", "_k", "drawStenciled", "drawText", "opt", "drawFormattedText", "formatText", "initAppGfx", "gopt", "ggl", "defShader", "makeShader", "DEF_VERT", "DEF_FRAG", "pixelDensity", "gscale", "gl", "emptyTex", "Texture", "frameBuffer", "FrameBuffer", "bgColor", "bgAlpha", "rgb", "renderer", "BatchRenderer", "VERTEX_FORMAT", "MAX_BATCHED_VERTS", "MAX_BATCHED_INDICES", "bgTex", "Mat4", "isFixed", "obj", "getRenderProps", "circle", "radius", "opt", "drawCircle", "getRenderProps", "Rect", "Vec2", "color", "args", "rgb", "drawon", "c", "fadeIn", "time", "finalOpacity", "t", "done", "dt", "map", "mask", "m", "opacity", "a", "time", "easeFunc", "_k", "toFixed", "outline", "width", "color", "rgb", "opacity", "join", "miterLimit", "cap", "Particle", "vec2", "particles", "popt", "eopt", "emitterLifetime", "colors", "Color", "opacities", "quads", "Quad", "scales", "lifetime", "direction", "spread", "speed", "angleRange", "angularVelocityRange", "accelerationRange", "dampingRange", "indices", "vertices", "count", "time", "i", "j", "Vec2", "rgb", "onEndEvents", "KEvent", "nextFree", "index", "n", "velocityAngle", "rand", "vel", "angle", "angularVelocity", "acceleration", "damping", "lt", "pos", "p", "DT", "dt", "progress", "colorIndex", "color", "lerp", "map", "opacityIndex", "opacity", "quadIndex", "quad", "scaleIndex", "scale", "c", "s", "hw", "hh", "v", "drawRaw", "action", "polygon", "pts", "opt", "drawPolygon", "getRenderProps", "Polygon", "p", "raycast", "origin", "direction", "exclude", "minHit", "_k", "tag", "hit", "rect", "w", "h", "opt", "drawRect", "getRenderProps", "Rect", "vec2", "shader", "id", "uniform", "addLevel", "map", "opt", "level", "_k", "pos", "vec2", "numRows", "numColumns", "spatialMap", "costMap", "edgeMap", "connectivityMap", "tile2Hash", "tilePos", "hash2Tile", "hash", "createSpatialMap", "child", "insertIntoSpatialMap", "obj", "i", "removeFromSpatialMap", "index", "updateSpatialMap", "spatialMapChanged", "createCostMap", "size", "objects", "cost", "createEdgeMap", "len", "mask", "j", "createConnectivityMap", "traverse", "frontier", "getNeighbours", "getCost", "node", "neighbour", "getHeuristic", "goal", "p1", "p2", "diagonals", "n", "x", "left", "top", "right", "bottom", "levelComp", "key", "args", "p", "comps", "hasPos", "hasTile", "comp", "tile", "calcTransform", "cb", "origin", "direction", "worldOrigin", "worldDirection", "invTileWidth", "levelOrigin", "hit", "raycastGrid", "tiles", "t", "minHit", "from", "to", "opts", "start", "BinaryHeap", "a", "b", "cameFrom", "costSoFar", "current", "neighbours", "next", "newCost", "path", "cameNode", "tw", "th", "row", "keys", "on", "event", "tag", "cb", "_k", "Registry", "obj", "args", "trigger", "onFixedUpdate", "overload2", "action", "p", "onUpdate", "onDraw", "onAdd", "onDestroy", "onUse", "onUnuse", "onTag", "onUntag", "onCollide", "t1", "t2", "f", "a", "b", "col", "onCollideUpdate", "onCollideEnd", "forAllCurrentAndFuture", "onClick", "events", "KEventController", "onHover", "onHoverUpdate", "onHoverEnd", "onLoading", "onResize", "onError", "onLoad", "onLoadError", "getFailedAssets", "asset", "setCamPos", "pos", "_k", "vec2", "getCamPos", "center", "setCamScale", "scale", "getCamScale", "setCamRot", "angle", "getCamRot", "getCamTransform", "flash", "flashColor", "rgb", "fadeOutTime", "rect", "width", "height", "color", "opacity", "fixed", "fade", "destroy", "camTransform", "shake", "intensity", "toScreen", "p", "toWorld", "camPos", "deprecateMsg", "camScale", "camRot", "camFlash", "make", "comps", "compStates", "anonymousCompStates", "cleanups", "events", "KEventHandler", "inputEvents", "tags", "treatTagsAsComponents", "_k", "onCurCompCleanup", "paused", "obj", "uid", "Mat4", "p", "e", "a", "calcTransform", "idx", "trigger", "o", "child", "tag", "flush", "f", "pushTransform", "pushTranslate", "pushScale", "pushRotate", "children", "o1", "o2", "l1", "l2", "maskFunc", "popTransform", "comp", "gc", "k", "COMP_DESC", "prop", "COMP_EVENTS", "func", "c", "val", "originalCompId", "checkDeps", "dep", "id", "t", "opts", "checkTagsOrComps", "list", "recurse", "isChild", "ev", "opt", "hierarchy", "include", "exclude", "parent", "distanceOp", "sdist", "op", "compList", "name", "action", "ctrl", "args", "info", "i", "key", "value", "cb", "evs", "newEv", "KEventController", "initGame", "KEventHandler", "make", "Vec2", "Mat4", "setGravity", "g", "_k", "vec2", "getGravity", "setGravityDirection", "d", "getGravityDirection", "initAudio", "ctx", "masterNode", "burpSnd", "SoundData", "createEmptyAudioBuffer", "burp_default", "buf", "err", "playMusic", "url", "opt", "onEndEvents", "KEvent", "el", "_k", "resumeAudioCtx", "play", "time", "l", "p", "val", "clamp", "s", "d", "action", "play", "src", "opt", "_k", "playMusic", "ctx", "paused", "srcNode", "onEndEvents", "KEvent", "gainNode", "panNode", "pos", "startTime", "stopTime", "started", "getTime", "start", "data", "snd", "resolveSound", "Asset", "t", "d", "cloneNode", "oldNode", "newNode", "p", "time", "val", "pan", "l", "action", "burp", "opt", "_k", "setVolume", "v", "_k", "getVolume", "volume", "deprecateMsg", "initEvents", "_k", "fixedSize", "updateViewport", "FrameBuffer", "toFixed", "clamp", "burp", "addKaboom", "p", "opt", "kaboom", "_k", "pos", "stay", "speed", "s", "sprite", "scale", "anchor", "boom", "ka", "timer", "setLayers", "layerNames", "defaultLayer", "_k", "defaultLayerIndex", "getLayers", "getDefaultLayer", "layers", "deprecateMsg", "destroy", "obj", "getTreeRoot", "_k", "scene", "id", "def", "_k", "go", "name", "args", "obj", "initEvents", "vec2", "Mat4", "onSceneLeave", "action", "getSceneName", "sprite", "src", "opt", "spriteData", "curAnim", "curAnimDir", "spriteLoadedEvent", "KEvent", "calcTexScale", "tex", "q", "w", "h", "scale", "vec2", "setSpriteData", "obj", "spr", "animName", "anim", "createAnimFrames", "frames", "frameSeqLength", "i", "Quad", "resolveSprite", "left", "right", "top", "bottom", "tw", "th", "iw", "ih", "w1", "w3", "w2", "h1", "h3", "h2", "quads", "quad", "uv", "transform", "drawTexture", "getRenderProps", "onLoad", "dt", "name", "prevAnim", "action", "Rect", "text", "opt", "update", "obj", "ftext", "formatText", "getRenderProps", "nt", "compileStyledText", "onLoad", "drawFormattedText", "Rect", "vec2", "uvquad", "w", "h", "drawUVQuad", "getRenderProps", "Rect", "vec2", "agent", "opts", "target", "path", "index", "navMapChangedEvent", "p", "cb", "pathfinder", "opts", "graph", "target", "parent", "value", "patrol", "opts", "waypoints", "speed", "endBehavior", "index", "finished", "value", "nextWaypoint", "cb", "sentry", "candidates", "opts", "get", "_k", "checkFrequency", "directionVector", "Vec2", "t", "value", "obj", "direction", "fieldOfView", "dir", "fov", "halfAngle", "hit", "raycast", "dt", "objects", "o", "cb", "tile", "opts", "tilePos", "vec2", "isObstacle", "cost", "edges", "getEdgeMask", "loopup", "s", "mask", "dir", "edgeMask", "p", "level", "is", "n", "e", "AnimateChannel", "name", "opts", "relative", "easings_default", "obj", "t", "count", "timing", "maxIndex", "p", "m", "index", "value", "serialization", "e", "reflect", "a", "b", "AnimateChannelNumber", "keys", "alpha", "isFinished", "easing", "lerp", "AnimateChannelVec2", "followMotion", "prevKey", "nextIndex", "nextKey", "prevPrevKey", "nextNextKey", "catmullRom", "hermiteFirstDerivative", "v", "AnimateChannelColor", "animate", "gopts", "channels", "vec2", "time", "clamp", "channel", "acc", "allFinished", "localFinished", "dt", "c", "Vec2", "Color", "cb", "options", "serializeAnimation", "o", "boom", "speed", "size", "time", "s", "vec2", "dt", "health", "hp", "maxHP", "origHP", "action", "lifespan", "time", "opt", "fade", "_k", "a", "easings_default", "named", "name", "state", "initState", "stateList", "transitions", "events", "initStateEvents", "KEvent", "on", "event", "action", "trigger", "args", "didFirstEnter", "oldState", "available", "s", "from", "to", "stay", "scenesToStay", "textInput", "hasFocus", "maxInputLength", "charEv", "backEv", "flip", "_k", "character", "timer", "maxLoopsPerFrame", "time", "action", "count", "waitFirst", "t", "onEndEvents", "KEvent", "ev", "_k", "i", "p", "f", "from", "to", "duration", "setValue", "easeFunc", "easings_default", "curTime", "lerp", "areaCount", "usesArea", "area", "opt", "colliding", "collidingThisFrame", "events", "_k", "obj", "col", "event", "id", "a", "pushTransform", "pushTranslate", "opts", "getViewportScale", "rgb", "isFixed", "Rect", "drawRect", "Polygon", "drawPolygon", "Circle", "drawCircle", "popTransform", "vec2", "mpos", "other", "f", "btn", "e", "action", "hovering", "onHover", "tag", "cb", "pt", "testPolygonPoint", "localArea", "transform", "offset", "anchorPt", "DEF_ANCHOR", "body", "opt", "curPlatform", "lastPlatformPos", "willFall", "acc", "vec2", "prevPhysicsPos", "nextPhysicsPos", "prevDrawPos", "DEF_JUMP_FORCE", "other", "col", "rcol", "tmass", "calcTransform", "col2", "_k", "pastPlatform", "dt", "restDt", "lerp", "fixedDt", "prevVel", "maxVel", "MAX_VEL", "nextVel", "action", "getGravityDirection", "impulse", "force", "doubleJump", "numJumps", "jumpsLeft", "force", "action", "surfaceEffector", "opts", "obj", "col", "dir", "currentVel", "force", "areaEffector", "Vec2", "pointEffector", "length", "distance", "forceScale", "constantForce", "platformEffector", "opt", "collision", "v", "angle", "getGravityDirection", "buoyancyEffector", "o", "polygon", "submergedArea", "_", "vec2", "body", "displacedMass", "buoyancyForce", "velocity", "dragMagnitude", "dragForce", "anchor", "o", "fixed", "follow", "obj", "offset", "vec2", "layer", "_layerIndex", "_k", "value", "move", "dir", "speed", "d", "Vec2", "offscreen", "opt", "isOut", "screenRect", "Rect", "vec2", "width", "height", "selfRect", "check", "self", "DEF_OFFSCREEN_DIS", "pos", "dist", "testRectPoint", "action", "onUpdate", "pos", "args", "vec2", "dt", "dest", "speed", "diff", "p", "isFixed", "toScreen", "toWorld", "other", "drawCircle", "rgb", "getViewportScale", "rotate", "a", "angle", "scale", "args", "_scale", "vec2", "value", "Vec2", "z", "VERSION", "package_default", "_k", "kaplay", "gopt", "root", "canvas", "gscale", "fixedSize", "styles", "cw", "ch", "pixelDensity", "fontCacheCanvas", "fontCacheC2d", "app", "initApp", "gc", "canvasContext", "gl", "ggl", "initGfx", "gfx", "initAppGfx", "audio", "initAudio", "assets", "initAssets", "game", "initGame", "timer", "makeCanvas", "w", "h", "fb", "FrameBuffer", "action", "flush", "frameStart", "drawUnscaled", "drawUVQuad", "width", "height", "Quad", "Mat4", "usePostEffect", "name", "uniform", "frameEnd", "ow", "oh", "drawTexture", "Vec2", "debugPaused", "debug", "timeScale", "updateFrame", "msgs", "max", "msg", "get", "v", "getData", "key", "def", "setData", "data", "plug", "plugin", "args", "funcs", "ctx", "funcsObj", "record", "frameRate", "stream", "audioDest", "recorder", "chunks", "e", "t", "resolve", "filename", "blob", "downloadBlob", "isFocused", "add", "readd", "destroyAll", "wait", "loop", "query", "tween", "kaSprite", "loadSprite", "ka_default", "boomSprite", "boom_default", "fixedUpdateFrame", "Collision", "source", "target", "normal", "distance", "resolved", "vec2", "checkFrame", "usesArea", "grid", "cellSize", "tr", "stack", "checkObj", "obj", "aobj", "bbox", "xmin", "ymin", "xmax", "ymax", "checked", "x", "y", "cell", "check", "other", "tag", "res", "sat", "col1", "col2", "handleErr", "err", "errorMessage", "gw", "gh", "textStyle", "DBG_FONT", "drawRect", "rgb", "title", "formatText", "drawFormattedText", "drawText", "popTransform", "onCleanup", "quit", "numTextureUnits", "unit", "f", "isFirstFrame", "processInput", "resetInput", "loadProgress", "getFailedAssets", "details", "drawLoadScreen", "drawFrame", "drawDebug", "updateViewport", "initEvents", "loadRoot", "loadSpriteAtlas", "loadSound", "loadMusic", "loadBitmapFont", "loadFont", "loadShader", "loadShaderURL", "loadAseprite", "loadPedit", "loadBean", "loadJSON", "load", "getSound", "getFont", "getBitmapFont", "getSprite", "getShader", "getAsset", "Asset", "SpriteData", "SoundData", "center", "dt", "fixedDt", "restDt", "onLoad", "onLoadError", "onLoading", "onResize", "onError", "flash", "setCamPos", "getCamPos", "setCamRot", "getCamRot", "setCamScale", "getCamScale", "getCamTransform", "camPos", "camScale", "camFlash", "camRot", "camTransform", "shake", "toScreen", "toWorld", "setGravity", "getGravity", "setGravityDirection", "getGravityDirection", "setBackground", "getBackground", "getTreeRoot", "make", "destroy", "pos", "scale", "rotate", "color", "opacity", "anchor", "area", "sprite", "text", "polygon", "rect", "circle", "uvquad", "outline", "particles", "body", "platformEffector", "surfaceEffector", "areaEffector", "pointEffector", "buoyancyEffector", "constantForce", "doubleJump", "shader", "textInput", "fixed", "stay", "health", "lifespan", "named", "state", "z", "layer", "move", "offscreen", "follow", "fadeIn", "mask", "drawon", "raycast", "tile", "animate", "serializeAnimation", "agent", "sentry", "patrol", "pathfinder", "trigger", "on", "onFixedUpdate", "onUpdate", "onDraw", "onAdd", "onDestroy", "onTag", "onUntag", "onUse", "onUnuse", "onClick", "onCollide", "onCollideUpdate", "onCollideEnd", "onHover", "onHoverUpdate", "onHoverEnd", "play", "setVolume", "getVolume", "volume", "burp", "Line", "Rect", "Circle", "Ellipse", "Point", "Polygon", "Color", "RNG", "rand", "randi", "randSeed", "hsl2rgb", "quad", "choose", "chooseMultiple", "shuffle", "chance", "lerp", "easings_default", "map", "mapc", "wave", "deg2rad", "rad2deg", "clamp", "evaluateQuadratic", "evaluateQuadraticFirstDerivative", "evaluateQuadraticSecondDerivative", "evaluateBezier", "evaluateBezierFirstDerivative", "evaluateBezierSecondDerivative", "evaluateCatmullRom", "evaluateCatmullRomFirstDerivative", "curveLengthApproximation", "normalizedCurve", "hermite", "cardinal", "catmullRom", "bezier", "kochanekBartels", "easingSteps", "easingLinear", "easingCubicBezier", "testLineLine", "testRectRect", "testRectLine", "testRectPoint", "testCirclePolygon", "testLinePoint", "testLineCircle", "isConvex", "triangulate", "NavMesh", "drawSprite", "drawLine", "drawLines", "drawTriangle", "drawCircle", "drawEllipse", "drawPolygon", "drawCurve", "drawBezier", "drawMasked", "drawSubtracted", "pushTransform", "pushTranslate", "pushScale", "pushRotate", "pushMatrix", "scene", "getSceneName", "go", "onSceneLeave", "layers", "getLayers", "setLayers", "getDefaultLayer", "addLevel", "download", "downloadJSON", "downloadText", "ASCII_CHARS", "addKaboom", "KEvent", "KEventHandler", "KEventController", "EVENT_CANCEL_SYMBOL", "plugins", "kaplay_default", "kaplay"]
}
