{
  "version": 3,
  "sources": ["../src/shared.ts", "../src/utils/dataURL.ts", "../src/data/gamepad.json", "../src/constants/general.ts", "../src/ecs/entity/utils.ts", "../src/events/events.ts", "../src/types.ts", "../src/assets/sprite.ts", "../src/math/clamp.ts", "../src/constants/colorMap.ts", "../src/math/lerpNumber.ts", "../src/math/color.ts", "../src/math/Vec2.ts", "../src/math/getImageOutline.ts", "../src/math/lerp.ts", "../src/math/math.ts", "../src/assets/utils.ts", "../src/math/Mat4.ts", "../src/constants/math.ts", "../src/ecs/components/draw/color.ts", "../src/math/easings.ts", "../src/utils/numbers.ts", "../src/ecs/components/draw/opacity.ts", "../src/game/utils.ts", "../src/math/various.ts", "../src/gfx/anchor.ts", "../src/gfx/stack.ts", "../src/utils/asserts.ts", "../src/utils/log.ts", "../src/assets/shader.ts", "../src/gfx/draw/drawRaw.ts", "../src/gfx/draw/drawLine.ts", "../src/gfx/draw/drawPolygon.ts", "../src/gfx/draw/drawRect.ts", "../src/gfx/draw/drawEllipse.ts", "../src/gfx/draw/drawCircle.ts", "../src/gfx/draw/drawUVQuad.ts", "../src/gfx/draw/drawFormattedText.ts", "../src/assets/bitmapFont.ts", "../src/assets/font.ts", "../src/utils/runes.ts", "../src/gfx/formatText.ts", "../src/gfx/draw/drawText.ts", "../src/gfx/draw/drawUnscaled.ts", "../src/core/errors.ts", "../src/gfx/draw/drawStenciled.ts", "../src/gfx/draw/drawMasked.ts", "../src/gfx/draw/drawPicture.ts", "../src/gfx/draw/drawSubtracted.ts", "../src/gfx/FrameBuffer.ts", "../src/ecs/entity/make.ts", "../src/ecs/entity/prefab.ts", "../src/ecs/entity/GameObjRaw.ts", "../src/ecs/systems/systems.ts", "../src/ecs/components/physics/area.ts", "../src/ecs/components/draw/rect.ts", "../src/ecs/components/transform/fixed.ts", "../src/game/camera.ts", "../src/utils/deepEq.ts", "../src/gfx/gfx.ts", "../src/gfx/TexPacker.ts", "../src/assets/asset.ts", "../src/assets/sound.ts", "../src/audio/audio.ts", "../src/utils/overload.ts", "../src/api/eventHandlers.ts", "../src/app/data.ts", "../src/assets/aseprite.ts", "../src/assets/spriteAtlas.ts", "../src/audio/playMusic.ts", "../src/audio/play.ts", "../src/audio/burp.ts", "../src/audio/volume.ts", "../src/debug/record.ts", "../src/ecs/components/draw/blend.ts", "../src/ecs/components/draw/circle.ts", "../src/ecs/components/draw/drawon.ts", "../src/ecs/components/draw/ellipse.ts", "../src/ecs/components/draw/fadeIn.ts", "../src/ecs/components/draw/fill.ts", "../src/ecs/components/draw/mask.ts", "../src/ecs/components/draw/outline.ts", "../src/ecs/components/draw/particles.ts", "../src/ecs/components/draw/picture.ts", "../src/ecs/components/draw/polygon.ts", "../src/ecs/components/draw/raycast.ts", "../src/ecs/components/draw/shader.ts", "../src/gfx/draw/drawTexture.ts", "../src/ecs/components/draw/sprite.ts", "../src/ecs/components/draw/text.ts", "../src/ecs/components/draw/uvquad.ts", "../src/ecs/components/draw/video.ts", "../src/ecs/components/level/agent.ts", "../src/utils/binaryheap.ts", "../src/ecs/components/transform/pos.ts", "../src/ecs/components/level/tile.ts", "../src/ecs/components/level/level.ts", "../src/math/navigation.ts", "../src/ecs/components/level/pathfinder.ts", "../src/ecs/components/level/patrol.ts", "../src/ecs/components/level/sentry.ts", "../src/ecs/components/misc/animate.ts", "../src/ecs/components/misc/fakeMouse.ts", "../src/ecs/components/misc/health.ts", "../src/ecs/components/misc/lifespan.ts", "../src/ecs/components/misc/named.ts", "../src/ecs/components/misc/state.ts", "../src/ecs/components/misc/stay.ts", "../src/ecs/components/misc/textInput.ts", "../src/ecs/components/misc/timer.ts", "../src/game/gravity.ts", "../src/ecs/components/physics/body.ts", "../src/ecs/components/physics/doubleJump.ts", "../src/ecs/components/physics/effectors.ts", "../src/ecs/components/transform/anchor.ts", "../src/ecs/components/transform/constraint.ts", "../src/ecs/components/transform/follow.ts", "../src/ecs/components/transform/layer.ts", "../src/ecs/components/transform/move.ts", "../src/ecs/components/transform/offscreen.ts", "../src/ecs/components/transform/rotate.ts", "../src/ecs/components/transform/scale.ts", "../src/ecs/components/transform/skew.ts", "../src/ecs/components/transform/z.ts", "../src/ecs/components/misc/boom.ts", "../src/ecs/entity/premade/addKaboom.ts", "../src/ecs/entity/premade/addLevel.ts", "../src/ecs/systems/Collision.ts", "../src/game/layers.ts", "../src/game/scenes.ts", "../src/gfx/bg.ts", "../src/gfx/canvasBuffer.ts", "../src/gfx/draw/drawCurve.ts", "../src/gfx/draw/drawBezier.ts", "../src/gfx/draw/drawCanvas.ts", "../src/gfx/draw/drawSprite.ts", "../src/gfx/draw/drawTriangle.ts", "../src/math/ai/decisiontree.ts", "../src/math/ai/rulesystem.ts", "../src/math/ai/statemachine.ts", "../src/math/convexhull.ts", "../src/math/gjk.ts", "../src/math/lerpAngle.ts", "../src/math/navigationgrid.ts", "../src/math/navigationmesh.ts", "../src/math/polygongeneration.ts", "../src/math/sort.ts", "../src/math/spatial/quadtree.ts", "../src/core/plug.ts", "../src/core/quit.ts", "../src/core/context.ts", "../src/gfx/viewport.ts", "../src/utils/sets.ts", "../src/app/buttons.ts", "../src/app/inputBindings.ts", "../src/app/app.ts", "../src/debug/debug.ts", "../src/events/scopeHandlers.ts", "../src/events/scopes.ts", "../src/game/game.ts", "../src/gfx/canvas.ts", "../src/gfx/gfxApp.ts", "../src/app/appEvents.ts", "../src/gfx/draw/drawInspectText.ts", "../src/gfx/draw/drawDebug.ts", "../src/gfx/draw/drawFrame.ts", "../src/gfx/draw/drawLoadingScreen.ts", "../src/core/engineLoop.ts", "../src/core/fontCache.ts", "../src/core/frameRendering.ts", "../src/core/engine.ts", "../src/math/minkowski.ts", "../src/math/sat.ts", "../src/math/spatial/hashgrid.ts", "../src/math/spatial/sweepandprune.ts", "../src/ecs/systems/createCollisionSystem.ts", "../src/kaplay.ts"],
  "sourcesContent": ["import type { Engine } from \"./core/engine\";\n\n/**\n * KAPLAY.js internal data\n *\n * @ignore\n */\nexport let _k: Engine;\n\n/** @ignore */\nexport function updateEngine(e: Engine) {\n    _k = e;\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,.+/);\n\nexport const getFileName = (p: string) => p.split(\".\").slice(0, -1).join(\".\");\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  \"DualSense Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 0ce6)\": {\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\": \"touchpad\"\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", "/*\nAs KAPLAY support creating and destroying context, we really need to track all\nour global constants not being dependent on the context. If it's a constant, it\nnever should depend on the context. If it does, should be a variable of Engine\n(app, game, gfx, etc)\n\nConstants should be SNAKE_CASE\n*/\n\nimport GAMEPAD_MAP from \"../data/gamepad.json\" assert { type: \"json\" };\n\n// some default charsets for loading bitmap fonts\nexport const ASCII_CHARS =\n    \" !\\\"#$%&'()*+,-./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 SPRITE_ATLAS_WIDTH = 2048;\nexport const SPRITE_ATLAS_HEIGHT = 2048;\nexport const DEF_HASH_GRID_SIZE = 64;\nexport const LOG_MAX = 8;\nexport const LOG_TIME = 4;\nexport const VERTEX_FORMAT = [\n    { name: \"a_pos\", size: 2 },\n    { name: \"a_uv\", size: 2 },\n    { 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 =\n    `attribute vec2 a_pos;attribute vec2 a_uv;attribute vec4 a_color;varying vec2 v_pos;varying vec2 v_uv;varying vec4 v_color;uniform float width;uniform float height;uniform mat4 camera;uniform mat4 transform;vec4 def_vert(){vec4 pos=camera*transform*vec4(a_pos,0.0,1.0);return vec4(pos.x/width*2.0-1.0,pos.y/-height*2.0+1.0,pos.z,pos.w);}{{user}}void main(){vec4 pos=vert(a_pos,a_uv,a_color);v_pos=a_pos;v_uv=a_uv;v_color=a_color;gl_Position=pos;}`;\nexport const FRAG_TEMPLATE =\n    `precision mediump float;varying vec2 v_pos;varying vec2 v_uv;varying vec4 v_color;uniform sampler2D u_tex;vec4 def_frag(){vec4 texColor=texture2D(u_tex,v_uv);return vec4((v_color.rgb*texColor.rgb),texColor.a)*v_color.a;}{{user}}void main(){gl_FragColor=frag(v_pos,v_uv,v_color,u_tex);if(gl_FragColor.a==0.0){discard;}}`;\nexport const DEF_VERT =\n    `vec4 vert(vec2 pos,vec2 uv,vec4 color){return def_vert();}`;\nexport const DEF_FRAG =\n    `vec4 frag(vec2 pos,vec2 uv,vec4 color,sampler2D tex){return def_frag();}`;\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\nexport const GP_MAP = GAMEPAD_MAP as unknown as Record<string, string>;\n\nexport const MAX_TRIES = 20;\n", "import { _k } from \"../../shared\";\nimport type { GameObj } from \"../../types\";\n\nexport function exists(obj: GameObj): boolean {\n    return obj && obj.exists();\n}\n\nexport function destroy(obj: GameObj) {\n    obj.destroy();\n}\n\nexport function getTreeRoot(): GameObj {\n    return _k.game.root;\n}\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 isPaused(obj: GameObj): boolean {\n    if (obj.paused) return true;\n    return obj.parent ? isPaused(obj.parent) : false;\n}\n", "import { EVENT_CANCEL_SYMBOL } from \"../constants/general\";\nimport { isPaused } from \"../ecs/entity/utils\";\nimport type { GameObj } from \"../types\";\n\n/**\n * @group Events\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 *\n * @group Events\n */\nexport class KEventController {\n    /** If the event is paused */\n    paused: boolean = false;\n    /** The game obj that attached this event */\n    controller?: GameObj | null = null;\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        Object.defineProperty(ev, \"controller\", {\n            get: () => events[0].controller,\n            set: (p: GameObj | null) => events.forEach((e) => e.controller = p),\n        });\n        ev.paused = !!events[0]?.paused;\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        Object.defineProperty(oldEv, \"controller\", {\n            get: () => newEv.controller,\n            set: (p: GameObj | null) => newEv.controller = p,\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 || ev.controller && isPaused(ev.controller)) 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    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 type { FixedSpeedOption } from \"./app/app\";\nimport type { ButtonsDef } from \"./app/inputBindings\";\nimport type { Asset } from \"./assets/asset\";\nimport type { ShaderData, Uniform } from \"./assets/shader\";\nimport type { KAPLAYCtx } from \"./core/contextType\";\nimport type { TypesOpt } from \"./core/taf\";\nimport type { GameObjRaw } from \"./ecs/entity/GameObjRaw\";\nimport type {\n    BroadPhaseType,\n    NarrowPhaseType,\n} from \"./ecs/systems/createCollisionSystem\";\nimport type { LineCap, LineJoin } from \"./gfx/draw/drawLine\";\nimport type { Picture } from \"./gfx/draw/drawPicture\";\nimport type { FrameBuffer } from \"./gfx/FrameBuffer\";\nimport type { Color, RGBAValue, RGBValue } from \"./math/color\";\nimport type { Circle, Ellipse, Line, Point, Polygon, Rect } from \"./math/math\";\nimport type { Vec2 } from \"./math/Vec2\";\nimport type { Defined, MergeObj } from \"./utils/types\";\n\nexport type Tag = string;\n\n/**\n * The basic unit of object in KAPLAY. The player, a butterfly, a tree, or even a piece of text.\n *\n * @group Game Obj\n * @subgroup Types\n */\nexport type GameObj<T = any> = GameObjRaw & MergeComps<T>;\n\ntype RemoveCompProps<T> = Defined<\n    {\n        [K in keyof T]: K extends keyof Comp ? never : T[K];\n    }\n>;\n\n/**\n * A type to merge the components of a game object, omitting the default component properties.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport type MergeComps<T> = MergeObj<RemoveCompProps<T>>;\n\nexport type MergePlugins<T extends PluginList<any>> = MergeObj<\n    ReturnType<T[number]>\n>;\n\n/**\n * A component list.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport type CompList<T extends any | undefined> = (T | Tag)[];\nexport type PluginList<T> = Array<T | KAPLAYPlugin<any>>;\n\n/**\n * A key.\n *\n * @group Input\n * @subgroup Keyboard\n */\nexport type Key =\n    | (\n        | \"f1\"\n        | \"f2\"\n        | \"f3\"\n        | \"f4\"\n        | \"f5\"\n        | \"f6\"\n        | \"f7\"\n        | \"f8\"\n        | \"f9\"\n        | \"f10\"\n        | \"f11\"\n        | \"f12\"\n        | \"`\"\n        | \"1\"\n        | \"2\"\n        | \"3\"\n        | \"4\"\n        | \"5\"\n        | \"6\"\n        | \"7\"\n        | \"8\"\n        | \"9\"\n        | \"0\"\n        | \"-\"\n        | \"+\"\n        | \"=\"\n        | \"q\"\n        | \"w\"\n        | \"e\"\n        | \"r\"\n        | \"t\"\n        | \"y\"\n        | \"u\"\n        | \"i\"\n        | \"o\"\n        | \"p\"\n        | \"[\"\n        | \"]\"\n        | \"\\\\\"\n        | \"a\"\n        | \"s\"\n        | \"d\"\n        | \"f\"\n        | \"g\"\n        | \"h\"\n        | \"j\"\n        | \"k\"\n        | \"l\"\n        | \";\"\n        | \"'\"\n        | \"z\"\n        | \"x\"\n        | \"c\"\n        | \"v\"\n        | \"b\"\n        | \"n\"\n        | \"m\"\n        | \",\"\n        | \".\"\n        | \"/\"\n        | \"escape\"\n        | \"backspace\"\n        | \"enter\"\n        | \"tab\"\n        | \"control\"\n        | \"alt\"\n        | \"meta\"\n        | \"space\"\n        | \" \"\n        | \"left\"\n        | \"right\"\n        | \"up\"\n        | \"down\"\n        | \"shift\"\n    )\n    | (string & {});\n\n/**\n * You can use 3 or more keys (like `control+shift+s`),\n * it just isn't included in the type here because typescript\n * crashes when it tries to expand all 74^3 = 405224 combinations\n * for 3 keys.\n */\nexport type ChordedKey = Key | `${Key}+${Key}`;\n\n/**\n * A mouse button.\n *\n * @group Input\n * @subgroup Mouse\n */\nexport type MouseButton = \"left\" | \"right\" | \"middle\" | \"back\" | \"forward\";\nexport type ChordedMouseButton = MouseButton | `${MouseButton}+${MouseButton}`;\n\n/**\n * A gamepad button.\n *\n * @group Input\n * @subgroup Gamepad\n */\nexport type KGamepadButton =\n    | \"north\"\n    | \"east\"\n    | \"south\"\n    | \"west\"\n    | \"ltrigger\"\n    | \"rtrigger\"\n    | \"lshoulder\"\n    | \"rshoulder\"\n    | \"select\"\n    | \"start\"\n    | \"lstick\"\n    | \"rstick\"\n    | \"dpad-up\"\n    | \"dpad-right\"\n    | \"dpad-down\"\n    | \"dpad-left\"\n    | \"home\"\n    | \"capture\"\n    | \"touchpad\";\nexport type ChordedKGamepadButton =\n    | KGamepadButton\n    | `${KGamepadButton}+${KGamepadButton}`\n    | `${KGamepadButton}+${KGamepadButton}+${KGamepadButton}`;\n\n/**\n * A gamepad stick.\n *\n * @group Input\n * @subgroup Gamepad\n */\nexport type KGamepadStick = \"left\" | \"right\";\n\n/**\n * A gamepad definition. Used in {@link KAPLAYOpt `KAPLAYOpt`}\n *\n * @group Input\n * @subgroup Gamepad\n */\nexport type GamepadDef = {\n    buttons: Record<string, KGamepadButton>;\n    sticks: Partial<Record<KGamepadStick, { x: number; y: number }>>;\n};\n\n/**\n *  A KAPLAY gamepad\n *\n * @group Input\n * @subgroup Gamepad\n */\nexport type KGamepad = {\n    /** The order of the gamepad in the gamepad list. */\n    index: number;\n    /** If certain button is pressed. */\n    isPressed(b: KGamepadButton): boolean;\n    /** If certain button is held down. */\n    isDown(b: KGamepadButton): boolean;\n    /** If certain button is released. */\n    isReleased(b: KGamepadButton): boolean;\n    /** Get the value of a stick. */\n    getStick(stick: KGamepadStick): Vec2;\n    /** Get the 0-1 analog value of the button\n     * (useful for `ltrigger` and `rtrigger` buttons) */\n    getAnalog(b: KGamepadButton): number;\n};\n\n/**\n * Inspect info for a game object.\n */\nexport type GameObjInspect = Record<Tag, string | null>;\n\nexport type MustKAPLAYOpt = {\n    scale: number;\n    spriteAtlasPadding: number;\n} & KAPLAYOpt;\n\n/**\n * KAPLAY configurations.\n *\n * @group Start\n */\nexport interface KAPLAYOpt {\n    /**\n     * Width of game.\n     */\n    width?: number;\n    /**\n     * Height of game.\n     */\n    height?: number;\n    /**\n     * Pixel scale / size.\n     */\n    scale?: number;\n    /**\n     * Keep aspect ratio and leave black bars on remaining spaces.\n     */\n    letterbox?: boolean;\n    /**\n     * If register debug buttons (default true)\n     */\n    debug?: boolean;\n    /**\n     * Key that toggles debug mode\n     */\n    debugKey?: Key;\n    /**\n     * Default font (defaults to \"monospace\").\n     */\n    font?: string;\n    /**\n     * Device pixel scale (defaults to 1, high pixel density will hurt performance).\n     *\n     * @since v3000.0\n     */\n    pixelDensity?: number;\n    /**\n     * Disable antialias and enable sharp pixel display. If you see rendering artifacts, set `pixelDensity`\n     * param to `Math.min(devicePixelRatio, 2)` and `scale` to FHD resolution (e.g. 960x540 would need scale 2). Will result in up to 4K.\n     */\n    crisp?: boolean;\n    /**\n     * The canvas DOM element to use. If empty will create one.\n     */\n    canvas?: HTMLCanvasElement;\n    /**\n     * The container DOM element to insert the canvas if created. Defaults to document.body.\n     */\n    root?: HTMLElement;\n    /**\n     * Background color. E.g. [ 0, 0, 255 ] for solid blue background, or [ 0, 0, 0, 0 ] for transparent background. Accepts RGB value array or string hex codes.\n     */\n    background?: RGBValue | RGBAValue | string;\n    /**\n     * Default sprite texture filter.\n     * @default \"nearest\"\n     */\n    texFilter?: TexFilter;\n    /**\n     * Default text rasterization filter.\n     * @default\n     * \"linear\" for vector fonts (.woff2, .ttf, .otf, etc)\n     * \"nearest\" for bitmap fonts (loaded from an image)\n     */\n    fontFilter?: TexFilter;\n    /**\n     * How many log messages can there be on one screen (default 8).\n     */\n    logMax?: number;\n    /**\n     * How many seconds log messages stay on screen (default 4).\n     *\n     * @since v3000.1\n     */\n    logTime?: number;\n    /**\n     * Size of the spatial hash grid for collision detection (default 64).\n     *\n     * @since v3000.0\n     */\n    hashGridSize?: number;\n    /**\n     * If translate touch events as mouse clicks (default true).\n     */\n    touchToMouse?: boolean;\n    /**\n     * If KAPLAY should render a default loading screen when assets are not fully ready (default true).\n     *\n     * @since v3000.0\n     */\n    loadingScreen?: boolean;\n    /**\n     * If pause audio when tab is not active (default false).\n     *\n     * @since v3000.0\n     */\n    backgroundAudio?: boolean;\n    /**\n     * Custom gamepad definitions (see gamepad.json for reference of the format).\n     *\n     * @since v3000.0\n     */\n    gamepads?: Record<string, GamepadDef>;\n    /**\n     * Defined buttons for input binding.\n     *\n     * @since v30010\n     */\n    buttons?: ButtonsDef;\n    /**\n     * Limit framerate to an amount per second.\n     *\n     * @since v3000.0\n     */\n    maxFPS?: number;\n    /**\n     * The number of fixedUpdate() events that should happen per second.\n     * The fixedUpdate() loop is used for physics.\n     * The average user should never need to change this. If you set it too low\n     * then your physics will freak out  due to numerical instability. If you set it too high then\n     * the game will lag.\n     *\n     * The options are:\n     * * friedPotato: 10Hz\n     * * potato: 20Hz\n     * * snail: 25Hz\n     * * normal: 50Hz (default)\n     * * lightspeed: 80Hz\n     * * ridiculous: 125Hz\n     * * ludicrous: 160Hz\n     *\n     * @group Physics\n     * @experimental\n     */\n    fixedUpdateMode?: FixedSpeedOption;\n    /**\n     * The maximum amount of time the game will simulate passing in order to\n     * limit lag. If the framerate lags low enough that one frame takes\n     * longer than this time, the game will instead use this as the delta time\n     * value, which means that the game will run slower than 100% speed.\n     * The average user should never need to change this. If you set it too\n     * low, the game will slow down with even the slightest lag, and if you\n     * set it too high then the game could try to do too much on each frame\n     * and amplify the lag problem.\n     *\n     * @default 0.1\n     * @group Physics\n     * @experimental\n     */\n    maxTimeStep?: number;\n    /**\n     * If focus on the canvas on start (default true).\n     *\n     * @since v3001.0\n     */\n    focus?: boolean;\n    /**\n     * If import all KAPLAY functions to global (default true).\n     */\n    global?: boolean;\n    /**\n     * List of plugins to import.\n     */\n    plugins?: PluginList<any>;\n    /**\n     * Enter burp mode.\n     */\n    burp?: boolean;\n    /**\n     * Make components ids be added as tags.\n     *\n     * That means .is() will return true for components with that id.\n     *\n     * @default true\n     */\n    tagComponentIds?: boolean;\n    /**\n     * Padding used when adding sprites to texture atlas.\n     *\n     * @default 2\n     */\n    spriteAtlasPadding?: number;\n    /**\n     * If the debug inspect view should ignore objects that are paused when choosing\n     * the object to show the inspect view on.\n     *\n     * @default false\n     * @experimental\n     */\n    inspectOnlyActive?: boolean;\n    /**\n     * Which strategy to use for broad phase collision, sap, sapv or quadtree\n     * @default \"sap\"\n     */\n    broadPhaseCollisionAlgorithm?: BroadPhaseType;\n    /**\n     * Which strategy to use for narrow phase collision, gjk, sat or box\n     * @default \"gjk\"\n     */\n    narrowPhaseCollisionAlgorithm?: NarrowPhaseType;\n    /**\n     * If true, only the topmost object receives clicks\n     * @default false\n     */\n    topMostOnlyActivate?: boolean;\n    /**\n     * Timeout (in milliseconds) at which other loaders waiting on sprites will give\n     * up and throw an error.\n     *\n     * Currently this is only used by {@link KAPLAYCtx.loadBitmapFontFromSprite}.\n     *\n     * @default 3000\n     */\n    loadTimeout?: number;\n    /**\n     * The default lifetime scope used for event handlers.\n     *\n     * @default \"scene\"\n     */\n    defaultLifetimeScope?: \"scene\" | \"app\";\n    /**\n     * TypeScript Advanced Features (TAF) are a series of options for TypeScript\n     * only features.\n     *\n     * It should be created using the helper function `kaplayTypes`.\n     *\n     * ```ts\n     * kaplay({\n     *    types: kaplayTypes<Opt<{\n     *        scenes: {}\n     *    }>>();\n     * });\n     * ```\n     *\n     * @since v4000.0\n     */\n    types?: TypesOpt;\n}\n\n/**\n * A plugin for KAPLAY.\n *\n * @example\n * ```js\n * // a plugin that adds a new function to KAPLAY\n * const myPlugin = (k) => ({\n *    myFunc: () => {\n *       k.debug.log(\"hello from my plugin\")\n *   }\n * })\n *\n * // use the plugin\n * kaplay({\n *   plugins: [ myPlugin ]\n * })\n *\n * // now you can use the new function\n * myFunc()\n * ```\n *\n * @group Plugins\n */\nexport type KAPLAYPlugin<T> = (\n    k: KAPLAYCtx,\n) => T | ((...args: any) => (k: KAPLAYCtx) => T);\n\n/**\n * @group Rendering\n * @subgroup Canvas\n */\nexport type RenderTarget = {\n    destination: FrameBuffer | Picture | null;\n    childrenOnly?: boolean;\n    refreshOnly?: boolean;\n    isFresh?: boolean;\n};\n\n/**\n * @group Game Obj\n * @subgroup Types\n */\nexport type GetOpt = {\n    /**\n     * Recursively get all children and their descendants.\n     */\n    recursive?: boolean;\n    /**\n     * Live update the returned list every time object is added / removed.\n     */\n    liveUpdate?: boolean;\n    /**\n     * Get only by tags or components.\n     */\n    only?: \"tags\" | \"comps\";\n};\n\n/**\n * @group Game Obj\n * @subgroup Types\n */\nexport type QueryOpt = {\n    /**\n     * All objects which include all or any of these tags, depending on includeOp.\n     */\n    include?: string | string[];\n    /**\n     * Selects the operator to use. Defaults to and.\n     */\n    includeOp?: \"and\" | \"or\";\n    /**\n     * All objects which do not have all or any of these tags, depending on excludeOp.\n     */\n    exclude?: string | string[];\n    /**\n     * Selects the operator to use. Defaults to and.\n     */\n    excludeOp?: \"and\" | \"or\";\n    /**\n     * All objects which are near or far to the position of this, depending on distanceOp.\n     */\n    distance?: number;\n    /**\n     * Selects the operator to use. Defaults to near.\n     */\n    distanceOp?: \"near\" | \"far\";\n    /**\n     * All objects visible from this standpoint.\n     */\n    visible?: boolean;\n    /**\n     * All objects in the given group. Defaults to children.\n     */\n    hierarchy?: \"children\" | \"siblings\" | \"ancestors\" | \"descendants\";\n    /**\n     * All objects matching name\n     */\n    name?: string;\n};\n\n/**\n * Sprite animation configuration when playing.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface SpriteAnimPlayOpt {\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     * If the animation should not restart from frame 1 and t=0 if it is already playing.\n     *\n     * @default false\n     */\n    preventRestart?: boolean;\n    /**\n     * Runs when this animation ends.\n     */\n    onEnd?: () => void;\n}\n\n/**\n * @group Assets\n * @subgroup Data\n */\nexport type MusicData = string;\n\n/**\n * @group Assets\n * @subgroup Types\n */\nexport interface LoadFontOpt {\n    outline?: number | Outline;\n    /**\n     * The size to load the font in (default 64).\n     *\n     * @since v3001.0\n     */\n    size?: number;\n    /**\n     * The font filter to use, if different from the global font filter.\n     */\n    filter?: TexFilter;\n}\n\n/**\n * @group Assets\n * @subgroup Types\n */\nexport type TextureOpt = {\n    filter?: TexFilter;\n    wrap?: TexWrap;\n};\n\n/**\n * @group Assets\n * @subgroup Types\n */\nexport type ImageSource = Exclude<TexImageSource, VideoFrame>;\n\n/**\n * @group Rendering\n * @subgroup Canvas\n */\nexport type Canvas = {\n    width: number;\n    height: number;\n    toImageData(): ImageData;\n    toDataURL(): string;\n    clear(): void;\n    draw(action: () => void): void;\n    free(): void;\n    readonly fb: FrameBuffer;\n};\n\n/**\n * @group Rendering\n * @subgroup Shaders\n */\nexport interface Vertex {\n    pos: Vec2;\n    uv: Vec2;\n    color: Color;\n    opacity: number;\n}\n\n/**\n * @group Rendering\n * @subgroup Shaders\n */\nexport enum BlendMode {\n    Normal = 0,\n    Add = 1,\n    Multiply = 2,\n    Screen = 3,\n    Overlay = 4,\n}\n\n/**\n * @group Rendering\n * @subgroup Shaders\n */\nexport interface Attributes {\n    pos: number[];\n    uv: number[];\n    color: number[];\n    opacity: number[];\n}\n\n/**\n * Texture scaling filter. \"nearest\" is mainly for sharp pixelated scaling, \"linear\" means linear interpolation.\n */\nexport type TexFilter = \"nearest\" | \"linear\";\nexport type TexWrap = \"repeat\" | \"clampToEdge\";\n\n/**\n * Common render properties.\n */\nexport interface RenderProps {\n    pos?: Vec2;\n    scale?: Vec2;\n    angle?: number;\n    skew?: Vec2;\n    color?: Color;\n    opacity?: number;\n    fixed?: boolean;\n    shader?: string | ShaderData | Asset<ShaderData> | null;\n    uniform?: Uniform | null;\n    blend?: BlendMode;\n    outline?: Outline;\n}\n\nexport interface Outline {\n    /**\n     * The width, or thickness of the line.\n     */\n    width?: number;\n    /**\n     * The color of the line.\n     */\n    color?: Color;\n    /**\n     * Opacity (overrides fill opacity).\n     *\n     * @since v3001.0\n     */\n    opacity?: number;\n    /**\n     * Line join.\n     *\n     * @since v3000.0\n     */\n    join?: LineJoin;\n    /**\n     * Miter limit. If the length of the miter divided by the line width exceeds this limit, the style is converted to a bevel.\n     *\n     * @since v3001.0\n     */\n    miterLimit?: number;\n    /**\n     * Line cap.\n     *\n     * @since v3001.0\n     */\n    cap?: LineCap;\n}\n\n/**\n * @group Rendering\n * @subgroup Screen\n */\nexport type Cursor =\n    | string\n    | \"auto\"\n    | \"default\"\n    | \"none\"\n    | \"context-menu\"\n    | \"help\"\n    | \"pointer\"\n    | \"progress\"\n    | \"wait\"\n    | \"cell\"\n    | \"crosshair\"\n    | \"text\"\n    | \"vertical-text\"\n    | \"alias\"\n    | \"copy\"\n    | \"move\"\n    | \"no-drop\"\n    | \"not-allowed\"\n    | \"grab\"\n    | \"grabbing\"\n    | \"all-scroll\"\n    | \"col-resize\"\n    | \"row-resize\"\n    | \"n-resize\"\n    | \"e-resize\"\n    | \"s-resize\"\n    | \"w-resize\"\n    | \"ne-resize\"\n    | \"nw-resize\"\n    | \"se-resize\"\n    | \"sw-resize\"\n    | \"ew-resize\"\n    | \"ns-resize\"\n    | \"nesw-resize\"\n    | \"nwse-resize\"\n    | \"zoom-int\"\n    | \"zoom-out\";\n\n/**\n * @group Draw\n */\nexport type Anchor =\n    | \"topleft\"\n    | \"top\"\n    | \"topright\"\n    | \"left\"\n    | \"center\"\n    | \"right\"\n    | \"botleft\"\n    | \"bot\"\n    | \"botright\";\n\n/**\n * @group Math\n * @subgroup Random\n */\nexport type RNGValue = number | Vec2 | Color;\n\n/**\n * @group Components\n * @subgroup Component Types\n */\nexport interface Comp {\n    /**\n     * Component ID (if left out won't be treated as a comp).\n     */\n    id?: Tag;\n    /**\n     * What other comps this comp depends on.\n     */\n    require?: Tag[];\n    /**\n     * Event that runs when host game obj is added to scene.\n     */\n    add?: () => void;\n    /**\n     * Event that runs at a fixed frame rate.\n     */\n    fixedUpdate?: () => void;\n    /**\n     * Event that runs every frame.\n     */\n    update?: () => void;\n    /**\n     * Event that runs every frame after update.\n     */\n    draw?: () => void;\n    /**\n     * Event that runs when obj is removed from scene.\n     */\n    destroy?: () => void;\n    /**\n     * Debug info for inspect mode.\n     */\n    inspect?: () => string | null;\n    /**\n     * Draw debug info in inspect mode.\n     *\n     * @since v3000.0\n     */\n    drawInspect?: () => void;\n    /**\n     * Serializes the component.\n     *\n     * @since v4000.0\n     */\n    serialize?: () => any;\n}\n\n/**\n * A valid game object id.\n *\n * @group Game Obj\n * @subgroup GameObjID\n */\nexport type GameObjID = number;\n\n/**\n * A component without own properties.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport type EmptyComp = { id: string } & Comp;\n\n/**\n * @group Draw\n */\nexport type Shape = Rect | Line | Point | Circle | Ellipse | Polygon;\n\nexport type Mask = \"intersect\" | \"subtract\";\n\n/**\n * @group Math\n * @subgroup Advanced\n */\nexport type Edge = \"left\" | \"right\" | \"top\" | \"bottom\";\n\n/**\n * @group Math\n * @subgroup Advanced\n */\nexport enum 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", "import type { DrawSpriteOpt } from \"../gfx/draw/drawSprite\";\nimport type { Frame } from \"../gfx/TexPacker\";\nimport { Quad, quad } from \"../math/math\";\nimport { _k } from \"../shared\";\nimport { type ImageSource, type TexFilter } from \"../types\";\nimport { Asset, loadImg, loadProgress, spriteSrcToImage } from \"./asset\";\nimport { fixURL, slice } from \"./utils\";\n\n/**\n * Frame-based animation configuration.\n *\n * @group Assets\n * @subgroup Types\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 *\n * @group Assets\n * @subgroup Types\n */\nexport type SpriteAnims = Record<string, SpriteAnim>;\n\n// TODO: support frameWidth and frameHeight as alternative to slice\n/**\n * Sprite loading options.\n *\n * @group Assets\n * @subgroup Types\n */\nexport interface LoadSpriteOpt {\n    /**\n     * If the single image area contains multiple sprites in a grid, how many frames are in the area horizontally.\n     */\n    sliceX?: number;\n    /**\n     * If the single image area contains multiple sprites arranged in a grid, 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' bounding boxes, if the frames are not in a grid and so sliceX/sliceY won't do.\n     * If present, overrides sliceX and sliceY. If the given sprite source is a list of images, each image is\n     * its own frame, and this is not used.\n     *\n     * Format: x, y, w, and h are in **pixels**\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     * The tex filter to use, if different than the global sprite filter\n     */\n    filter?: TexFilter;\n    /**\n     * If you've already packed your spritesheet, you can set this to false to tell KAPLAY not to repack it\n     * when loading it into the main texture. However, this may negatively impact rendering performance if\n     * it causes future sprites to not fit and be moved to a different GPU texture.\n     *\n     * This doesn't apply if you use singular: true, because the entire image will be its own texture then.\n     *\n     * @default true\n     */\n    repack?: boolean;\n}\n\n/**\n * @group Assets\n * @subgroup Types\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     * How regions should tile when the sprite is scaled.\n     * - `\"none\"`: All regions stretch (default)\n     * - `\"edges\"`: Edge regions (top, bottom, left, right) tile, center stretches\n     * - `\"center\"`: Center region tiles, edges stretch\n     * - `\"all\"`: Both edges and center tile\n     *\n     * Corners never tile.\n     */\n    tileMode?: \"none\" | \"edges\" | \"center\" | \"all\";\n};\n\n/**\n * Possible values for loading an sprite using {@link loadSprite `loadSprite`}.\n *\n * @group Assets\n * @subgroup Types\n */\nexport type LoadSpriteSrc = string | ImageSource;\n\nexport class SpriteData {\n    constructor(\n        public frames: Frame[],\n        public anims: SpriteAnims = {},\n        public slice9: NineSlice | null = null,\n    ) {}\n\n    /**\n     * @since v3001.0\n     */\n    get width() {\n        return this.frames[0].tex.width * this.frames[0].q.w;\n    }\n\n    get height() {\n        return this.frames[0].tex.height * this.frames[0].q.h;\n    }\n\n    static fromSpriteSrc(\n        src: LoadSpriteSrc,\n        opt: LoadSpriteOpt = {},\n    ): Promise<SpriteData> {\n        return spriteSrcToImage(src).then(img =>\n            SpriteData.fromSingle(img, opt)\n        );\n    }\n\n    static fromMultiple(\n        data: ImageSource[],\n        opt: LoadSpriteOpt = {},\n    ): SpriteData {\n        const filter = opt.filter ?? _k.globalOpt.texFilter ?? \"nearest\";\n        const frames = data.map(\n            opt.singular\n                ? (src => _k.assets.packer.addSingle(src, filter))\n                : (src => _k.assets.packer.add(src, filter)),\n        );\n        return new SpriteData(frames, opt.anims, opt.slice9);\n    }\n\n    static fromSingle(data: ImageSource, opt: LoadSpriteOpt = {}): SpriteData {\n        const frames: Quad[] = opt.frames\n            ? fixFramesPixelsToFractionOfImage(\n                opt.frames,\n                data.width,\n                data.height,\n            )\n            : slice(opt.sliceX || 1, opt.sliceY || 1);\n        const filter = opt.filter ?? _k.globalOpt.texFilter ?? \"nearest\";\n        if (opt.singular) {\n            const { tex, q: quad, id } = _k.assets.packer.addSingle(\n                data,\n                filter,\n            );\n            return new SpriteData(\n                frames.map(f => ({\n                    tex,\n                    q: quad.scale(f),\n                    id,\n                })),\n                opt.anims,\n                opt.slice9,\n            );\n        }\n        const sd = new SpriteData(\n            (opt.repack ?? true)\n                ? frames.map(frame => _k.assets.packer.add(data, filter, frame))\n                : _k.assets.packer.addPrepacked(data, filter, frames),\n            opt.anims,\n            opt.slice9,\n        );\n        return sd;\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        // might be sometimes unnecessary here but if we're getting the sprite data directly\n        // then obviously we might be wanting to draw it.\n        _k.k.onLoad(() => _k.assets.packer.syncIfPending());\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\n    if (Array.isArray(src)) {\n        if (src.some((s) => typeof s === \"string\")) {\n            return _k.assets.sprites.add(\n                name,\n                Promise.all(\n                    src.map((s) => {\n                        return typeof s === \"string\"\n                            ? loadImg(s)\n                            : Promise.resolve(s);\n                    }),\n                ).then(images => SpriteData.fromMultiple(images, opt)),\n            );\n        }\n        else {\n            return _k.assets.sprites.addLoaded(\n                name,\n                SpriteData.fromMultiple(src as ImageSource[], opt),\n            );\n        }\n    }\n    else {\n        if (typeof src === \"string\") {\n            return _k.assets.sprites.add(\n                name,\n                SpriteData.fromSpriteSrc(src, opt),\n            );\n        }\n        else {\n            return _k.assets.sprites.addLoaded(\n                name,\n                SpriteData.fromSingle(src, opt),\n            );\n        }\n    }\n}\n\nexport function loadBean(name: string = \"bean\"): Asset<SpriteData> {\n    if (!_k.game.defaultAssets.bean) {\n        throw new Error(\"You can't use bean in kaplay/mini\");\n    }\n\n    return loadSprite(name, _k.game.defaultAssets.bean);\n}\n\nexport function fixFramesPixelsToFractionOfImage(\n    frames: Quad[],\n    width: number,\n    height: number,\n): Quad[] {\n    // Given frames are dx, dy, width, and height in pixels, but internal\n    // format is fraction of image size, so convert it\n    return frames.map(q =>\n        quad(\n            q.x / width,\n            q.y / height,\n            q.w / width,\n            q.h / height,\n        )\n    );\n}\n", "export const 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", "// For using color(\"gray\"), color(\"red\")\nexport const CSS_COLOR_MAP = {\n    black: \"#000000\",\n    silver: \"#c0c0c0\",\n    gray: \"#808080\",\n    white: \"#ffffff\",\n    maroon: \"#800000\",\n    red: \"#ff0000\",\n    purple: \"#800080\",\n    fuchsia: \"#ff00ff\",\n    green: \"#008000\",\n    lime: \"#00ff00\",\n    olive: \"#808000\",\n    yellow: \"#ffff00\",\n    navy: \"#000080\",\n    blue: \"#0000ff\",\n    teal: \"#008080\",\n    aqua: \"#00ffff\",\n    aliceblue: \"#f0f8ff\",\n    antiquewhite: \"#faebd7\",\n    aquamarine: \"#7fffd4\",\n    azure: \"#f0ffff\",\n    beige: \"#f5f5dc\",\n    bisque: \"#ffe4c4\",\n    blanchedalmond: \"#ffebcd\",\n    blueviolet: \"#8a2be2\",\n    brown: \"#a52a2a\",\n    burlywood: \"#deb887\",\n    cadetblue: \"#5f9ea0\",\n    chartreuse: \"#7fff00\",\n    chocolate: \"#d2691e\",\n    coral: \"#ff7f50\",\n    cornflowerblue: \"#6495ed\",\n    cornsilk: \"#fff8dc\",\n    crimson: \"#dc143c\",\n    cyan: \"#00ffff\",\n    darkblue: \"#00008b\",\n    darkcyan: \"#008b8b\",\n    darkgoldenrod: \"#b8860b\",\n    darkgray: \"#a9a9a9\",\n    darkgreen: \"#006400\",\n    darkkhaki: \"#bdb76b\",\n    darkmagenta: \"#8b008b\",\n    darkolivegreen: \"#556b2f\",\n    darkorange: \"#ff8c00\",\n    darkorchid: \"#9932cc\",\n    darkred: \"#8b0000\",\n    darksalmon: \"#e9967a\",\n    darkseagreen: \"#8fbc8f\",\n    darkslateblue: \"#483d8b\",\n    darkslategray: \"#2f4f4f\",\n    darkturquoise: \"#00ced1\",\n    darkviolet: \"#9400d3\",\n    deeppink: \"#ff1493\",\n    deepskyblue: \"#00bfff\",\n    dimgray: \"#696969\",\n    dodgerblue: \"#1e90ff\",\n    firebrick: \"#b22222\",\n    floralwhite: \"#fffaf0\",\n    forestgreen: \"#228b22\",\n    gainsboro: \"#dcdcdc\",\n    ghostwhite: \"#f8f8ff\",\n    gold: \"#ffd700\",\n    goldenrod: \"#daa520\",\n    greenyellow: \"#adff2f\",\n    honeydew: \"#f0fff0\",\n    hotpink: \"#ff69b4\",\n    indianred: \"#cd5c5c\",\n    indigo: \"#4b0082\",\n    ivory: \"#fffff0\",\n    khaki: \"#f0e68c\",\n    lavender: \"#e6e6fa\",\n    lavenderblush: \"#fff0f5\",\n    lawngreen: \"#7cfc00\",\n    lemonchiffon: \"#fffacd\",\n    lightblue: \"#add8e6\",\n    lightcoral: \"#f08080\",\n    lightcyan: \"#e0ffff\",\n    lightgoldenrodyellow: \"#fafad2\",\n    lightgray: \"#d3d3d3\",\n    lightgreen: \"#90ee90\",\n    lightpink: \"#ffb6c1\",\n    lightsalmon: \"#ffa07a\",\n    lightseagreen: \"#20b2aa\",\n    lightskyblue: \"#87cefa\",\n    lightslategray: \"#778899\",\n    lightsteelblue: \"#b0c4de\",\n    lightyellow: \"#ffffe0\",\n    limegreen: \"#32cd32\",\n    linen: \"#faf0e6\",\n    mediumaquamarine: \"#66cdaa\",\n    mediumblue: \"#0000cd\",\n    mediumorchid: \"#ba55d3\",\n    mediumpurple: \"#9370db\",\n    mediumseagreen: \"#3cb371\",\n    mediumslateblue: \"#7b68ee\",\n    mediumspringgreen: \"#00fa9a\",\n    mediumturquoise: \"#48d1cc\",\n    mediumvioletred: \"#c71585\",\n    midnightblue: \"#191970\",\n    mintcream: \"#f5fffa\",\n    mistyrose: \"#ffe4e1\",\n    moccasin: \"#ffe4b5\",\n    navajowhite: \"#ffdead\",\n    oldlace: \"#fdf5e6\",\n    olivedrab: \"#6b8e23\",\n    orange: \"#ffa500\",\n    orangered: \"#ff4500\",\n    orchid: \"#da70d6\",\n    palegoldenrod: \"#eee8aa\",\n    palegreen: \"#98fb98\",\n    paleturquoise: \"#afeeee\",\n    palevioletred: \"#db7093\",\n    papayawhip: \"#ffefd5\",\n    peachpuff: \"#ffdab9\",\n    peru: \"#cd853f\",\n    pink: \"#ffc0cb\",\n    plum: \"#dda0dd\",\n    powderblue: \"#b0e0e6\",\n    rebeccapurple: \"#663399\",\n    rosybrown: \"#bc8f8f\",\n    royalblue: \"#4169e1\",\n    saddlebrown: \"#8b4513\",\n    salmon: \"#fa8072\",\n    sandybrown: \"#f4a460\",\n    seagreen: \"#2e8b57\",\n    seashell: \"#fff5ee\",\n    sienna: \"#a0522d\",\n    skyblue: \"#87ceeb\",\n    slateblue: \"#6a5acd\",\n    slategray: \"#708090\",\n    snow: \"#fffafa\",\n    springgreen: \"#00ff7f\",\n    steelblue: \"#4682b4\",\n    tan: \"#d2b48c\",\n    thistle: \"#d8bfd8\",\n    tomato: \"#ff6347\",\n    turquoise: \"#40e0d0\",\n    violet: \"#ee82ee\",\n    wheat: \"#f5deb3\",\n    whitesmoke: \"#f5f5f5\",\n    yellowgreen: \"#9acd32\",\n};\n", "export function lerpNumber(\n    a: number,\n    b: number,\n    t: number,\n) {\n    return a + (b - a) * t;\n}\n", "import { CSS_COLOR_MAP } from \"../constants/colorMap\";\nimport { _k } from \"../shared\";\nimport { clamp } from \"./clamp\";\nimport { lerpNumber } from \"./lerpNumber\";\n\n/**\n * @group Math\n * @subgroup Colors\n */\nexport type RGBValue = [number, number, number];\n\n/**\n * @group Math\n * @subgroup Colors\n */\nexport type RGBAValue = [number, number, number, number];\n\n/**\n * @group Math\n * @subgroup Colors\n */\nexport type CSSColorKeywords = keyof typeof CSS_COLOR_MAP;\n\n/**\n * A serialized color.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedColor {\n    r: number;\n    g: number;\n    b: number;\n}\n\n/**\n * 0-255 RGBA color.\n *\n * @group Math\n * @subgroup Colors\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    static fromArray(arr: [number, number, 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    /**\n     * Create a color from a CSS color name\n     *\n     * @param cssColor - The color name.\n     *\n     * @example\n     * ```js\n     * loadHappy();\n     *\n     * add([\n     *     rect(512, 512, {\n     *         radius: [0, 96, 96, 96]\n     *     }),\n     *     color(\"#663399\"),\n     *     pos(40, 40),\n     * ]);\n     *\n     * add([\n     *     text(\"css\", { size: 192, font: \"happy\" }),\n     *     pos(90, 310)\n     * ]);\n     * ```\n     *\n     * @static\n     * @returns The color.\n     * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0\n     */\n    static fromCSS(cssColor: CSSColorKeywords) {\n        const color = CSS_COLOR_MAP[cssColor];\n        // for js users\n        if (!color) throw new Error(\"Can't use an invalid CSS color\");\n\n        return Color.fromHex(color);\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            lerpNumber(this.r, dest.r, t),\n            lerpNumber(this.g, dest.g, t),\n            lerpNumber(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    serialize(): { r: number; g: number; b: number } {\n        return { r: this.r, g: this.g, b: this.b };\n    }\n\n    static deserialize(data: { r: number; g: number; b: number }): Color {\n        return new Color(data.r, data.g, data.b);\n    }\n}\n\n/**\n * Possible color arguments for various functions.\n *\n * @group Math\n * @subgroup Colors\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    | [CSSColorKeywords & (string & {})]\n    | [number];\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        const cl = args[0];\n\n        if (cl instanceof Color) {\n            // rgb(new Color(255, 255, 255))\n            return cl.clone();\n        }\n        else if (typeof cl === \"string\") {\n            if (cl[0] != \"#\" && CSS_COLOR_MAP[cl as CSSColorKeywords]) {\n                return Color.fromCSS(cl as CSSColorKeywords);\n            }\n\n            return Color.fromHex(args[0]);\n        }\n        else if (typeof cl === \"number\") {\n            return Color.fromHex(cl);\n        }\n        else if (Array.isArray(args[0]) && args[0].length === 3) {\n            // rgb([255, 255, 255])\n            return Color.fromArray(args[0] as [number, number, number]);\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 { _k } from \"../shared\";\nimport { lerpNumber } from \"./lerpNumber\";\nimport type { Mat4 } from \"./Mat4\";\nimport { deg2rad, rad2deg, Rect, vec2, type Vec2Args } from \"./math\";\n\n/**\n * A serialized 2d vector.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedVec2 {\n    x: number;\n    y: number;\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    /** Set the X and Y of this vector */\n    set(x: number, y: number): Vec2 {\n        this.x = x;\n        this.y = y;\n        return this;\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    /** Closest orthogonal direction: LEFT, RIGHT, UP, or DOWN */\n    toAxis(): Vec2 {\n        return Math.abs(this.x) > Math.abs(this.y)\n            ? this.x < 0 ? Vec2.LEFT : Vec2.RIGHT\n            : this.y < 0\n            ? Vec2.UP\n            : Vec2.DOWN;\n    }\n\n    /** Clone the vector */\n    clone(): Vec2 {\n        return new Vec2(this.x, this.y);\n    }\n\n    static copy(v: Vec2, out: Vec2): Vec2 {\n        out.x = v.x;\n        out.y = v.y;\n        return out;\n    }\n\n    /** Returns the sum 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    static addScaled(v: Vec2, other: Vec2, s: number, out: Vec2): Vec2 {\n        out.x = v.x + other.x * s;\n        out.y = v.y + other.y * s;\n        return out;\n    }\n\n    /**\n     * Calculates the sum of the vectors\n     * @param v - The first term\n     * @param x - The x of the second term\n     * @param y - The y of the second term\n     * @param out - The vector sum\n     *\n     * @returns The sum of the vectors\n     */\n    static addc(v: Vec2, x: number, y: number, out: Vec2): Vec2 {\n        out.x = v.x + x;\n        out.y = v.y + y;\n        return out;\n    }\n\n    /**\n     * Calculates the sum of the vectors\n     * @param v - The first term\n     * @param other - The second term\n     * @param out - The vector sum\n     *\n     * @returns The sum of the vectors\n     */\n    static add(v: Vec2, other: Vec2, out: Vec2): Vec2 {\n        out.x = v.x + other.x;\n        out.y = v.y + other.y;\n        return out;\n    }\n\n    /** Returns the difference 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    /**\n     * Calculates the difference of the vectors\n     * @param v - The first term\n     * @param x - The x of the second term\n     * @param y - The y of the second term\n     * @param out - The vector difference\n     *\n     * @returns The difference of the vectors\n     */\n    static subc(v: Vec2, x: number, y: number, out: Vec2): Vec2 {\n        out.x = v.x - x;\n        out.y = v.y - y;\n        return out;\n    }\n\n    /**\n     * Calculates the difference of the vectors\n     * @param v - The first term\n     * @param other - The second term\n     * @param out - The vector difference\n     *\n     * @returns The difference of the vectors\n     */\n    static sub(v: Vec2, other: Vec2, out: Vec2): Vec2 {\n        out.x = v.x - other.x;\n        out.y = v.y - other.y;\n        return out;\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    /**\n     * Calculates the scale of the vector\n     * @param v - The vector\n     * @param x - The x scale\n     * @param y - The y scale\n     * @param out - The scaled vector\n     *\n     * @returns The scale of the vector\n     */\n    static scale(v: Vec2, s: number, out: Vec2): Vec2 {\n        out.x = v.x * s;\n        out.y = v.y * s;\n        return out;\n    }\n\n    /**\n     * Calculates the scale of the vector\n     * @param v - The vector\n     * @param x - The x scale\n     * @param y - The y scale\n     * @param out - The scaled vector\n     *\n     * @returns The scale of the vector\n     */\n    static scalec(v: Vec2, x: number, y: number, out: Vec2): Vec2 {\n        out.x = v.x * x;\n        out.y = v.y * y;\n        return out;\n    }\n\n    /**\n     * Calculates the scale of the vector\n     * @param v - The vector\n     * @param other - The scale\n     * @param out - The scaled vector\n     *\n     * @returns The scale of the vector\n     */\n    static scalev(v: Vec2, other: Vec2, out: Vec2): Vec2 {\n        out.x = v.x * other.x;\n        out.y = v.y * other.y;\n        return out;\n    }\n\n    /** Scale by the inverse of another vector. or a single number */\n    invScale(...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    /**\n     * Calculates the distance between the vectors\n     * @param v - The vector\n     * @param other - The other vector\n     *\n     * @returns The between the vectors\n     */\n    static dist(v: Vec2, other: Vec2): number {\n        const x = v.x - other.x;\n        const y = v.y - other.y;\n        return Math.sqrt(x * x + y * y);\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     *\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     * Calculates the length of the vector\n     * @param v - The vector\n     *\n     * @returns The length of the vector\n     */\n    static len(v: Vec2) {\n        return Math.sqrt(v.x * v.x + v.y * v.y);\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     * Calculates the squared length of the vector\n     * @param v - The vector\n     *\n     * @returns The squared length of the vector\n     */\n    static slen(v: Vec2) {\n        return v.x * v.x + v.y * v.y;\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    static unit(v: Vec2, out: Vec2): Vec2 {\n        const len = Vec2.len(v);\n        if (len === 0) {\n            out.x = 0;\n            out.y = 0;\n            return out;\n        }\n        out.x = v.x / len;\n        out.y = v.y / len;\n        return out;\n    }\n\n    /**\n     * Get the perpendicular vector.\n     */\n    normal(): Vec2 {\n        return new Vec2(this.y, -this.x);\n    }\n\n    static normal(v: Vec2, out: Vec2): Vec2 {\n        out.x = v.y;\n        out.y = -v.x;\n        return out;\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    rotate(vecOrAngle: Vec2 | number) {\n        if (vecOrAngle instanceof Vec2) {\n            return new Vec2(\n                this.x * vecOrAngle.x - this.y * vecOrAngle.y,\n                this.x * vecOrAngle.y + this.y * vecOrAngle.x,\n            );\n        }\n        else {\n            const angle = deg2rad(vecOrAngle);\n            const c = Math.cos(angle);\n            const s = Math.sin(angle);\n            return new Vec2(\n                this.x * c - this.y * s,\n                this.x * s + this.y * c,\n            );\n        }\n    }\n\n    /**\n     * Calculates the rotated vector\n     * @param v - The vector\n     * @param dir - The rotation vector\n     * @param out - The rotated vector\n     *\n     * @returns The rotated vector\n     */\n    static rotate(v: Vec2, dir: Vec2, out: Vec2): Vec2 {\n        const tmp = v.x;\n        out.x = v.x * dir.x - v.y * dir.y;\n        out.y = tmp * dir.y + v.y * dir.x;\n        return out;\n    }\n\n    /**\n     * Calculates the rotated vector\n     * @param v - The vector\n     * @param angle - The angle in radians\n     * @param out - The rotated vector\n     *\n     * @returns The rotated vector\n     */\n    static rotateByAngle(v: Vec2, angle: number, out: Vec2): Vec2 {\n        const c = Math.cos(angle);\n        const s = Math.sin(angle);\n        const tmp = v.x;\n        out.x = v.x * c - v.y * s;\n        out.y = tmp * s + v.y * c;\n        return out;\n    }\n\n    invRotate(vecOrAngle: Vec2 | number) {\n        if (vecOrAngle instanceof Vec2) {\n            return this.rotate(new Vec2(vecOrAngle.x, -vecOrAngle.y));\n        }\n        else {\n            return this.rotate(-vecOrAngle);\n        }\n    }\n\n    /**\n     * Calculates the inverse rotated vector\n     * @param v - The vector\n     * @param dir - The rotation vector\n     * @param out - The rotated vector\n     *\n     * @returns The rotated vector\n     */\n    static inverseRotate(v: Vec2, dir: Vec2, out: Vec2): Vec2 {\n        const tmp = v.x;\n        out.x = v.x * dir.x + v.y * dir.y;\n        out.y = -tmp * dir.y + v.y * dir.x;\n        return out;\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     * Calculates the angle represented by the vector in radians\n     * @param v - The vector\n     *\n     * @returns Angle represented by the vector in radians\n     */\n    static toAngle(v: Vec2) {\n        return Math.atan2(v.y, v.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     * Calculates the angle between the vectors in radians\n     * @param v - First vector\n     * @param other - Second vector\n     *\n     * @returns Angle between the vectors in radians\n     */\n    static angleBetween(v: Vec2, other: Vec2) {\n        return Math.atan2(Vec2.cross(v, other), Vec2.dot(v, other));\n    }\n\n    /**\n     * Linear interpolate to a destination vector (for positions).\n     */\n    lerp(dest: Vec2, t: number): Vec2 {\n        return new Vec2(\n            lerpNumber(this.x, dest.x, t),\n            lerpNumber(this.y, dest.y, t),\n        );\n    }\n\n    /**\n     * Linear interpolate src and dst by t\n     * @param src - First vector\n     * @param dst - Second vector\n     * @param t - Percentage\n     * @param out - The linear interpolation between src and dst by t\n     *\n     * @returns The linear interpolation between src and dst by t\n     */\n    static lerp(src: Vec2, dst: Vec2, t: number, out: Vec2): Vec2 {\n        out.x = src.x + (dst.x - src.x) * t;\n        out.y = src.y + (dst.y - src.y) * t;\n        return out;\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        if (Math.abs(sin) < 1e-6) {\n            return this.lerp(dest, t);\n        }\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     * Spherical interpolate src and dst by t\n     * @param src - First vector\n     * @param dst - Second vector\n     * @param t - Percentage\n     * @param out - The spherical interpolation between src and dst by t\n     *\n     * @returns The spherical interpolation between src and dst by t\n     */\n    static slerp(src: Vec2, dst: Vec2, t: number, out: Vec2): Vec2 {\n        const cos = Vec2.dot(src, dst);\n        const sin = Vec2.cross(src, dst);\n        if (Math.abs(sin) < 1e-6) {\n            return out = src.lerp(dst, t);\n        }\n        const angle = Math.atan2(sin, cos);\n        const t1 = Math.sin((1 - t) * angle);\n        const t2 = Math.sin(t * angle);\n        const invSin = 1 / sin;\n        out.x = (src.x * t1 + dst.x * t2) * invSin;\n        out.y = (src.y * t1 + dst.y * t2) * invSin;\n        return out;\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    serialize(): SerializedVec2 {\n        return { x: this.x, y: this.y };\n    }\n\n    static deserialize(data: SerializedVec2): Vec2 {\n        return vec2(data.x, data.y);\n    }\n}\n", "import { Vec2 } from \"./Vec2\";\n\nexport function traceRegion(\n    width: number,\n    height: number,\n    isInRegion: (x: number, y: number) => boolean,\n    RDP: boolean,\n    epsilon: number,\n): Vec2[] {\n    // Directions for clockwise boundary tracing (Moore-neighborhood)\n    const directions = [\n        new Vec2(1, 0),\n        new Vec2(1, 1),\n        new Vec2(0, 1),\n        new Vec2(-1, 1),\n        new Vec2(-1, 0),\n        new Vec2(-1, -1),\n        new Vec2(0, -1),\n        new Vec2(1, -1),\n    ];\n\n    // Find a starting pixel in the region\n    let start: Vec2 | null = null;\n    for (let y = 0; y < height && !start; y++) {\n        for (let x = 0; x < width && !start; x++) {\n            if (isInRegion(x, y)) {\n                start = new Vec2(x, y);\n                break;\n            }\n        }\n    }\n    if (!start) return [];\n\n    const outline: Vec2[] = [];\n    let current = { ...start };\n    let prevDir = 0;\n\n    do {\n        outline.push(new Vec2(current.x, current.y));\n        // Search neighbors clockwise from previous direction - 2\n        let dir = (prevDir + 6) % 8;\n        for (let i = 0; i < 8; i++) {\n            const d = directions[(dir + i) % 8];\n            const nx = current.x + d.x;\n            const ny = current.y + d.y;\n            if (\n                nx >= 0 && nx < width && ny >= 0 && ny < height\n                && isInRegion(nx, ny)\n            ) {\n                current = { x: nx, y: ny };\n                prevDir = (dir + i) % 8;\n                break;\n            }\n        }\n    } while (\n        current.x !== start.x || current.y !== start.y || outline.length === 1\n    );\n\n    // Optional Ramer\u2013Douglas\u2013Peucker simplification\n    if (RDP) {\n        return simplifyClosed(outline, epsilon);\n    }\n\n    return outline;\n}\n\nfunction simplifyClosed(points: Vec2[], epsilon: number): Vec2[] {\n    const open = points.slice();\n    if (open.length > 1 && open[0].dist(open[open.length - 1]) < 1e-3) {\n        open.pop();\n    }\n    const simplified = RDP(open, epsilon);\n\n    simplified.push(simplified[0]);\n    return simplified;\n}\n\n// ****************************************************************************\n// Calculates the perpendicular distance between c and the line formed by a, b\n// ****************************************************************************\nfunction getDistance(c: Vec2, a: Vec2, b: Vec2): number {\n    const A = b.y - a.y;\n    const B = a.x - b.x;\n    const C = b.x * a.y - a.x * b.y;\n\n    return Math.abs(A * c.x + B * c.y + C) / Math.sqrt(A * A + B * B);\n}\n\n// *****************************************************\n// Ramer\u2013Douglas\u2013Peucker - Used to simplify the polygons\n// *****************************************************\nfunction RDP(points: Vec2[], epsilon: number): Vec2[] {\n    if (points.length < 3) return points;\n\n    var start_indx = 0;\n    var end_indx = points.length - 1;\n    var max_dist = 0;\n    var max_indx = 0;\n\n    for (var i = start_indx + 1; i < end_indx; i++) {\n        var d = getDistance(points[i], points[start_indx], points[end_indx]);\n        if (d > max_dist) {\n            max_dist = d;\n            max_indx = i;\n        }\n    }\n\n    if (points[0].eq(points[points.length - 1])) {\n        points = points.slice(0, -1);\n    }\n\n    if (max_dist > epsilon) {\n        var l = RDP(points.slice(start_indx, max_indx + 1), epsilon);\n        var r = RDP(points.slice(max_indx, end_indx + 1), epsilon);\n\n        return [...l.slice(0, -1), ...r];\n    }\n    else {\n        return [points[start_indx], points[end_indx]];\n    }\n}\n", "import { Color } from \"./color\";\nimport { Vec2 } from \"./Vec2\";\n\n/**\n * A valid value for lerp.\n *\n * @group Math\n * @subgroup Tween\n */\nexport type LerpValue = number | Vec2 | Color;\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        // we don't call lerpNumber just for performance, but should be the same\n        return a + (b - a) * t as V;\n    }\n    // check for Vec2\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\n    throw new Error(\n        `Bad value for lerp(): ${a}, ${b}. Only number, Vec2 and Color is supported.`,\n    );\n}\n", "// TODO: A lot\n// - move RNG to it's own file\n\nimport { resolveSprite } from \"../assets/sprite\";\nimport { _k } from \"../shared\";\nimport type { GameObj, RNGValue, Shape } from \"../types\";\nimport { clamp } from \"./clamp\";\nimport { Color, rgb } from \"./color\";\nimport { traceRegion } from \"./getImageOutline\";\nimport { lerp, type LerpValue } from \"./lerp\";\nimport { Vec2 } from \"./Vec2\";\n\n/**\n * Possible arguments for a Vec2.\n *\n * @group Math\n * @subgroup Vectors\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 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\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 * @subgroup Advanced\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/**\n * @group Math\n * @subgroup Advanced\n */\nexport class 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\nexport class Mat23 {\n    // 2x3 matrix, 2 rows and 3 columns, since the last row is always (0, 0, 1)\n    // | a c e |\n    // | b d f |\n    // | 0 0 1 |\n    // Actually would like a Mat2 + Vec2, but that would be 3 objects for 1 matrix\n    a: number;\n    b: number;\n    c: number;\n    d: number;\n    e: number;\n    f: number;\n    _inverse: Mat23 | null = null;\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    // | 1 0 x |\n    // | 0 1 y |\n    // | 0 0 1 |\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    // | c -s 0 |\n    // | s  c 0 |\n    // | 0 0 1 |\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    // | x 0 0 |\n    // | 0 y 0 |\n    // | 0 0 1 |\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    // | 1 x 0 |\n    // | y 1 0 |\n    // | 0 0 1 |\n    static fromSkew(s: Vec2): Mat23 {\n        const x = Math.tan(s.x);\n        const y = Math.tan(s.y);\n        return new Mat23(\n            1,\n            y,\n            x,\n            1,\n            0,\n            0,\n        );\n    }\n    clone() {\n        return new Mat23(\n            this.a,\n            this.b,\n            this.c,\n            this.d,\n            this.e,\n            this.f,\n        );\n    }\n    setMat23(m: Mat23) {\n        this.a = m.a;\n        this.b = m.b;\n        this.c = m.c;\n        this.d = m.d;\n        this.e = m.e;\n        this.f = m.f;\n        this._inverse = m._inverse;\n        return this;\n    }\n    // | 1 0 0 |\n    // | 0 1 0 |\n    // | 0 0 1 |\n    setIdentity() {\n        this.a = 1;\n        this.b = 0;\n        this.c = 0;\n        this.d = 1;\n        this.e = 0;\n        this.f = 0;\n        this._inverse = null;\n        return this;\n    }\n    setTRS(x: number, y: number, angle: number, sx: number, sy: number) {\n        const radians = angle * Math.PI / 180;\n        const c = Math.cos(radians);\n        const s = Math.sin(radians);\n        this.a = c * sx;\n        this.b = s * sx;\n        this.c = -s * sy;\n        this.d = c * sy;\n        this.e = x;\n        this.f = y;\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    // | a c e |   | 1 0 x |\n    // | b d f | * | 0 1 y |\n    // | 0 0 1 |   | 0 0 1 |\n    translateSelfV(t: Vec2): Mat23 {\n        this.e += t.x * this.a + t.y * this.c;\n        this.f += t.x * this.b + t.y * this.d;\n        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | 1 0 x |\n    // | b d f | * | 0 1 y |\n    // | 0 0 1 |   | 0 0 1 |\n    translateSelf(x: number, y: number): Mat23 {\n        this.e += x * this.a + y * this.c;\n        this.f += x * this.b + y * this.d;\n        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | c -s 0 |\n    // | b d f | * | s  c 0 |\n    // | 0 0 1 |   | 0  0 1 |\n    rotateSelf(degrees: number): Mat23 {\n        const radians = deg2rad(degrees);\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        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | x 0 0 |\n    // | b d f | * | 0 y 0 |\n    // | 0 0 1 |   | 0 0 1 |\n    scaleSelfV(s: Vec2): Mat23 {\n        this.a *= s.x;\n        this.b *= s.x;\n        this.c *= s.y;\n        this.d *= s.y;\n        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | x 0 0 |\n    // | b d f | * | 0 y 0 |\n    // | 0 0 1 |   | 0 0 1 |\n    scaleSelf(x: number, y: number): Mat23 {\n        this.a *= x;\n        this.b *= x;\n        this.c *= y;\n        this.d *= y;\n        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | 1 x 0 |\n    // | b d f | * | y 1 0 |\n    // | 0 0 1 |   | 0 0 1 |\n    skewSelfV(s: Vec2): Mat23 {\n        const x = Math.tan(deg2rad(s.x));\n        const y = Math.tan(deg2rad(s.y));\n        const oldA = this.a;\n        const oldB = this.b;\n        this.a += this.c * y;\n        this.b += this.d * y;\n        this.c += oldA * x;\n        this.d += oldB * x;\n        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | 1 x 0 |\n    // | b d f | * | y 1 0 |\n    // | 0 0 1 |   | 0 0 1 |\n    skewSelf(x: number, y: number): Mat23 {\n        x = Math.tan(deg2rad(x));\n        y = Math.tan(deg2rad(y));\n        const oldA = this.a;\n        const oldB = this.b;\n        this.a += this.c * y;\n        this.b += this.d * y;\n        this.c += oldA * x;\n        this.d += oldB * x;\n        this._inverse = null;\n        return this;\n    }\n    mulSelf(other: Mat23): Mat23 {\n        const a = other.a * this.a + other.b * this.c;\n        const b = other.a * this.b + other.b * this.d;\n        const c = other.c * this.a + other.d * this.c;\n        const d = other.c * this.b + other.d * this.d;\n        const e = other.e * this.a + other.f * this.c + this.e;\n        const f = other.e * this.b + other.f * this.d + this.f;\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        this._inverse = null;\n        return this;\n    }\n    // | a c e |   | x |\n    // | b d f | * | y |\n    // | 0 0 1 |   | 1 |\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    // | a c e |   | x |\n    // | b d f | * | y |\n    // | 0 0 1 |   | 1 |\n    transformPointV(p: Vec2, o: Vec2): Vec2 {\n        const tmp = p.x;\n        o.x = this.a * p.x + this.c * p.y + this.e;\n        o.y = this.b * tmp + this.d * p.y + this.f;\n        return o;\n    }\n    // | a c e |   | x |\n    // | b d f | * | y |\n    // | 0 0 1 |   | 0 |\n    transformVectorV(v: Vec2, o: Vec2): Vec2 {\n        const tmp = v.x;\n        o.x = this.a * v.x + this.c * v.y;\n        o.y = this.b * tmp + this.d * v.y;\n        return o;\n    }\n    // | a c e |   | x |\n    // | b d f | * | y |\n    // | 0 0 1 |   | 1 |\n    transformPoint(x: number, y: number, o: Vec2): Vec2 {\n        const tmp = x;\n        o.x = this.a * x + this.c * y + this.e;\n        o.y = this.b * tmp + this.d * y + this.f;\n        return o;\n    }\n    // | a c e |   | x |\n    // | b d f | * | y |\n    // | 0 0 1 |   | 0 |\n    transformVector(x: number, y: number, o: Vec2): Vec2 {\n        const tmp = x;\n        o.x = this.a * x + this.c * y;\n        o.y = this.b * tmp + this.d * y;\n        return o;\n    }\n\n    get det() {\n        return this.a * this.d - this.b * this.c;\n    }\n\n    get inverse() {\n        if (this._inverse) return this._inverse;\n        const det = this.det;\n        this._inverse = 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        return this._inverse;\n    }\n    // The translation is directly accessible\n    getTranslation() {\n        return new Vec2(this.e, this.f);\n    }\n    // Using atan2(y, x) = angle\n    // since a = sx * cos(angle)\n    //       b = sx * sin(angle)\n    // and atan2 does y / x, thus sx is eliminated\n    getRotation() {\n        if (this.a || this.b) {\n            return rad2deg(\n                Math.atan2(this.b, this.a),\n            );\n        }\n        else {\n            return 90 - rad2deg(\n                Math.atan2(this.d, this.c),\n            );\n        }\n    }\n    // Using cos^2 + sin^2 = 1, thus sqrt(a^2 + b^2) contains the scale\n    // since a = sx * cos(angle)\n    //       b = sx * sin(angle)\n    getScale() {\n        const d = this.det;\n        if (d != 0) {\n            if (this.a || this.b) {\n                const r = Math.sqrt(this.a * this.a + this.b * this.b);\n                return vec2(r, d / r);\n            }\n            else if (this.c || this.d) {\n                const s = Math.sqrt(this.c * this.c + this.d * this.d);\n                return vec2(d / s, s);\n            }\n        }\n        return vec2(0);\n    }\n    getSkew() {\n        if (this.a || this.b) {\n            const r = Math.sqrt(this.a * this.a + this.b * this.b);\n            return vec2(\n                rad2deg(Math.atan2(this.a * this.c + this.b * this.d, r * r)),\n                0,\n            );\n        }\n        else if (this.c || this.d) {\n            const s = Math.sqrt(this.c * this.c + this.d * this.d);\n            return vec2(\n                0,\n                rad2deg(Math.atan2(this.a * this.c + this.b * this.d, s * s)),\n            );\n        }\n        return vec2(0);\n    }\n}\n\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\nexport function wave<V extends LerpValue>(\n    lo: V,\n    hi: V,\n    t: number,\n    f = (t: number) => -Math.cos(t),\n): V {\n    return lerp(lo, hi, (f(t) + 1) / 2);\n}\n\n// basic ANSI C LCG\nexport const A = 1103515245;\nexport const C = 12345;\nexport const M = 2147483648;\n\n/**\n * A random number generator using the linear congruential generator algorithm.\n *\n * @group Math\n * @subgroup Random\n */\nexport class RNG {\n    /**\n     * The current seed value used by the random number generator.\n     */\n    seed: number;\n    constructor(seed: number) {\n        this.seed = seed;\n    }\n\n    /**\n     * Generate a random number between 0 and 1.\n     *\n     * @example\n     * ```js\n     * const rng = new RNG(Date.now())\n     * const value = rng.gen() // Returns number between 0-1\n     * ```\n     *\n     * @returns A number between 0 and 1.\n     */\n    gen(): number {\n        this.seed = (A * this.seed + C) % M;\n        return this.seed / M;\n    }\n\n    /**\n     * Generate a random number between two values.\n     *\n     * @param a - The minimum value.\n     * @param b - The maximum value.\n     *\n     * @example\n     * ```js\n     * const rng = new RNG(Date.now())\n     * const value = rng.genNumber(10, 20) // Returns number between 10-20\n     * ```\n     *\n     * @returns A number between a and b.\n     */\n    genNumber(a: number, b: number): number {\n        return a + this.gen() * (b - a);\n    }\n    /**\n     * Generate a random 2D vector between two vectors.\n     *\n     * @param a - The minimum vector.\n     * @param b - The maximum vector.\n     *\n     * @example\n     * ```js\n     * const rng = new RNG(Date.now())\n     * const vec = rng.genVec2(vec2(0,0), vec2(100,100))\n     * ```\n     *\n     * @returns A vector between vectors a and b.\n     */\n    genVec2(a: Vec2, b: Vec2): Vec2 {\n        return new Vec2(this.genNumber(a.x, b.x), this.genNumber(a.y, b.y));\n    }\n\n    /**\n     * Generate a random color between two colors.\n     *\n     * @param a - The first color.\n     * @param b - The second color.\n     *\n     * @example\n     * ```js\n     * const rng = new RNG(Date.now())\n     * const color = rng.genColor(rgb(0,0,0), rgb(255,255,255))\n     * ```\n     *\n     * @returns A color between colors a and b.\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\n    /**\n     * Generate a random value of a specific type.\n     *\n     * @param args - No args for [0-1], one arg for [0-arg], or two args for [arg1-arg2].\n     *\n     * @example\n     * ```js\n     * const rng = new RNG(Date.now())\n     * const val = rng.genAny(0, 100) // Number between 0-100\n     * const vec = rng.genAny(vec2(0,0), vec2(100,100)) // Vec2\n     * const col = rng.genAny(rgb(0,0,0), rgb(255,255,255)) // Color\n     * ```\n     *\n     * @returns A random value.\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\nexport function randSeed(seed?: number): number {\n    if (seed != null) {\n        _k.game.defRNG.seed = seed;\n    }\n    return _k.game.defRNG.seed;\n}\n\nexport function rand<T = number>(...args: [] | [T] | [T, T]) {\n    return _k.game.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 clipLineToRect(r: Rect, l: Line, result: Line): boolean {\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    else {\n        if (l.p1.x < r.pos.x || l.p1.x > r.pos.x + r.width) {\n            return false;\n        }\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    else {\n        if (l.p1.y < r.pos.y || l.p1.y > r.pos.y + r.height) {\n            return false;\n        }\n    }\n\n    if (tmax >= tmin && tmax >= 0 && tmin <= 1) {\n        Vec2.addScaled(l.p1, dir, Math.max(tmin, 0), result.p1);\n        Vec2.addScaled(l.p1, dir, Math.min(tmax, 1), result.p2);\n        return true;\n    }\n    else {\n        return false;\n    }\n}\n\nexport function testRectLine(r: Rect, l: Line): boolean {\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    else {\n        if (l.p1.x < r.pos.x || l.p1.x > r.pos.x + r.width) {\n            return false;\n        }\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    else {\n        if (l.p1.y < r.pos.y || l.p1.y > r.pos.y + r.height) {\n            return false;\n        }\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 clipLineToCircle(\n    circle: Circle,\n    l: Line,\n    result: Line,\n): 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            if (testCirclePoint(circle, l.p1)) {\n                Vec2.copy(l.p1, result.p1);\n                Vec2.addScaled(l.p1, v, t, result.p2);\n            }\n            else {\n                Vec2.addScaled(l.p1, v, t, result.p1);\n                Vec2.copy(l.p2, result.p2);\n            }\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        const b1 = t1 >= 0 && t1 <= 1;\n        const b2 = t2 >= 0 && t2 <= 1;\n        if (b1 && b2) {\n            Vec2.addScaled(l.p1, v, t1, result.p1);\n            Vec2.addScaled(l.p1, v, t2, result.p2);\n            return true;\n        }\n        else if (b1 || b2) {\n            const t = b1 ? t1 : t2;\n            if (testCirclePoint(circle, l.p1)) {\n                Vec2.copy(l.p1, result.p1);\n                Vec2.addScaled(l.p1, v, t, result.p2);\n            }\n            else {\n                Vec2.addScaled(l.p1, v, t, result.p1);\n                Vec2.copy(l.p2, result.p2);\n            }\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    if (testCirclePoint(circle, l.p1)) {\n        Vec2.copy(l.p1, result.p1);\n        Vec2.copy(l.p2, result.p2);\n        return true;\n    }\n    else {\n        return false;\n    }\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 * @subgroup Shapes\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 * @subgroup Raycast\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 * @subgroup Raycast\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 (direction.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 (direction.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: Mat23, s?: Shape): Point {\n        if (s && s instanceof Point) {\n            m.transformPointV(this.pt, s.pt);\n            return s;\n        }\n        return new Point(m.transformPointV(this.pt, vec2()));\n    }\n    bbox(r?: Rect): Rect {\n        if (r) {\n            r.pos.x = this.pt.x;\n            r.pos.y = this.pt.y;\n            r.width = 0;\n            r.height = 0;\n            return r;\n        }\n        else {\n            return new Rect(this.pt, 0, 0);\n        }\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    serialize(): any {\n        return { \"Point\": { pt: this.pt.serialize() } };\n    }\n    support(direction: Vec2): Vec2 {\n        return this.pt;\n    }\n    get gjkCenter(): Vec2 {\n        return this.pt;\n    }\n    /* Returns the point\n     **/\n    closestPt(p: Vec2): Vec2 | undefined {\n        return this.pt;\n    }\n}\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: Mat23, s?: Shape): Line {\n        if (s && s instanceof Line) {\n            m.transformPointV(this.p1, s.p1);\n            m.transformPointV(this.p2, s.p2);\n            return s;\n        }\n        return new Line(\n            m.transformPointV(this.p1, vec2()),\n            m.transformPointV(this.p2, vec2()),\n        );\n    }\n    bbox(r?: Rect): Rect {\n        if (r) {\n            r.pos.x = this.p1.x;\n            r.pos.y = this.p1.y;\n            r.width = this.p2.x - this.p1.x;\n            r.height = this.p2.y - this.p1.y;\n            return r;\n        }\n        else {\n            return Rect.fromPoints(this.p1, this.p2);\n        }\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    serialize(): any {\n        return { Line: { p1: this.p1.serialize(), p2: this.p2.serialize() } };\n    }\n    support(direction: Vec2): Vec2 {\n        return this.p1.dot(direction) > this.p2.dot(direction)\n            ? this.p1\n            : this.p2;\n    }\n    get gjkCenter(): Vec2 {\n        return new Vec2(\n            (this.p1.x + this.p2.x) / 2,\n            (this.p1.y + this.p2.y) / 2,\n        );\n    }\n    /* Calculates the point on the line segment (not just vertex)\n     * closest to the given point.\n     **/\n    closestPt(p: Vec2): Vec2 | undefined {\n        const v1 = new Vec2();\n        const v2 = new Vec2();\n        Vec2.sub(p, this.p1, v1);\n        Vec2.sub(this.p2, this.p1, v2);\n        // Calculate scalar projection\n        const t = v1.dot(v2) / v2.dot(v2);\n        // If on edge segment\n        if (t >= 0 && t <= 1) {\n            // Calculate projected point on edge\n            return this.p1.add(v2.scale(t));\n        }\n        else {\n            return this.p1.sdist(p) < this.p2.sdist(p) ? this.p1 : this.p2;\n        }\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: Mat23, s?: Shape): Polygon {\n        // TODO: resize existing pts array?\n        const p = (s && s instanceof Polygon && s.pts.length == 4)\n            ? s\n            : new Polygon([new Vec2(), new Vec2(), new Vec2(), new Vec2()]);\n        p.pts[0] = m.transformPointV(this.pos, p.pts[0]);\n        p.pts[1] = m.transformPoint(\n            this.pos.x + this.width,\n            this.pos.y,\n            p.pts[1],\n        );\n        p.pts[2] = m.transformPoint(\n            this.pos.x + this.width,\n            this.pos.y + this.height,\n            p.pts[2],\n        );\n        p.pts[3] = m.transformPoint(\n            this.pos.x,\n            this.pos.y + this.height,\n            p.pts[3],\n        );\n        return p;\n    }\n    bbox(r?: Rect): Rect {\n        if (r) {\n            r.pos.x = this.pos.x;\n            r.pos.y = this.pos.y;\n            r.width = this.width;\n            r.height = this.height;\n            return r;\n        }\n        else {\n            return this.clone();\n        }\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    serialize(): any {\n        return {\n            Rect: {\n                pos: this.pos.serialize(),\n                width: this.width,\n                height: this.height,\n            },\n        };\n    }\n    support(direction: Vec2): Vec2 {\n        const pts = this.points();\n        let maxPoint = this.points()[0];\n        let maxDistance = Number.NEGATIVE_INFINITY;\n        let vertex;\n        for (let i = 1; i < pts.length; i++) {\n            vertex = pts[i];\n            const distance = vertex.dot(direction);\n            if (distance > maxDistance) {\n                maxDistance = distance;\n                maxPoint = vertex;\n            }\n        }\n\n        return maxPoint;\n    }\n    get gjkCenter(): Vec2 {\n        return this.pos;\n    }\n    /* Calculates the point on the rectangle (not just vertex)\n     * closest to the given point provided that the projected point lies within the rectangle\n     **/\n    closestPt(p: Vec2): Vec2 | undefined {\n        // TODO\n        return undefined;\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: Mat23, s?: Shape): Ellipse {\n        return new Ellipse(this.center, this.radius, this.radius).transform(tr);\n    }\n    bbox(r?: Rect): Rect {\n        if (r) {\n            r.pos.x = this.center.x - this.radius;\n            r.pos.y = this.center.y - this.radius;\n            r.width = this.radius * 2;\n            r.height = this.radius * 2;\n            return r;\n        }\n        else {\n            return Rect.fromPoints(\n                this.center.sub(vec2(this.radius)),\n                this.center.add(vec2(this.radius)),\n            );\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    serialize(): any {\n        return {\n            Circle: { center: this.center.serialize(), radius: this.radius },\n        };\n    }\n    support(direction: Vec2): Vec2 {\n        const s = new Vec2(direction.x, direction.y);\n        Vec2.unit(s, s);\n        Vec2.scale(s, this.radius, s);\n        Vec2.add(s, this.center, s);\n        return s;\n    }\n    get gjkCenter(): Vec2 {\n        return this.center;\n    }\n    /* Calculates the point on the circle\n     * closest to the given point provided that the projected point lies within the circle\n     **/\n    closestPt(p: Vec2): Vec2 | undefined {\n        return this.support(p.sub(this.center));\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: Mat23): 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.transformPointV(this.center, vec2()),\n                tr.a * this.radiusX,\n                tr.d * 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.transformPointV(this.center, vec2());\n            return ellipse;\n        }\n    }\n    bbox(r?: Rect): Rect {\n        if (this.angle == 0) {\n            // No rotation, so the semi-major and semi-minor axis give the extends\n            if (r) {\n                r.pos.x = this.center.x - this.radiusX;\n                r.pos.y = this.center.y - this.radiusY;\n                r.width = this.radiusX * 2;\n                r.height = this.radiusY * 2;\n                return r;\n            }\n            else {\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        }\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            if (r) {\n                r.pos.x = this.center.x - halfwidth;\n                r.pos.y = this.center.y - halfheight;\n                r.width = halfwidth * 2;\n                r.height = halfheight * 2;\n                return r;\n            }\n            else {\n                return Rect.fromPoints(\n                    this.center.sub(vec2(halfwidth, halfheight)),\n                    this.center.add(vec2(halfwidth, halfheight)),\n                );\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    serialize(): any {\n        return {\n            Ellipse: {\n                center: this.center.serialize(),\n                radiusX: this.radiusX,\n                radiusY: this.radiusY,\n                angle: this.angle,\n            },\n        };\n    }\n    support(direction: Vec2): Vec2 {\n        // Axis aligned\n        if (this.angle === 0.0) {\n            let axis = new Vec2(direction.x, direction.y);\n            Vec2.unit(axis, axis);\n            Vec2.scalec(axis, this.radiusX, this.radiusY, axis);\n            Vec2.add(axis, this.center, axis);\n            return axis;\n        }\n        // Rotated\n        else {\n            let axis = new Vec2(direction.x, direction.y);\n            Vec2.rotateByAngle(axis, -this.angle, axis);\n            Vec2.unit(axis, axis);\n            Vec2.scalec(axis, this.radiusX, this.radiusY, axis);\n            Vec2.rotateByAngle(axis, this.angle, axis);\n            Vec2.add(axis, this.center, axis);\n            return axis;\n        }\n    }\n    get gjkCenter(): Vec2 {\n        return this.center;\n    }\n    /* Calculates the point on the ellipse\n     * closest to the given point provided that the projected point lies within the circle\n     **/\n    closestPt(p: Vec2): Vec2 | undefined {\n        return this.support(p.sub(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\nexport function getSpriteOutline(\n    asset: string,\n    frame = 0,\n    RDP = true,\n    epsilon = 10,\n): Polygon {\n    const spr = resolveSprite(asset);\n    if (!spr?.data) throw new Error(\"Can't load asset: \" + asset);\n\n    const frameData = spr.data.frames[frame];\n\n    const px = frameData.q.x * frameData.tex.width;\n    const py = frameData.q.y * frameData.tex.height;\n    const pw = frameData.q.w * frameData.tex.width;\n    const ph = frameData.q.h * frameData.tex.height;\n\n    const canvas = document.createElement(\"canvas\");\n    canvas.width = pw;\n    canvas.height = ph;\n    const ctx = canvas.getContext(\"2d\")!;\n    ctx.drawImage(frameData.tex.src as any, px, py, pw, ph, 0, 0, pw, ph);\n\n    const image_data = ctx.getImageData(0, 0, pw, ph);\n    const isInRegion = (x: number, y: number) => {\n        const idx = (y * image_data.width + x) * 4 + 3;\n        return image_data.data[idx] >= 50;\n    };\n\n    const trace = traceRegion(\n        image_data.width,\n        image_data.height,\n        isInRegion,\n        RDP,\n        epsilon,\n    );\n    console.log(trace);\n    return new Polygon(trace);\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        /*this.center = new Vec2(pts[0].x, pts[0].y);\n        for (let i = 1; i < pts.length; i++) {\n            this.center.x += pts[i].x;\n            this.center.y += pts[i].y;\n        }\n        this.center.x /= pts.length;\n        this.center.y /= pts.length;*/\n    }\n    transform(m: Mat23, s?: Shape): Polygon {\n        // TODO: resize existing pts array?\n        if (s && s instanceof Polygon && s.pts.length == this.pts.length) {\n            for (let i = 0; i < this.pts.length; i++) {\n                m.transformPointV(this.pts[i], s.pts[i]);\n            }\n            return s;\n        }\n        return new Polygon(this.pts.map((pt) => m.transformPointV(pt, vec2())));\n    }\n    bbox(r?: Rect): 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        if (r) {\n            r.pos.x = p1.x;\n            r.pos.y = p1.y;\n            r.width = p2.x - p1.x;\n            r.height = p2.y - p1.y;\n            return r;\n        }\n        else {\n            return Rect.fromPoints(p1, p2);\n        }\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(\n        a: Vec2,\n        b: Vec2,\n        srcUv?: Vec2[],\n        dstUv?: [Vec2[], Vec2[]],\n    ): [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, index) => {\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                if (srcUv && dstUv) {\n                    const uv1 =\n                        srcUv[index === 0 ? srcUv.length - 1 : index - 1];\n                    const uv2 = srcUv[index];\n                    const ab = p.sub(prev);\n                    const ac = intersection.sub(prev);\n                    const alpha = ac.dot(ab) / ab.dot(ab);\n                    const uv = lerp(uv1, uv2, alpha);\n                    dstUv[0].push(uv);\n                    dstUv[1].push(uv);\n                }\n                wasLeft = isLeft;\n            }\n            (isLeft ? left : right).push(p);\n            if (srcUv && dstUv) {\n                (isLeft ? dstUv[0] : dstUv[1]).push(srcUv[index]);\n            }\n            prev = p;\n        });\n        return [\n            left.length ? new Polygon(left) : null,\n            right.length ? new Polygon(right) : null,\n        ];\n    }\n    serialize(): any {\n        return { Polygon: { pts: this.pts.map(p => p.serialize()) } };\n    }\n    support(direction: Vec2): Vec2 {\n        let maxPoint = this.pts[0];\n        let maxDistance = maxPoint.dot(direction);\n\n        let vertex;\n        for (let i = 1; i < this.pts.length; i++) {\n            vertex = this.pts[i];\n            const distance = vertex.dot(direction);\n            if (distance > maxDistance) {\n                maxDistance = distance;\n                maxPoint = vertex;\n            }\n        }\n\n        return maxPoint;\n    }\n    get gjkCenter(): Vec2 {\n        return this.pts[0];\n    }\n    /* Calculates the point on the polygon (not just vertex)\n     * closest to the given point.\n     **/\n    closestPt(p: Vec2): Vec2 | undefined {\n        // Edge points\n        let p1 = this.pts.at(-1)!, p2;\n        // Vector from point to edge and edge vector\n        let v1 = new Vec2(), v2 = new Vec2();\n        // Projected point\n        let pp;\n        // Closest point and closest (squared) distance if any\n        let c, cd;\n        // For all edges\n        for (let i = 0; i < this.pts.length; i++) {\n            p2 = this.pts[i];\n            // Calculate aforementioned vectors\n            Vec2.sub(p, p1, v1);\n            Vec2.sub(p2, p1, v2);\n            // Calculate scalar projection\n            const t = v1.dot(v2) / v2.dot(v2);\n            // If on edge segment\n            if (t >= 0 && t <= 1) {\n                // Calculate projected point on edge\n                pp = p1.add(v2.scale(t));\n                // Calculate squared distance\n                const d = Vec2.sdist(p, pp);\n                if (c === undefined || d < cd!) {\n                    // Update closest point\n                    c = pp;\n                    cd = d;\n                }\n            }\n            // If not, check the vertex itself\n            else {\n                const d = Vec2.sdist(p, p2);\n                if (c === undefined || d < cd!) {\n                    c = p2;\n                    cd = d;\n                }\n            }\n            p1 = p2;\n        }\n        return c;\n    }\n}\n\nexport function shapeFactory(data: any): Shape {\n    const type = Object.keys(data)[0];\n    const d = data[type];\n    switch (type) {\n        case \"Point\":\n            return new Point(Vec2.deserialize(d.pt));\n        case \"Line\":\n            return new Line(Vec2.deserialize(d.p1), Vec2.deserialize(d.p2));\n        case \"Rect\":\n            return new Rect(Vec2.deserialize(d.pos), d.width, d.height);\n        case \"Circle\":\n            return new Circle(Vec2.deserialize(d.pos), d.radius);\n        case \"Ellipse\":\n            return new Ellipse(\n                Vec2.deserialize(d.pos),\n                d.radiusX,\n                d.radiusY,\n                d.angle,\n            );\n        case \"Polygon\":\n            return new Polygon(data.pts.map((p: any) => Vec2.deserialize(p)));\n    }\n    throw new Error(`Unknown shape type ${type} in serialized data`);\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 *\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 *\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 *\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 *\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 *\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 *\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/**\n * A second order function returning an evaluator for a piecewise cubic B\u00E9zier\n * @param pts - A series of points with 2 control points between each pair of points\n *\n * @returns A function which evaluates a piecewise cubic B\u00E9zier\n */\nexport function piecewiseBezier(pts: Vec2[]) {\n    // tuples with [from s, to s, from px, to px, bezier, curve length]\n    const beziers: [\n        number,\n        number,\n        number,\n        number,\n        (t: number) => Vec2,\n        (t: number, b: boolean) => number,\n    ][] = [];\n    let totalLength = 0;\n    for (let i = 0; i < pts.length - 3; i += 3) {\n        const bezierCurve = bezier(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]);\n        const curveLength = curveLengthApproximation(bezierCurve);\n        const length = curveLength(1);\n        const fromLength = totalLength;\n        const toLength = totalLength += length;\n        beziers.push([\n            fromLength,\n            toLength,\n            fromLength,\n            toLength,\n            bezierCurve,\n            curveLength,\n        ]);\n    }\n\n    for (let i = 0; i < beziers.length; i++) {\n        beziers[i][0] /= totalLength;\n        beziers[i][1] /= totalLength;\n    }\n\n    return (s: number) => {\n        for (let i = 0; i < beziers.length; i++) {\n            const b = beziers[i];\n            if (s < b[1]) {\n                s = map(s, b[0], b[1], 0, 1);\n                const l = s * (b[3] - b[2]);\n                const t = b[5](l, true);\n                return b[4](t);\n            }\n        }\n        return beziers[beziers.length - 1][4](1);\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 *\n * @returns Reflected point\n */\nfunction reflect(a: Vec2, b: Vec2) {\n    return b.add(b.sub(a));\n}\n\n/**\n * A second order function returning an evaluator for a piecewise Catmull-Rom curve\n * @param pts - A series of points the curve should go through\n *\n * @returns A function which evaluates a piecewise Catmull-Rom curve\n */\nexport function piecewiseCatmullRom(pts: Vec2[]) {\n    // tuples with [from s, to s, from px, to px, bezier, curve length]\n    const curves: [\n        number,\n        number,\n        number,\n        number,\n        (t: number) => Vec2,\n        (t: number, b: boolean) => number,\n    ][] = [];\n    let totalLength = 0;\n    const addCurve = (pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2) => {\n        const curve = catmullRom(pt1, pt2, pt3, pt4);\n        const curveLength = curveLengthApproximation(curve);\n        const length = curveLength(1);\n        const fromLength = totalLength;\n        const toLength = totalLength += length;\n        curves.push([\n            fromLength,\n            toLength,\n            fromLength,\n            toLength,\n            curve,\n            curveLength,\n        ]);\n    };\n    const firstPt = reflect(pts[1], pts[0]);\n    addCurve(firstPt, pts[0], pts[1], pts[2]);\n    for (let i = 0; i < pts.length - 3; i++) {\n        addCurve(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]);\n    }\n    const lastPt = reflect(pts[pts.length - 2], pts[pts.length - 1]);\n    addCurve(\n        pts[pts.length - 3],\n        pts[pts.length - 2],\n        pts[pts.length - 1],\n        lastPt,\n    );\n\n    for (let i = 0; i < curves.length; i++) {\n        curves[i][0] /= totalLength;\n        curves[i][1] /= totalLength;\n    }\n\n    return (s: number) => {\n        for (let i = 0; i < curves.length; i++) {\n            const b = curves[i];\n            if (s < b[1]) {\n                s = map(s, b[0], b[1], 0, 1);\n                const l = s * (b[3] - b[2]);\n                const t = b[5](l, true);\n                return b[4](t);\n            }\n        }\n        return curves[curves.length - 1][4](1);\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\n/**\n * @group Math\n * @subgroup Tween\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\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 = i;\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", "import { Quad } from \"../math/math\";\nimport { _k } from \"../shared\";\nimport type { ImageSource } from \"../types\";\nimport { isDataURL } from \"../utils/dataURL\";\n\nexport function fixURL<D>(url: D): D {\n    if (typeof url == \"string\" && window.kaplayjs_assetsAliases[url]) {\n        url = (window.kaplayjs_assetsAliases[url] as unknown) as D;\n    }\n\n    if (typeof url !== \"string\" || isDataURL(url)) return url;\n    return _k.assets.urlPrefix + url as D;\n}\n\nexport function drawImageSourceAt(\n    c2d: CanvasRenderingContext2D,\n    src: ImageSource,\n    atX: number,\n    atY: number,\n    cutX: number,\n    cutY: number,\n    cutWidth: number,\n    cutHeight: number,\n) {\n    if (src instanceof ImageData) {\n        c2d.putImageData(src, atX, atY, cutX, cutY, cutWidth, cutHeight);\n    }\n    else {\n        c2d.drawImage(\n            src,\n            cutX,\n            cutY,\n            cutWidth,\n            cutHeight,\n            atX,\n            atY,\n            cutWidth,\n            cutHeight,\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(new Quad(dx + i * qw, dy + j * qh, qw, qh));\n        }\n    }\n    return frames;\n}\n", "import { deg2rad, rad2deg } from \"./math\";\nimport { Vec2 } from \"./Vec2\";\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", "import { Mat4 } from \"../math/Mat4\";\nimport { Vec2 } from \"../math/Vec2\";\n\nexport const IDENTITY_MATRIX = new Mat4();\nexport const TOP_LEFT = new Vec2(-1, -1);\nexport const TOP = new Vec2(0, -1);\nexport const TOP_RIGHT = new Vec2(1, -1);\nexport const LEFT = new Vec2(-1, 0);\nexport const CENTER = new Vec2(0, 0);\nexport const RIGHT = new Vec2(1, 0);\nexport const BOTTOM_LEFT = new Vec2(-1, 1);\nexport const BOTTOM = new Vec2(0, 1);\nexport const BOTTOM_RIGHT = new Vec2(1, 1);\n", "import { Color, type ColorArgs, rgb, type RGBValue } from \"../../../math/color\";\nimport type { Comp } from \"../../../types\";\n\n/**\n * The serialized {@link color `color()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedColorComp {\n    color: { r: number; g: number; b: number };\n}\n\n/**\n * The {@link color `color()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface ColorComp extends Comp {\n    color: Color;\n    serialize(): SerializedColorComp;\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        serialize() {\n            return {\n                color: this.color.serialize(),\n            };\n        },\n    };\n}\n\nexport function colorFactory(data: any) {\n    return color(Color.deserialize(data));\n}\n", "/**\n * The list of easing functions available.\n *\n * @group Math\n * @subgroup Tween\n */\nexport type EaseFuncs =\n    | \"linear\"\n    | \"easeInSine\"\n    | \"easeOutSine\"\n    | \"easeInOutSine\"\n    | \"easeInQuad\"\n    | \"easeOutQuad\"\n    | \"easeInOutQuad\"\n    | \"easeInCubic\"\n    | \"easeOutCubic\"\n    | \"easeInOutCubic\"\n    | \"easeInQuart\"\n    | \"easeOutQuart\"\n    | \"easeInOutQuart\"\n    | \"easeInQuint\"\n    | \"easeOutQuint\"\n    | \"easeInOutQuint\"\n    | \"easeInExpo\"\n    | \"easeOutExpo\"\n    | \"easeInOutExpo\"\n    | \"easeInCirc\"\n    | \"easeOutCirc\"\n    | \"easeInOutCirc\"\n    | \"easeInBack\"\n    | \"easeOutBack\"\n    | \"easeInOutBack\"\n    | \"easeInElastic\"\n    | \"easeOutElastic\"\n    | \"easeInOutElastic\"\n    | \"easeInBounce\"\n    | \"easeOutBounce\"\n    | \"easeInOutBounce\";\n\n/**\n * A function that takes a time value and returns a new time value.\n *\n * @group Math\n * @subgroup Tween\n */\nexport type EaseFunc = (t: number) => number;\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\nexport const 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", "export function toFixed(n: number, f: number) {\n    return Number(n.toFixed(f));\n}\n", "import { type EaseFunc, easings } from \"../../../math/easings\";\nimport { _k } from \"../../../shared\";\nimport type { Comp } from \"../../../types\";\nimport { toFixed } from \"../../../utils/numbers\";\nimport type { TweenController } from \"../misc/timer\";\n\n/**\n * The serialized {@link opacity `opacity()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedOpacityComp {\n    opacity: number;\n}\n\n/**\n * The {@link opacity `opacity()`} component.\n *\n * @group Components\n * @subgroup 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    serialize(): SerializedOpacityComp;\n}\n\nexport function opacity(a: number): OpacityComp {\n    return {\n        id: \"opacity\",\n        opacity: a ?? 1,\n        fadeIn(time = 1, easeFunc = easings.linear): TweenController {\n            const toValue = this.opacity;\n            this.opacity = 0;\n            return _k.game.root.tween(\n                0,\n                toValue,\n                time,\n                (a) => this.opacity = a,\n                easeFunc,\n            );\n        },\n        fadeOut(time = 1, easeFunc = 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        serialize() {\n            return { opacity: this.opacity };\n        },\n    };\n}\n\nexport function opacityFactory(data: SerializedOpacityComp) {\n    return opacity(data.opacity);\n}\n", "import type { GameObj } from \"../types\";\n\n// Note: I will doom this soon \uD83D\uDE08\uD83D\uDE08\uD83D\uDE08\uD83D\uDE08\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        blend: obj.blend,\n    };\n}\n", "import type { GameObj } from \"../types\";\nimport { deg2rad, Mat23, vec2 } from \"./math\";\nimport { Vec2 } from \"./Vec2\";\n\nexport function calcTransform(obj: GameObj, tr: Mat23): Mat23 {\n    if (obj.parent) {\n        tr.setMat23(obj.parent.transform);\n    }\n    else {\n        tr.setIdentity();\n    }\n    if (obj.pos) tr.translateSelfV(obj.pos);\n    if (obj.angle) tr.rotateSelf(obj.angle);\n    if (obj.scale) tr.scaleSelfV(obj.scale);\n    return tr;\n}\n\nexport function updateTransformRecursive(obj: GameObj) {\n    calcTransform(obj, obj.transform);\n    for (let i = 0; i < obj.children.length; i++) {\n        updateTransformRecursive(obj.children[i]);\n    }\n}\n\nexport function updateChildrenTransformRecursive(obj: GameObj) {\n    for (let i = 0; i < obj.children.length; i++) {\n        updateTransformRecursive(obj.children[i]);\n    }\n}\n\nexport function clampAngle(angle: number) {\n    angle = angle % 360;\n    if (angle < -180) {\n        angle += 360;\n    }\n    else if (angle > 180) {\n        angle -= 360;\n    }\n    return angle;\n}\n\n// convert a screen space coordinate to webgl normalized device coordinate\nexport function screen2ndc(pt: Vec2, width: number, height: number, out: Vec2) {\n    out.x = pt.x / width * 2 - 1;\n    out.y = -pt.y / height * 2 + 1;\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    const isLoop = (end - start) == 0;\n    if (end <= start) end += Math.PI * 2;\n\n    const pts: Vec2[] = [];\n    const nverts = Math.round(\n        Math.sqrt(((radiusX + radiusY) / 2) * 20) * (end - start) / Math.PI * 2,\n    ); // 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        v = vec2(v.x * r.x - v.y * r.y, v.x * r.y + v.y * r.x);\n    }\n\n    // Make sure the endpoints match if it is a loop\n    if (isLoop) {\n        pts[pts.length - 1].x = pts[0].x;\n        pts[pts.length - 1].y = pts[0].y;\n    }\n\n    return pts;\n}\n", "import {\n    BOTTOM,\n    BOTTOM_LEFT,\n    BOTTOM_RIGHT,\n    CENTER,\n    LEFT,\n    RIGHT,\n    TOP,\n    TOP_LEFT,\n    TOP_RIGHT,\n} from \"../constants/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport { type Anchor } from \"../types\";\nimport type { TextAlign } from \"./draw/drawText\";\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", "import type { Uniform } from \"../assets/shader\";\nimport { type Mat23, vec2 } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport { _k } from \"../shared\";\n\nexport function pushTransform() {\n    _k.gfx.transformStack[++_k.gfx.transformStackIndex].setMat23(\n        _k.gfx.transform,\n    );\n}\n\nexport function popTransform() {\n    if (_k.gfx.transformStackIndex >= 0) {\n        _k.gfx.transform.setMat23(\n            _k.gfx.transformStack[_k.gfx.transformStackIndex--],\n        );\n    }\n}\n\nexport function pushMatrix(m: Mat23) {\n    pushTransform();\n    loadMatrix(m);\n}\n\nexport function multTranslateV(t: Vec2 | undefined) {\n    if (t === undefined) return;\n    if (t.x === 0 && t.y === 0) return;\n    _k.gfx.transform.translateSelfV(t);\n}\n\nexport function multTranslate(x: number, y: number) {\n    if (x === 0 && y === 0) return;\n    _k.gfx.transform.translateSelf(x, y);\n}\n\nexport function multRotate(angle: number | undefined) {\n    if (!angle) return;\n    _k.gfx.transform.rotateSelf(angle);\n}\n\nexport function multScaleV(s: Vec2 | undefined) {\n    if (s === undefined) return;\n    if (s.x === 1 && s.y === 1) return;\n    _k.gfx.transform.scaleSelfV(s);\n}\n\nexport function multScale(x: number, y: number) {\n    if (x === 1 && y === 1) return;\n    _k.gfx.transform.scaleSelf(x, y);\n}\n\nexport function multSkewV(s: Vec2 | undefined) {\n    if (s === undefined) return;\n    if (s.x === 0 && s.y === 0) return;\n    _k.gfx.transform.skewSelfV(s);\n}\n\nexport function multSkew(x: number, y: number) {\n    if (x === 0 && y === 0) return;\n    _k.gfx.transform.skewSelf(x, y);\n}\n\nexport function loadIdentity() {\n    _k.gfx.transform.setIdentity();\n}\n\nexport function loadMatrix(m: Mat23) {\n    _k.gfx.transform.setMat23(m);\n}\n\nexport function storeMatrix(m: Mat23) {\n    m.setMat23(_k.gfx.transform);\n}\n\nexport function flush() {\n    _k.gfx.renderer.flush(width(), height());\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 center(): Vec2 {\n    return vec2(_k.gfx.width / 2, _k.gfx.height / 2);\n}\n\nexport const usePostEffect = (\n    name: string,\n    uniform?: Uniform | (() => Uniform),\n) => {\n    _k.gfx.postShader = name;\n    _k.gfx.postShaderUniform = uniform ?? null;\n};\n", "import { Color } from \"../math/color\";\nimport { Vec2 } from \"../math/Vec2\";\n\nexport function arrayIsColor(arr: unknown[]): arr is Color[] {\n    return arr[0] instanceof Color;\n}\n\nexport function arrayIsVec2(arr: unknown[]): arr is Vec2[] {\n    return arr[0] instanceof Vec2;\n}\n\nexport function arrayIsNumber(arr: unknown[]): arr is number[] {\n    return typeof arr[0] === \"number\";\n}\n", "import { _k } from \"../shared\";\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 (!_k.game.warned.has(msg)) {\n        _k.game.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", "import {\n    DEF_FRAG,\n    DEF_VERT,\n    FRAG_TEMPLATE,\n    VERT_TEMPLATE,\n    VERTEX_FORMAT,\n} from \"../constants/general\";\nimport { type GfxCtx, Texture } from \"../gfx/gfx\";\nimport { Color } from \"../math/color\";\nimport { Mat4 } from \"../math/Mat4\";\nimport { Mat23 } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport { _k } from \"../shared\";\nimport type { RenderProps } from \"../types\";\nimport { arrayIsColor, arrayIsNumber, arrayIsVec2 } from \"../utils/asserts\";\nimport { getErrorMessage } from \"../utils/log\";\nimport { fetchText, loadProgress } from \"./asset\";\nimport { Asset } from \"./asset\";\nimport { fixURL } from \"./utils\";\n\nclass TextureUnitManager {\n    private static textureMap = new Map<Texture, number>();\n    private static maxUnit = 1;\n\n    constructor() {}\n\n    static getUnitForTexture(texture: Texture): number {\n        let unit = TextureUnitManager.textureMap.get(texture);\n\n        if (unit === undefined) {\n            // Assign new unit\n            unit = TextureUnitManager.maxUnit++;\n\n            // Check if this unit is actually available\n            const gl = _k.gfx.gl;\n            if (gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS) < unit) {\n                throw new Error(\n                    \"Using too many concurrent textures. Try to use less additional textures as uniforms\",\n                );\n            }\n\n            // Assign texture to unit\n            gl.activeTexture(gl.TEXTURE0 + unit);\n            gl.bindTexture(gl.TEXTURE_2D, texture.glTex);\n            gl.activeTexture(gl.TEXTURE0);\n\n            // Remember location\n            TextureUnitManager.textureMap.set(texture, unit);\n        }\n\n        return unit;\n    }\n}\n\n/**\n * @group Assets\n * @subgroup Data\n */\nexport type ShaderData = Shader;\n\n/**\n * Possible values for a shader Uniform.\n *\n * @group Rendering\n * @subgroup Shaders\n */\nexport type UniformValue =\n    | number\n    | Vec2\n    | Color\n    | Mat4\n    | Mat23\n    | number[]\n    | Vec2[]\n    | Color[]\n    | Texture;\n\n/**\n * Possible uniform value, basically any but \"u_tex\".\n *\n * @group Rendering\n * @subgroup Shaders\n */\nexport type UniformKey = string;\n\n/**\n * @group Rendering\n * @subgroup Shaders\n */\nexport type Uniform = Record<UniformKey, UniformValue>;\n\n/**\n * A shader, yeah.\n *\n * @group Rendering\n * @subgroup Shaders\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        this.glProgram = this.compile(vert, frag, attribs);\n    }\n\n    compile(vert: string, frag: string, attribs: string[]) {\n        const gl = this.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\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            const linkError = gl.getProgramInfoLog(prog!);\n            if (linkError) throw new Error(\"LINK ERROR: \" + linkError);\n            throw new Error(\"Unknown shader error (gl.LINK_STATUS was false)\");\n        }\n\n        gl.deleteShader(vertShader);\n        gl.deleteShader(fragShader);\n\n        return prog!;\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 of Object.keys(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 Mat23) {\n                gl.uniformMatrix4fv(\n                    loc,\n                    false,\n                    new Float32Array([\n                        val.a,\n                        val.b,\n                        0,\n                        0,\n                        val.c,\n                        val.d,\n                        0,\n                        0,\n                        0,\n                        0,\n                        1,\n                        0,\n                        val.e,\n                        val.f,\n                        0,\n                        1,\n                    ]),\n                );\n                // console.log(val)\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 (val instanceof Texture) {\n                gl.uniform1i(loc, TextureUnitManager.getUnitForTexture(val));\n            }\n            else if (Array.isArray(val)) {\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                console.error(\n                    \"unknown data passed to Shader.send:\",\n                    val,\n                    \"(key: \" + name + \")\",\n                );\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 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);\n        const msg = match.groups.msg.trim();\n        const ty = match.groups.type.toLowerCase();\n        const lines = (ty == \"vertex\" ? vcode : fcode).split(\"\\n\");\n        const lineContents = lines[line - 1];\n        throw new Error(`${ty} shader line ${line}: ${msg}\\n${lineContents}`);\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 { Asset } from \"../../assets/asset\";\nimport { resolveShader, type Uniform } from \"../../assets/shader\";\nimport { _k } from \"../../shared\";\nimport { type Attributes, BlendMode, type RenderProps } from \"../../types\";\nimport type { Texture } from \"../gfx\";\nimport { height, width } from \"../stack\";\n\nexport function drawRaw(\n    attributes: Attributes,\n    indices: number[],\n    fixed: boolean = false,\n    tex?: Texture,\n    shaderSrc?: RenderProps[\"shader\"],\n    uniform?: Uniform,\n    blend?: BlendMode,\n) {\n    const parsedTex = tex ?? _k.gfx.whitePixel.tex;\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.transform;\n\n    const vertLength = attributes.pos.length / 2;\n    const vv: number[] = new Array(vertLength * 8);\n\n    let index = 0;\n    for (let i = 0; i < vertLength; i++) {\n        _k.gfx.scratchPt.x = attributes.pos[i * 2];\n        _k.gfx.scratchPt.y = attributes.pos[i * 2 + 1];\n        transform.transformPointV(_k.gfx.scratchPt, _k.gfx.scratchPt);\n\n        vv[index++] = _k.gfx.scratchPt.x;\n        vv[index++] = _k.gfx.scratchPt.y;\n        vv[index++] = attributes.uv[i * 2];\n        vv[index++] = attributes.uv[i * 2 + 1];\n        vv[index++] = attributes.color[i * 3] / 255;\n        vv[index++] = attributes.color[i * 3 + 1] / 255;\n        vv[index++] = attributes.color[i * 3 + 2] / 255;\n        vv[index++] = attributes.opacity[i];\n    }\n\n    _k.gfx.renderer.push(\n        _k.gfx.ggl.gl.TRIANGLES,\n        vv,\n        indices,\n        shader,\n        parsedTex,\n        uniform,\n        blend ?? BlendMode.Normal,\n        width(),\n        height(),\n        _k.gfx.fixed || fixed,\n    );\n}\n", "import { Color } from \"../../math/color\";\nimport { lerp } from \"../../math/lerp\";\nimport { deg2rad, vec2 } from \"../../math/math\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport { _k } from \"../../shared\";\nimport type { RenderProps } from \"../../types\";\nimport { drawRaw } from \"./drawRaw\";\n\n/**\n * How the line should look like.\n *\n * @group Draw\n * @subgroup Types\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(1),\n        color: opt.color ?? Color.WHITE,\n        opacity: opt.opacity ?? 1,\n    }));*/\n\n    const color = opt.color ?? Color.WHITE;\n    const opacity = opt.opacity ?? 1;\n\n    const attributes = {\n        pos: [\n            p1.x - dis.x,\n            p1.y - dis.y,\n            p1.x + dis.x,\n            p1.y + dis.y,\n            p2.x + dis.x,\n            p2.y + dis.y,\n            p2.x - dis.x,\n            p2.y - dis.y,\n        ],\n        uv: [\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n        ],\n        color: [\n            color.r,\n            color.g,\n            color.b,\n            color.r,\n            color.g,\n            color.b,\n            color.r,\n            color.g,\n            color.b,\n            color.r,\n            color.g,\n            color.b,\n        ],\n        opacity: [\n            opacity,\n            opacity,\n            opacity,\n            opacity,\n        ],\n    };\n\n    drawRaw(\n        attributes,\n        [0, 1, 3, 1, 2, 3],\n        opt.fixed,\n        _k.gfx.whitePixel.tex,\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     * Line bias, the position of the line relative to its center (default 0).\n     */\n    bias?: number;\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 centerOffset = halfWidth\n        * lerp(-1, 1, ((opt.bias || 0.0) + 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(1 / 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(\n                    pt2.add(dir).add(normal.scale(centerOffset - halfWidth)),\n                );\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset + halfWidth)),\n                );\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(halfWidth);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                const p = pt2.add(normal.scale(centerOffset));\n                for (let j = 0; j < n; j++) {\n                    vertices.push(p);\n                    vertices.push(p.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(1 / nextLength);\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.scale(centerOffset - halfWidth)));\n            vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n\n            if (segment.dot(nextSegment) < 0) {\n                vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n                vertices.push(pt1.add(normal.scale(centerOffset - halfWidth)));\n            }\n\n            segment = nextSegment;\n            length = nextLength;\n            normal = nextNormal;\n            continue;\n        }\n\n        if (det > 0) {\n            const lambda = (nextNormal.scale(centerOffset - halfWidth).sub(\n                normal.scale(centerOffset - halfWidth),\n            )).cross(nextSegment) / det;\n            const d = normal.scale(centerOffset - halfWidth).add(\n                segment.scale(lambda),\n            );\n\n            vertices.push(pt1.add(d));\n            vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n            vertices.push(pt1.add(d));\n            vertices.push(pt1.add(nextNormal.scale(centerOffset + halfWidth)));\n        }\n        else {\n            const lambda = (nextNormal.scale(centerOffset + halfWidth).sub(\n                normal.scale(centerOffset + halfWidth),\n            )).cross(nextSegment) / det;\n            const d = normal.scale(centerOffset + halfWidth).add(\n                segment.scale(lambda),\n            );\n\n            vertices.push(pt1.add(normal.scale(centerOffset - halfWidth)));\n            vertices.push(pt1.add(d));\n            vertices.push(pt1.add(nextNormal.scale(centerOffset - halfWidth)));\n            vertices.push(pt1.add(d));\n        }\n\n        segment = nextSegment;\n        length = nextLength;\n        normal = nextNormal;\n    }\n\n    if (!isLoop) {\n        vertices.push(pt2.add(normal.scale(centerOffset - halfWidth)));\n        vertices.push(pt2.add(normal.scale(centerOffset + halfWidth)));\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(halfWidth / length);\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset - halfWidth)),\n                );\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset + halfWidth)),\n                );\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(halfWidth);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                const p = pt2.add(normal.scale(centerOffset));\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(p);\n                    vertices.push(p.add(vector));\n                }\n            }\n        }\n    }\n\n    if (vertices.length < 4) return;\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    /*const verts = vertices.map(v => ({\n        pos: offset.add(v),\n        uv: vec2(1),\n        color: opt.color || Color.WHITE,\n        opacity: opt.opacity ?? 1,\n    }));*/\n\n    const attributes = {\n        pos: new Array<number>(vertices.length * 2),\n        uv: new Array<number>(vertices.length * 2).fill(1),\n        color: new Array<number>(vertices.length * 3).fill(255),\n        opacity: new Array<number>(vertices.length).fill(opt.opacity ?? 1),\n    };\n\n    for (let i = 0; i < vertices.length; i++) {\n        attributes.pos[i * 2] = vertices[i].x + offset.x;\n        attributes.pos[i * 2 + 1] = vertices[i].y + offset.y;\n        if (opt.color) {\n            attributes.color[i * 3] = opt.color.r;\n            attributes.color[i * 3 + 1] = opt.color.g;\n            attributes.color[i * 3 + 2] = opt.color.b;\n        }\n    }\n\n    drawRaw(\n        attributes,\n        indices,\n        opt.fixed,\n        _k.gfx.whitePixel.tex,\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 centerOffset = halfWidth * lerp(-1, 1, ((opt.bias || 0.0) + 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(1 / 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(\n                    pt2.add(dir).add(normal.scale(centerOffset - halfWidth)),\n                );\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset + halfWidth)),\n                );\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(halfWidth);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                const p = pt2.add(normal.scale(centerOffset));\n                for (let j = 0; j < n; j++) {\n                    vertices.push(p);\n                    vertices.push(p.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(1 / nextLength);\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.scale(centerOffset - halfWidth)));\n            vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n\n            if (segment.dot(nextSegment) < 0) {\n                vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n                vertices.push(pt1.add(normal.scale(centerOffset - halfWidth)));\n            }\n\n            segment = nextSegment;\n            length = nextLength;\n            normal = nextNormal;\n            continue;\n        }\n\n        if (det > 0) {\n            // Calculate the vector d from pt1 towards the intersection of the offset lines on the inner side\n            const lambda = (nextNormal.scale(centerOffset - halfWidth).sub(\n                normal.scale(centerOffset - halfWidth),\n            )).cross(nextSegment) / det;\n            const d = normal.scale(centerOffset - halfWidth).add(\n                segment.scale(lambda),\n            );\n\n            const n = Math.max(halfWidth, 10);\n            const angle = deg2rad(normal.angleBetween(nextNormal) / n);\n            let vector = normal.scale(halfWidth * 2);\n            const fixedPoint = pt1.add(d);\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(fixedPoint.add(vector));\n                vector = vec2(\n                    vector.x * cs - vector.y * sn,\n                    vector.x * sn + vector.y * cs,\n                );\n            }\n        }\n        else {\n            // Calculate the vector d from pt1 towards the intersection of the offset lines on the inner side\n            const lambda = (nextNormal.scale(centerOffset + halfWidth).sub(\n                normal.scale(centerOffset + halfWidth),\n            )).cross(nextSegment) / det;\n            const d = normal.scale(centerOffset + halfWidth).add(\n                segment.scale(lambda),\n            );\n\n            const n = Math.max(halfWidth, 10);\n            const angle = deg2rad(normal.angleBetween(nextNormal) / n);\n            let vector = normal.scale(halfWidth * 2);\n            const fixedPoint = pt1.add(d);\n            const cs = Math.cos(angle);\n            const sn = Math.sin(angle);\n            for (let j = 0; j < n; j++) {\n                vertices.push(fixedPoint.sub(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.scale(centerOffset - halfWidth)));\n        vertices.push(pt2.add(normal.scale(centerOffset + halfWidth)));\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(halfWidth / length);\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset - halfWidth)),\n                );\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset + halfWidth)),\n                );\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(halfWidth);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                const p = pt2.add(normal.scale(centerOffset));\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(p);\n                    vertices.push(p.add(vector));\n                }\n            }\n        }\n    }\n\n    if (vertices.length < 4) return;\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    const attributes = {\n        pos: new Array<number>(vertices.length * 2),\n        uv: new Array<number>(vertices.length * 2).fill(1),\n        color: new Array<number>(vertices.length * 3).fill(255),\n        opacity: new Array<number>(vertices.length).fill(opt.opacity ?? 1),\n    };\n\n    for (let i = 0; i < vertices.length; i++) {\n        attributes.pos[i * 2] = vertices[i].x + offset.x;\n        attributes.pos[i * 2 + 1] = vertices[i].y + offset.y;\n        if (opt.color) {\n            attributes.color[i * 3] = opt.color.r;\n            attributes.color[i * 3 + 1] = opt.color.g;\n            attributes.color[i * 3 + 2] = opt.color.b;\n        }\n    }\n\n    drawRaw(\n        attributes,\n        indices,\n        opt.fixed,\n        _k.gfx.whitePixel.tex,\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 centerOffset = halfWidth * lerp(-1, 1, ((opt.bias || 0.0) + 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(1 / 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(\n                    pt2.add(dir).add(normal.scale(centerOffset - halfWidth)),\n                );\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset + halfWidth)),\n                );\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(halfWidth);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                const p = pt2.add(normal.scale(centerOffset));\n                for (let j = 0; j < n; j++) {\n                    vertices.push(p);\n                    vertices.push(p.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(1 / nextLength);\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.scale(centerOffset - halfWidth)));\n            vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n\n            if (segment.dot(nextSegment) < 0) {\n                vertices.push(pt1.add(normal.scale(centerOffset + halfWidth)));\n                vertices.push(pt1.add(normal.scale(centerOffset - halfWidth)));\n            }\n\n            segment = nextSegment;\n            length = nextLength;\n            normal = nextNormal;\n            continue;\n        }\n\n        let lambda = (nextNormal.scale(centerOffset - halfWidth).sub(\n            normal.scale(centerOffset - halfWidth),\n        )).cross(nextSegment) / det;\n        let d = normal.scale(centerOffset - halfWidth).add(\n            segment.scale(lambda),\n        );\n        vertices.push(pt1.add(d));\n\n        lambda = (nextNormal.scale(centerOffset + halfWidth).sub(\n            normal.scale(centerOffset + halfWidth),\n        )).cross(nextSegment) / det;\n        d = normal.scale(centerOffset + halfWidth).add(segment.scale(lambda));\n        vertices.push(pt1.add(d));\n\n        segment = nextSegment;\n        length = nextLength;\n        normal = nextNormal;\n    }\n\n    if (!isLoop) {\n        vertices.push(pt2.add(normal.scale(centerOffset - halfWidth)));\n        vertices.push(pt2.add(normal.scale(centerOffset + halfWidth)));\n        switch (opt.cap) {\n            case \"square\": {\n                const dir = segment.scale(halfWidth / length);\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset - halfWidth)),\n                );\n                vertices.push(\n                    pt2.add(dir).add(normal.scale(centerOffset + halfWidth)),\n                );\n                break;\n            }\n            case \"round\": {\n                const n = Math.max(halfWidth, 10);\n                const angle = Math.PI / n;\n                let vector = normal.scale(halfWidth);\n                const cs = Math.cos(angle);\n                const sn = Math.sin(angle);\n                const p = pt2.add(normal.scale(centerOffset));\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(p);\n                    vertices.push(p.add(vector));\n                }\n            }\n        }\n    }\n\n    if (vertices.length < 4) return;\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    const attributes = {\n        pos: new Array<number>(vertices.length * 2),\n        uv: new Array<number>(vertices.length * 2).fill(1),\n        color: new Array<number>(vertices.length * 3).fill(255),\n        opacity: new Array<number>(vertices.length).fill(opt.opacity ?? 1),\n    };\n\n    for (let i = 0; i < vertices.length; i++) {\n        attributes.pos[i * 2] = vertices[i].x + offset.x;\n        attributes.pos[i * 2 + 1] = vertices[i].y + offset.y;\n        if (opt.color) {\n            attributes.color[i * 3] = opt.color.r;\n            attributes.color[i * 3 + 1] = opt.color.g;\n            attributes.color[i * 3 + 2] = opt.color.b;\n        }\n    }\n\n    drawRaw(\n        attributes,\n        indices,\n        opt.fixed,\n        _k.gfx.whitePixel.tex,\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        return _drawLinesBevel(opt);\n    }\n    else {\n        return _drawLinesRound(opt);\n    }\n}\n", "import { Color } from \"../../math/color\";\nimport { triangulate } from \"../../math/math\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport { _k } from \"../../shared\";\nimport { BlendMode, type RenderProps } from \"../../types\";\nimport type { Texture } from \"../gfx\";\nimport {\n    multRotate,\n    multScaleV,\n    multSkew,\n    multSkewV,\n    multTranslateV,\n    popTransform,\n    pushTransform,\n} from \"../stack\";\nimport { drawLines } from \"./drawLine\";\nimport { drawRaw } from \"./drawRaw\";\n\n/**\n * How the polygon should look like.\n *\n * @group Draw\n * @subgroup Types\n */\nexport type DrawPolygonOpt = RenderProps & {\n    /**\n     * The points that make up the polygon\n     */\n    pts: 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     * Manual triangulation.\n     */\n    indices?: number[];\n    /**\n     * The center point of transformation in relation to the position.\n     */\n    offset?: Vec2;\n    /**\n     * The radius of each corner.\n     */\n    radius?: number | number[];\n    /**\n     * The color of each vertex.\n     *\n     * @since v3000.0\n     */\n    colors?: Color[];\n    /**\n     * The opacity of each vertex.\n     *\n     * @since v4000.0\n     */\n    opacities?: number[];\n    /**\n     * The uv of each vertex.\n     *\n     * @since v3001.0\n     */\n    uv?: Vec2[];\n    /**\n     * The texture if uv are supplied.\n     *\n     * @since v3001.0\n     */\n    tex?: Texture;\n    /**\n     * Triangulate concave polygons.\n     *\n     * @since v3001.0\n     */\n    triangulate?: boolean;\n};\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    multTranslateV(opt.pos);\n    multRotate(opt.angle);\n    multScaleV(opt.scale);\n    multSkewV(opt.skew);\n    multTranslateV(opt.offset);\n\n    if (opt.fill !== false) {\n        const color = opt.color ?? Color.WHITE;\n\n        const attributes = {\n            pos: new Array<number>(opt.pts.length * 2),\n            uv: new Array<number>(opt.pts.length * 2),\n            color: new Array<number>(opt.pts.length * 3),\n            opacity: new Array<number>(opt.pts.length),\n        };\n\n        for (let i = 0; i < opt.pts.length; i++) {\n            attributes.pos[i * 2] = opt.pts[i].x;\n            attributes.pos[i * 2 + 1] = opt.pts[i].y;\n        }\n\n        if (opt.uv) {\n            for (let i = 0; i < opt.uv.length; i++) {\n                attributes.uv[i * 2] = opt.uv[i].x;\n                attributes.uv[i * 2 + 1] = opt.uv[i].y;\n            }\n        }\n        else {\n            attributes.uv.fill(1);\n        }\n\n        if (opt.colors) {\n            for (let i = 0; i < opt.colors.length; i++) {\n                attributes.color[i * 3] = opt.colors[i].r;\n                attributes.color[i * 3 + 1] = opt.colors[i].g;\n                attributes.color[i * 3 + 2] = opt.colors[i].b;\n            }\n        }\n        else {\n            for (let i = 0; i < opt.pts.length; i++) {\n                attributes.color[i * 3] = color.r;\n                attributes.color[i * 3 + 1] = color.g;\n                attributes.color[i * 3 + 2] = color.b;\n            }\n        }\n\n        if (opt.opacities) {\n            for (let i = 0; i < opt.pts.length; i++) {\n                attributes.opacity[i] = opt.opacities[i];\n            }\n        }\n        else {\n            attributes.opacity.fill(opt.opacity ?? 1);\n        }\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(1, 1),\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            attributes,\n            opt.indices ?? indices,\n            opt.fixed,\n            opt.uv ? opt.tex : _k.gfx.whitePixel.tex,\n            opt.shader,\n            opt.uniform ?? undefined,\n            opt.blend ?? BlendMode.Normal,\n        );\n    }\n\n    if (opt.outline) {\n        drawLines({\n            pts: opt.pts[0].eq(opt.pts[opt.pts.length - 1])\n                ? opt.pts\n                : [...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 { DEF_ANCHOR } from \"../../constants/general\";\nimport type { Color } from \"../../math/color\";\nimport { vec2 } from \"../../math/math\";\nimport { getArcPts } from \"../../math/various\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport { drawPolygon } from \"./drawPolygon\";\n\n/**\n * How the rectangle should look like.\n *\n * @group Draw\n * @subgroup Types\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 type { Color } from \"../../math/color\";\nimport { getArcPts } from \"../../math/various\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport { drawPolygon } from \"./drawPolygon\";\n\n/**\n * How the ellipse should look like.\n *\n * @group Draw\n * @subgroup Types\n */\nexport type DrawEllipseOpt = RenderProps & {\n    /**\n     * The horizontal radius.\n     */\n    radiusX: number;\n    /**\n     * The vertical radius.\n     */\n    radiusY: 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 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/Vec2\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport { drawEllipse } from \"./drawEllipse\";\n\n/**\n * How the circle should look like.\n * @group Draw\n * @subgroup Types\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 { DEF_ANCHOR } from \"../../constants/general\";\nimport { Color } from \"../../math/color\";\nimport { Quad } from \"../../math/math\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport { type Anchor, BlendMode, type RenderProps } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport type { Texture } from \"../gfx\";\nimport {\n    multRotate,\n    multScaleV,\n    multSkewV,\n    multTranslate,\n    multTranslateV,\n    popTransform,\n    pushTransform,\n} from \"../stack\";\nimport { drawRaw } from \"./drawRaw\";\n\n/**\n * How the UV Quad should look like.\n *\n * @group Draw\n * @subgroup Types\n */\nexport type DrawUVQuadOpt = RenderProps & {\n    /**\n     * Width of the UV quad.\n     */\n    width: number;\n    /**\n     * Height of the UV quad.\n     */\n    height: number;\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 texture to sample for this quad.\n     */\n    tex?: Texture;\n    /**\n     * The texture sampling area.\n     */\n    quad?: Quad;\n    /**\n     * The anchor point, or the pivot point. Default to \"topleft\".\n     */\n    anchor?: Anchor | Vec2;\n};\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 offsetX = anchor.x * w * -0.5;\n    const offsetY = anchor.y * h * -0.5;\n    const q = opt.quad || new Quad(0, 0, 1, 1);\n    const color = opt.color || Color.WHITE;\n    const opacity = opt.opacity ?? 1;\n\n    pushTransform();\n    multTranslateV(opt.pos);\n    multRotate(opt.angle);\n    multScaleV(opt.scale);\n    multSkewV(opt.skew);\n    multTranslate(offsetX, offsetY);\n\n    drawRaw(\n        {\n            pos: [\n                -w / 2,\n                h / 2,\n                -w / 2,\n                -h / 2,\n                w / 2,\n                -h / 2,\n                w / 2,\n                h / 2,\n            ],\n            uv: [\n                opt.flipX ? q.x + q.w : q.x,\n                opt.flipY ? q.y : q.y + q.h,\n                opt.flipX ? q.x + q.w : q.x,\n                opt.flipY ? q.y + q.h : q.y,\n                opt.flipX ? q.x : q.x + q.w,\n                opt.flipY ? q.y + q.h : q.y,\n                opt.flipX ? q.x : q.x + q.w,\n                opt.flipY ? q.y : q.y + q.h,\n            ],\n            color: [\n                color.r,\n                color.g,\n                color.b,\n                color.r,\n                color.g,\n                color.b,\n                color.r,\n                color.g,\n                color.b,\n                color.r,\n                color.g,\n                color.b,\n            ],\n            opacity: [\n                opacity,\n                opacity,\n                opacity,\n                opacity,\n            ],\n        },\n        [0, 1, 3, 1, 2, 3],\n        opt.fixed,\n        opt.tex,\n        opt.shader,\n        opt.uniform ?? undefined,\n        opt.blend ?? BlendMode.Normal,\n    );\n\n    popTransform();\n}\n", "import type { FontData } from \"../../assets/font\";\nimport type { Uniform } from \"../../assets/shader\";\nimport { Color } from \"../../math/color\";\nimport type { Vec2 } from \"../../math/Vec2\";\nimport { anchorPt } from \"../anchor\";\nimport type { Texture } from \"../gfx\";\nimport {\n    multRotate,\n    multTranslateV,\n    popTransform,\n    pushTransform,\n} from \"../stack\";\nimport type { Frame } from \"../TexPacker\";\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 *\n * @group Rendering\n * @subgroup Text\n */\nexport type FormattedText = {\n    width: number;\n    height: number;\n    chars: FormattedChar[];\n    opt: DrawTextOpt;\n    renderedText: string;\n};\n\n/**\n * One formatted character.\n *\n * @group Rendering\n * @subgroup Text\n */\nexport interface FormattedChar {\n    ch: string;\n    frame: Frame;\n    width: number;\n    height: number;\n    pos: Vec2;\n    scale: Vec2;\n    skew: Vec2;\n    angle: number;\n    color: Color;\n    opacity: number;\n    font?: string | FontData;\n    stretchInPlace: boolean;\n    shader?: string;\n    uniform?: Uniform;\n}\n\n// cSpell: ignore ftext\nexport function drawFormattedText(ftext: FormattedText) {\n    pushTransform();\n    multTranslateV(ftext.opt.pos!);\n    multRotate(ftext.opt.angle!);\n    multTranslateV(\n        anchorPt(ftext.opt.anchor ?? \"topleft\").add(1, 1).scale(\n            ftext.width,\n            ftext.height,\n        ).scale(-0.5),\n    );\n\n    const charsByTexture = new Map<Texture, FormattedChar[]>();\n\n    ftext.chars.forEach((ch) => {\n        const chars = charsByTexture.get(ch.frame.tex) ?? [];\n        chars.push(ch);\n        charsByTexture.set(ch.frame.tex, chars);\n    });\n\n    const sortedChars = Array.from(charsByTexture.values()).flat();\n\n    sortedChars.forEach((ch) => {\n        drawUVQuad({\n            tex: ch.frame.tex,\n            quad: ch.frame.q,\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            skew: ch.skew,\n            opacity: ch.opacity,\n            anchor: \"center\",\n            uniform: ch.uniform ?? ftext.opt.uniform,\n            shader: ch.shader ?? ftext.opt.shader,\n            fixed: ftext.opt.fixed,\n        });\n    });\n\n    popTransform();\n}\n", "import { ASCII_CHARS } from \"../constants/general\";\nimport type { Frame } from \"../gfx/TexPacker\";\nimport { _k } from \"../shared\";\nimport type { TexFilter } from \"../types\";\nimport { type Asset, loadImg } from \"./asset\";\nimport { makeFont } from \"./font\";\nimport { fixURL } from \"./utils\";\n\n/**\n * @group Assets\n * @subgroup Types\n */\nexport interface GfxFont {\n    map: Record<string, Frame>;\n    size: number;\n    filter: TexFilter;\n}\n\n/**\n * @group Assets\n * @subgroup Data\n */\nexport type BitmapFontData = GfxFont;\n\nexport function getBitmapFont(name: string): Asset<BitmapFontData> | null {\n    return _k.assets.bitmapFonts.get(name) ?? null;\n}\n\n/**\n * @group Assets\n * @subgroup Types\n */\nexport interface LoadBitmapFontOpt {\n    /**\n     * A string of characters to map to every sprite in the characters grid\n     *\n     * @default \" !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\";\n     */\n    chars?: string;\n    /**\n     * Rasterization filter to use, if different than the global font filter.\n     */\n    filter?: TexFilter;\n}\n\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                    img,\n                    gw,\n                    gh,\n                    opt.chars ?? ASCII_CHARS,\n                    opt.filter ?? _k.globalOpt.fontFilter ?? \"nearest\",\n                );\n            }),\n    );\n}\n\nexport function loadBitmapFontFromSprite(\n    spriteID: string,\n    chars: string,\n): Asset<BitmapFontData> {\n    return _k.assets.bitmapFonts.add(\n        spriteID,\n        (async () => {\n            if (/[\\n ]/.test(chars)) {\n                throw new Error(\n                    `While defining sprite font \"${spriteID}\": spaces are not allowed in chars`,\n                );\n            }\n            const splittedChars = chars.split(\"\");\n            if (new Set(splittedChars).size !== splittedChars.length) {\n                throw new Error(\n                    `Duplicate characters given when defining sprite font \"${spriteID}\": ${chars}`,\n                );\n            }\n            const spr = await _k.assets.sprites.waitFor(\n                spriteID,\n                _k.globalOpt.loadTimeout ?? 3000,\n            );\n            const frames = spr.frames;\n            if (frames.length < splittedChars.length) {\n                throw new Error(\n                    `Tried to define ${splittedChars.length} characters for sprite font \"${spriteID}\", but there are only ${frames.length} frames defined`,\n                );\n            }\n            const h = spr.height;\n            return {\n                map: Object.fromEntries(\n                    splittedChars.map((c, i) => [c, frames[i]]),\n                ),\n                size: h,\n                filter: null as any,\n            };\n        })(),\n    );\n}\n\n// loading happiness...\nexport function loadHappy(\n    fontName: string = \"happy\",\n    opt?: LoadBitmapFontOpt,\n) {\n    if (!_k.game.defaultAssets.happy) {\n        throw new Error(\"You can't use loadHappy with kaplay/mini\");\n    }\n\n    return loadBitmapFont(fontName, _k.game.defaultAssets.happy, 28, 36, {\n        filter: \"nearest\",\n        ...opt,\n    });\n}\n", "import {\n    DEF_FONT,\n    DEF_TEXT_CACHE_SIZE,\n    MAX_TEXT_CACHE_SIZE,\n} from \"../constants/general\";\nimport type { DrawTextOpt } from \"../gfx/draw/drawText\";\nimport type { Frame } from \"../gfx/TexPacker\";\nimport { rgb } from \"../math/color\";\nimport { Quad } from \"../math/math\";\nimport { _k } from \"../shared\";\nimport type { ImageSource, LoadFontOpt, Outline, TexFilter } from \"../types\";\nimport { Asset, loadProgress } from \"./asset\";\nimport { type BitmapFontData, getBitmapFont, type GfxFont } from \"./bitmapFont\";\n\n/**\n * @group Assets\n * @subgroup Data\n */\nexport class FontData {\n    outline: Outline | null = null;\n    size: number = DEF_TEXT_CACHE_SIZE;\n    filter: TexFilter;\n    constructor(\n        public fontface: FontFace,\n        opt: LoadFontOpt = {},\n    ) {\n        this.filter = opt.filter ?? _k.globalOpt.fontFilter ?? \"linear\";\n        this.size = opt.size ?? DEF_TEXT_CACHE_SIZE;\n        if (this.size > MAX_TEXT_CACHE_SIZE) {\n            throw new Error(\n                `Font size too big! Max font size: ${MAX_TEXT_CACHE_SIZE}`,\n            );\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 | ArrayBuffer | ArrayBufferView,\n    opt: LoadFontOpt = {},\n): Asset<FontData> {\n    const font = new FontFace(\n        name,\n        typeof src === \"string\" ? `url(${src})` : src,\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 \"${src}\": ${err}`);\n        }).then((face) => new FontData(face, opt)),\n    );\n}\n\nexport function makeFont(\n    tex: ImageSource,\n    gw: number,\n    gh: number,\n    chars: string,\n    filter: TexFilter,\n): GfxFont {\n    const w = tex.width;\n    const h = tex.height;\n    const cols = w / gw;\n    const map: Record<string, Frame> = {};\n    const charMap = chars.split(\"\").entries();\n\n    for (const [i, ch] of charMap) {\n        map[ch] = _k.assets.packer.add(\n            tex,\n            filter,\n            new Quad(\n                (i % cols) * gw / w,\n                Math.floor(i / cols) * gh / h,\n                gw / w,\n                gh / h,\n            ),\n        );\n    }\n\n    return {\n        map,\n        size: gh,\n        filter,\n    };\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\n// Cache for Intl.Segmenter instances by locale\nconst segmenterCache = new Map<string, Intl.Segmenter>();\n\n/**\n * Get or create a cached Intl.Segmenter instance for the given locale.\n */\nfunction getSegmenter(locale?: string): Intl.Segmenter {\n    const key = locale || \"default\";\n    let segmenter = segmenterCache.get(key);\n\n    if (!segmenter) {\n        segmenter = new Intl.Segmenter(locale, { granularity: \"grapheme\" });\n        segmenterCache.set(key, segmenter);\n    }\n\n    return segmenter;\n}\n\n/**\n * Split a string into an array of grapheme clusters (visual characters).\n * Uses Intl.Segmenter for proper Unicode segmentation when available,\n * with fallback to legacy implementation for older browsers.\n *\n * @param string - The string to split into grapheme clusters\n * @param locale - Optional locale for locale-aware segmentation (e.g., 'bn' for Bengali, 'hi' for Hindi)\n *\n * @returns Array of grapheme clusters\n */\nexport function runes(string: string, locale?: string): string[] {\n    if (typeof string !== \"string\") {\n        throw new TypeError(\"string cannot be undefined or null\");\n    }\n\n    // Use Intl.Segmenter if available (Chrome 87+, Safari 14.1+, Firefox 125+)\n    if (typeof Intl !== \"undefined\" && Intl.Segmenter) {\n        // Normalize to NFC for consistent representation of combining characters\n        const normalized = string.normalize(\"NFC\");\n        const segmenter = getSegmenter(locale);\n        return Array.from(\n            segmenter.segment(normalized),\n            segment => segment.segment,\n        );\n    }\n\n    // Fallback to legacy implementation for older browsers\n    return runesLegacy(string);\n}\n\n/**\n * Legacy grapheme cluster splitting implementation.\n * Used as fallback for browsers without Intl.Segmenter support.\n */\nfunction runesLegacy(string: string): string[] {\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", "import { Asset } from \"../assets/asset\";\nimport type { BitmapFontData, GfxFont } from \"../assets/bitmapFont\";\nimport { FontData, resolveFont } from \"../assets/font\";\nimport { DEF_TEXT_CACHE_SIZE } from \"../constants/general\";\nimport { Color, rgb } from \"../math/color\";\nimport { vec2 } from \"../math/math\";\nimport { _k } from \"../shared\";\nimport type { Outline } from \"../types\";\nimport { runes } from \"../utils/runes\";\nimport { alignPt } from \"./anchor\";\nimport type { FormattedChar, FormattedText } from \"./draw/drawFormattedText\";\nimport type { CharTransform, DrawTextOpt } from \"./draw/drawText\";\n\n/**\n * @group Rendering\n * @subgroup Text\n */\nexport type FontAtlas = {\n    font: BitmapFontData;\n    maxHeight: number;\n    outline: Outline | null;\n    ascent: number;\n    descent: number;\n    lineHeight: number;\n};\n\n/**\n * @group Rendering\n * @subgroup Text\n */\nexport type StyledTextInfo = {\n    charStyleMap: Record<number, [string, string][]>;\n    text: string;\n};\n\nfunction applyCharTransform(fchar: FormattedChar, tr: CharTransform) {\n    if (tr.font) fchar.font = tr.font;\n    if (tr.stretchInPlace !== undefined) {\n        fchar.stretchInPlace = tr.stretchInPlace;\n    }\n    if (tr.shader !== undefined) fchar.shader = tr.shader;\n    if (tr.uniform !== undefined) fchar.uniform = tr.uniform;\n    if (typeof tr.skew === \"number\") tr.skew = vec2(-tr.skew, 0);\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.skew) fchar.skew = fchar.skew.add(vec2(tr.skew));\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: any): StyledTextInfo {\n    const charStyleMap = {} as Record<number, [string, string][]>;\n    let renderText = \"\";\n    let styleStack: [string, string][] = [];\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, endSlash, theTagName, tagParam] = execResult;\n            if (endSlash !== undefined) {\n                if (tagParam) {\n                    throw new Error(\n                        `Styled text error: cannot use param in close tag [/${theTagName}]`,\n                    );\n                }\n                if (styleStack.length === 0) {\n                    throw new Error(\n                        `Styled text error: stray end tag [/${theTagName}]`,\n                    );\n                }\n                const [expectedTagName, arg] = styleStack.pop()!;\n                if (expectedTagName !== theTagName) {\n                    throw new Error(\n                        `Styled text error: mismatched tags. Expected [/${expectedTagName}], got [/${theTagName}]`,\n                    );\n                }\n            }\n            else styleStack.push([theTagName, tagParam]);\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.join(\", \")}`,\n        );\n    }\n\n    return {\n        charStyleMap,\n        text: renderText,\n    };\n}\n\nfunction getFontName(font: FontData | string): string {\n    return font instanceof FontData\n        ? font.fontface.family\n        : font;\n}\n\nfunction getFontAtlasForFont(font: FontData | string): FontAtlas {\n    const fontName = getFontName(font);\n    let atlas = _k.gfx.fontAtlases[fontName];\n    if (!atlas) {\n        // create a new atlas\n        const f = font instanceof FontData ? font : null;\n        _k.gfx.fontAtlases[fontName] = atlas = {\n            font: {\n                map: {},\n                size: f?.size ?? DEF_TEXT_CACHE_SIZE,\n                filter: f?.filter ?? _k.globalOpt.fontFilter ?? \"linear\",\n            },\n            maxHeight: 0,\n            ascent: 0,\n            descent: 0,\n            lineHeight: 0,\n            outline: f?.outline ?? null,\n        };\n    }\n    return atlas;\n}\n\nconst allChars = (() => {\n    const renderableChars: string[] = [];\n    for (let i = 33; i <= 126; i++) { // ASCII printables, excluding space which is often ridiculously tall\n        renderableChars.push(String.fromCharCode(i));\n    }\n    return renderableChars.join(\"\") + \"\u00C5\u00C1\u00C2\u00C4\u00C3\u0104\"; // extended support for tall accents\n})();\n\nfunction updateFontAtlas(font: FontData | string, ch: string) {\n    const atlas = getFontAtlasForFont(font);\n    const fontName = getFontName(font);\n    if (!atlas.font.map[ch]) {\n        const c2d = _k.fontCacheC2d;\n        if (!c2d) {\n            throw new Error(\n                \"error generating font texture: _k.fontCacheC2d is null\",\n            );\n        }\n\n        if (!_k.fontCacheCanvas) {\n            throw new Error(\n                \"error generating font texture: _k.fontCacheCanvas is missing\",\n            );\n        }\n\n        c2d.clearRect(\n            0,\n            0,\n            _k.fontCacheCanvas.width,\n            _k.fontCacheCanvas.height,\n        );\n\n        c2d.font = `${atlas.font.size}px ${fontName}, sans-serif`; // generic-family fallback stabilizes ascent of missing glyphs\n        c2d.textBaseline = \"alphabetic\"; // more accurate across browsers and easier to calculate baseline\n        c2d.textAlign = \"left\";\n        c2d.fillStyle = \"#fff\";\n\n        if (!atlas.lineHeight) {\n            const m = c2d.measureText(allChars);\n            const ascent = m.actualBoundingBoxAscent;\n            const descent = m.actualBoundingBoxDescent;\n            const safeOffset = 2;\n\n            atlas.ascent =\n                Math.ceil(ascent > 0 ? ascent : atlas.font.size * 0.78)\n                + safeOffset;\n            atlas.descent =\n                Math.ceil(descent > 0 ? descent : atlas.font.size * 0.22)\n                + safeOffset;\n            atlas.lineHeight = Math.ceil(atlas.ascent + atlas.descent);\n        }\n\n        let w = Math.ceil(c2d.measureText(ch).width);\n        if (!w) return;\n\n        let h = atlas.lineHeight;\n\n        const p = (atlas.outline?.width ?? 0)\n            * (_k.globalOpt.pixelDensity || 1);\n        const x = p;\n        const y = p + atlas.ascent;\n\n        w += p * 2;\n        h += p * 2;\n\n        if (atlas.outline?.width) {\n            c2d.lineJoin = \"round\";\n            c2d.lineWidth = atlas.outline.width * 2;\n            c2d.strokeStyle = rgb(atlas.outline?.color || 0).toHex();\n            c2d.strokeText(ch, x, y);\n        }\n\n        c2d.fillText(ch, x, y);\n\n        const img = c2d.getImageData(0, 0, w, h);\n\n        atlas.font.map[ch] = _k.assets.packer.add(img, atlas.font.filter);\n        _k.assets.packer.syncIfPending();\n\n        atlas.maxHeight = Math.max(atlas.maxHeight, h);\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, opt.locale);\n\n    const fontAtlas = font instanceof FontData || typeof font === \"string\"\n        ? (() => {\n            const atlas = getFontAtlasForFont(font);\n            if (atlas.maxHeight == 0) updateFontAtlas(font, chars[0]);\n            return atlas;\n        })()\n        : null;\n    const defGfxFont = fontAtlas ? fontAtlas.font : font as GfxFont;\n\n    const size = opt.size || defGfxFont.size;\n    const sizeScale = size / defGfxFont.size;\n    const scale = vec2(opt.scale ?? 1).scale(sizeScale);\n    const lineSpacing = opt.lineSpacing ?? 0;\n    const letterSpacing = opt.letterSpacing ?? 0;\n    const baselineCenterOffset = fontAtlas\n        ? Math.round((fontAtlas.maxHeight * sizeScale - size) / 2)\n        : 0;\n\n    let curX: number = 0;\n    let tw = 0;\n    const lines: Array<{\n        width: number;\n        chars: { ch: FormattedChar; font: GfxFont }[];\n    }> = [];\n    let curLine: typeof lines[number][\"chars\"] = [];\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            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            const defaultFontValue =\n                (font instanceof FontData || typeof font === \"string\")\n                    ? font\n                    : undefined;\n            type PartialBy<T, K extends keyof T> =\n                & Omit<T, K>\n                & Partial<Pick<T, K>>;\n            const theFChar: PartialBy<\n                FormattedChar,\n                \"width\" | \"height\" | \"frame\"\n            > = {\n                ch: ch,\n                pos: vec2(curX, 0),\n                opacity: opt.opacity ?? 1,\n                color: opt.color ?? Color.WHITE,\n                scale: vec2(scale),\n                skew: vec2(0),\n                angle: 0,\n                font: defaultFontValue,\n                stretchInPlace: true,\n            };\n\n            if (opt.transform) {\n                const tr = typeof opt.transform === \"function\"\n                    ? opt.transform(cursor, ch, \"\")\n                    : opt.transform;\n                if (tr) {\n                    applyCharTransform(theFChar as any, tr);\n                }\n            }\n\n            if (charStyleMap[cursor]) {\n                const styles = charStyleMap[cursor];\n                for (const [name, param] of styles) {\n                    const style = opt.styles?.[name];\n                    const tr = typeof style === \"function\"\n                        ? style(cursor, ch, param)\n                        : style;\n\n                    if (tr) {\n                        applyCharTransform(theFChar as any, tr);\n                    }\n                }\n            }\n\n            const requestedFont = theFChar.font;\n            const resolvedFont = resolveFont(requestedFont);\n            if (resolvedFont instanceof Asset || !resolvedFont) {\n                // abort, not all fonts have loaded yet\n                return {\n                    width: 0,\n                    height: 0,\n                    chars: [],\n                    opt: opt,\n                    renderedText: \"\",\n                };\n            }\n            let requestedFontData = defGfxFont;\n            let requestedFontScale = 1;\n            if (requestedFont && requestedFont !== defaultFontValue) {\n                if (\n                    resolvedFont instanceof FontData\n                    || typeof resolvedFont === \"string\"\n                ) {\n                    requestedFontData = getFontAtlasForFont(requestedFont).font;\n                }\n                else requestedFontData = resolvedFont;\n                requestedFontScale = defGfxFont.size / requestedFontData.size;\n            }\n            if (\n                requestedFont\n                && (resolvedFont instanceof FontData\n                    || typeof resolvedFont === \"string\")\n            ) updateFontAtlas(requestedFont, ch);\n\n            let f = theFChar.frame = requestedFontData.map[ch];\n\n            // TODO: leave space if character not found?\n            if (f) {\n                let charWidth = f.q.w * f.tex.width * requestedFontScale\n                    * (theFChar.stretchInPlace\n                        ? scale\n                        : theFChar.scale).x;\n\n                if (opt.width && curX + charWidth > opt.width && curX > 0) {\n                    // new line on last word if width exceeds\n                    if (lastSpace != null) {\n                        cursor -= curLine.length - lastSpace;\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                    continue;\n                }\n\n                theFChar.width = f.q.w * f.tex.width * requestedFontScale;\n                theFChar.height = f.q.h * f.tex.height * requestedFontScale;\n\n                theFChar.pos = theFChar.pos.add(\n                    charWidth * 0.5,\n                    theFChar.height * theFChar.scale.y * 0.5,\n                );\n\n                // queue char to be drawn\n                curLine.push({\n                    ch: theFChar as FormattedChar,\n                    font: requestedFontData,\n                });\n\n                if (ch === \" \") {\n                    lastSpace = curLine.length;\n                    lastSpaceWidth = curX;\n                }\n                if (\n                    opt.indentAll\n                    && paraIndentX === undefined\n                    && /\\S/.test(ch)\n                ) {\n                    paraIndentX = curX;\n                }\n\n                curX += charWidth;\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    if (opt.width) {\n        tw = opt.width;\n    }\n\n    const formattedChars: FormattedChar[] = [];\n\n    let th = 0;\n\n    for (let i = 0; i < lines.length; i++) {\n        if (i > 0) th += lineSpacing;\n        const ox = (tw - lines[i].width) * alignPt(opt.align ?? \"left\");\n        let thisLineHeight = size;\n        for (const { ch } of lines[i].chars) {\n            ch.pos = ch.pos.add(ox, th - baselineCenterOffset);\n            formattedChars.push(ch);\n            thisLineHeight = Math.max(\n                thisLineHeight,\n                size * (ch.stretchInPlace ? scale : ch.scale).y / scale.y,\n            );\n        }\n        th += thisLineHeight;\n    }\n\n    return {\n        width: tw,\n        height: th,\n        chars: formattedChars,\n        opt,\n        renderedText: text,\n    };\n}\n", "import type { Asset } from \"../../assets/asset\";\nimport type { BitmapFontData } from \"../../assets/bitmapFont\";\nimport type { FontData } from \"../../assets/font\";\nimport type { Uniform } from \"../../assets/shader\";\nimport type { Color } from \"../../math/color\";\nimport type { Vec2 } from \"../../math/Vec2\";\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 * @subgroup Types\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     * Locale for text segmentation (e.g., 'hi' for Hindi, 'ar' for Arabic, 'bn' for Bengali).\n     * Helps with proper grapheme cluster detection for complex scripts.\n     * Only used when Intl.Segmenter is available in the browser.\n     *\n     * @since v4000.0\n     */\n    locale?: string;\n};\n\n/**\n * A function that returns a character transform config. Useful if you're generating dynamic styles.\n *\n * @group Rendering\n * @subgroup Text\n */\nexport type CharTransformFunc = (\n    idx: number,\n    ch: string,\n    param: string,\n) => CharTransform;\n\n/**\n * Describes how to transform each character.\n *\n * @group Rendering\n * @subgroup Text\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     * Skew transformation to skew each of the characters, in degrees of tilt.\n     * When a number, it skews the text to the right as with italic text.\n     * Given a 2D vector, it affects the skew of the horizontal and vertical sides.\n     */\n    skew?: 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     * If the font for this character should be different from the default font\n     * or the one specified in {@link DrawTextOpt.font}.\n     * Because the font can't be composed like the other properties,\n     * this will override the font even if {@link CharTransform.override} is false.\n     */\n    font?: string | FontData;\n\n    /**\n     * If true, characters that have a X scale that is not 1 won't have the bounding box stretched to fit the character,\n     * and may end up overlapping with adjacent characters.\n     *\n     * @default true\n     */\n    stretchInPlace?: boolean;\n\n    /**\n     * A name for a shader that will be applied to this character only.\n     */\n    shader?: string;\n\n    /**\n     * Values to use for the shader's uniform inputs.\n     * If there is no shader set (by this character's transform or an entire-text\n     * transform), this is not used.\n     */\n    uniform?: Uniform;\n}\n\n/**\n * How the text should be aligned.\n *\n * @group Rendering\n * @subgroup Text\n */\nexport type TextAlign =\n    | \"center\"\n    | \"left\"\n    | \"right\";\n\nexport function drawText(opt: DrawTextOpt) {\n    drawFormattedText(formatText(opt));\n}\n", "import { _k } from \"../../shared\";\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/general\";\nimport { drawFormattedText } from \"../gfx/draw/drawFormattedText\";\nimport { drawRect } from \"../gfx/draw/drawRect\";\nimport { drawText } from \"../gfx/draw/drawText\";\nimport { drawUnscaled } from \"../gfx/draw/drawUnscaled\";\nimport { formatText } from \"../gfx/formatText\";\nimport { height, popTransform, width } from \"../gfx/stack\";\nimport { rgb } from \"../math/color\";\nimport { vec2 } from \"../math/math\";\nimport { _k } from \"../shared\";\n\nexport const throwError = (err: string) => {\n    handleErr(err);\n};\n\nexport const handleErr = (err: unknown) => {\n    if (_k.game.crashed) return;\n    _k.game.crashed = true;\n    _k.audio.ctx.suspend();\n    let error: Error;\n\n    if (err instanceof Error) {\n        error = err;\n    }\n    else {\n        error = new Error(String(err));\n    }\n\n    if (!error.message) {\n        error.message = \"Unknown error, check console for more info\";\n    }\n\n    function showErrorScreen() {\n        _k.app.state.stopped = true;\n        _k.frameRenderer.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: esc(error.message),\n                pos: vec2(pad, pad + title.height + gap),\n                fixed: true,\n            });\n\n            popTransform();\n            _k.game.events.trigger(\"error\", error);\n        });\n\n        _k.frameRenderer.frameEnd();\n    }\n\n    showErrorScreen();\n\n    // TODO: Make this a setting\n    if (!error.message.startsWith(\"[rendering]\")) {\n        console.error(error);\n        throw error;\n    }\n    else {\n        // We don't throw rendering errors,\n        // but we log them to the console\n        // This is for \"headless\" rendering\n        console.error(error);\n    }\n};\n\nfunction esc(t: string) {\n    return t.replaceAll(/(?<!\\\\)\\[/g, \"\\\\[\");\n}\n", "import { _k } from \"../../shared\";\nimport { flush } from \"../stack\";\n\nexport function drawStenciled(\n    content: () => void,\n    mask: () => void,\n    test: GLenum,\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 \"../../shared\";\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 type { Shader, Uniform } from \"../../assets/shader\";\nimport { IDENTITY_MATRIX } from \"../../constants/math\";\nimport { getCamTransform } from \"../../game/camera\";\nimport { _k } from \"../../shared\";\nimport type { BlendMode, RenderProps } from \"../../types\";\nimport { Mesh, type Texture } from \"../gfx\";\nimport { height, width } from \"../stack\";\n\n/**\n * @group Draw\n * @subgroup Picture\n */\nexport type Material = {\n    tex?: Texture;\n    shader?: Shader;\n    uniform?: Uniform;\n    blend?: BlendMode;\n};\n\n/**\n * @group Draw\n * @subgroup Picture\n */\nexport type PictureCommand = {\n    material: Material;\n    index: number;\n    count: number;\n};\n\n/**\n * A picture holding drawing data\n *\n * @group Draw\n * @subgroup Picture\n */\nexport class Picture {\n    vertices: number[];\n    indices: number[];\n    commands: PictureCommand[];\n    mesh?: Mesh;\n\n    /**\n     * Creates an empty picture if no data is given, otherwise deserializes the data\n     * @param data - Optional archived picture data\n     */\n    constructor(data?: string) {\n        this.vertices = [];\n        this.indices = [];\n        this.commands = [];\n\n        if (data) {\n            // TODO: deserialize\n        }\n    }\n\n    /**\n     * Serializes this picture to a JSON string\n     * @returns a string containing JSON picture data\n     */\n    archive(): string {\n        return JSON.stringify({\n            vertices: this.vertices,\n            indices: this.indices,\n            commands: this.commands.map(command => {\n                return {\n                    material: {\n                        tex: \"\", // TODO: Find a way to refer to a texture by name (main, font, single, etc)\n                        shader: \"\", // TODO: Find a way to refer to a shader by name command.material.shader.name\n                        uniform: command.material.uniform,\n                        blend: command.material.blend,\n                    },\n                    index: command.index,\n                    count: command.count,\n                };\n            }),\n        });\n    }\n\n    free() {\n        this.mesh?.free();\n    }\n}\n\n/**\n * Drawing options for drawPicture\n *\n * @group Draw\n * @subgroup Types\n */\nexport type DrawPictureOpt = RenderProps & {};\n\n/**\n * Draws a picture to the screen. This function can not be used to draw recursively to a picture.\n * @param picture - The picture to draw\n * @param opt - Drawing options\n */\nexport function drawPicture(\n    picture: Picture,\n    opt: DrawPictureOpt,\n) {\n    const w = width();\n    const h = height();\n    _k.gfx.renderer.flush(w, h);\n\n    // This is the transform we will apply\n    const transform = _k.gfx.transform.clone();\n    if (opt.pos) transform.translateSelfV(opt.pos);\n    if (opt.angle) transform.rotateSelf(opt.angle);\n    if (opt.scale) transform.scaleSelfV(opt.scale);\n    if (opt.skew) transform.skewSelfV(opt.skew);\n\n    const ctx = _k.gfx.renderer.ctx;\n    const gl = ctx.gl;\n\n    // This binds the vertex buffer\n    ctx.pushArrayBuffer(picture.mesh!.glVBuf);\n    // Once bound, we set the pointers, which are offsets relative to the pointer of the array buffer we just bound\n    const a_pos = gl.getAttribLocation(_k.gfx.defShader.glProgram, \"a_pos\");\n    gl.vertexAttribPointer(a_pos, 2, gl.FLOAT, false, 32, 0);\n    const a_uv = gl.getAttribLocation(_k.gfx.defShader.glProgram, \"a_uv\");\n    gl.vertexAttribPointer(a_uv, 2, gl.FLOAT, false, 32, 8);\n    const a_color = gl.getAttribLocation(_k.gfx.defShader.glProgram, \"a_color\");\n    gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 32, 16);\n    // Bind the index buffer as well\n    ctx.pushElementArrayBuffer(picture.mesh!.glIBuf);\n\n    let lastShader: Shader | null = null;\n    let lastTexture: Texture | null = null;\n\n    // Execute all commands, basically drawing ranges using a given material\n    for (const command of picture.commands) {\n        const texture = command.material.tex ?? _k.gfx.whitePixel.tex;\n        const shader = command.material.shader ?? _k.gfx.defShader;\n\n        if (command.material.blend) {\n            _k.gfx.renderer.setBlend(command.material.blend);\n        }\n\n        if (shader != lastShader) {\n            lastShader?.unbind();\n            shader.bind();\n            lastShader = shader;\n            shader.send({\n                width: w,\n                height: h,\n                camera: opt.fixed ? IDENTITY_MATRIX : getCamTransform(),\n                transform: transform,\n            });\n        }\n\n        if (command.material.uniform) {\n            shader?.send(command.material.uniform);\n        }\n\n        if (texture != lastTexture) {\n            lastTexture?.unbind();\n            texture?.bind();\n            lastTexture = texture;\n        }\n\n        // Do the actual draw\n        // TODO: put the mode into the command\n        gl.drawElements(\n            gl.TRIANGLES,\n            command.count,\n            gl.UNSIGNED_SHORT,\n            command.index * 2,\n        );\n    }\n\n    lastShader?.unbind();\n    lastTexture?.unbind();\n\n    // Pop these to balance the stack\n    ctx.popArrayBuffer();\n    ctx.popElementArrayBuffer();\n\n    // So, you would think that once you pop the vertex buffer, the vertex buffer of the renderer is bound again\n    // But that seems not to be happening, so we do it explicitly here\n    ctx.pushArrayBuffer(_k.gfx.renderer.glVBuf);\n    // We set the pointers to this vertex buffer again\n    gl.vertexAttribPointer(a_pos, 2, gl.FLOAT, false, 32, 0);\n    gl.vertexAttribPointer(a_uv, 2, gl.FLOAT, false, 32, 8);\n    gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 32, 16);\n    // And pop the buffer to balance\n    ctx.popArrayBuffer();\n}\n\n/**\n * Selects the picture for drawing, erases existing data.\n * @param picture - The picture to write drawing data to.\n */\nexport function beginPicture(picture?: Picture) {\n    picture ??= new Picture();\n    picture.vertices.length = 0;\n    picture.indices.length = 0;\n    picture.commands.length = 0;\n    _k.gfx.renderer.picture = picture;\n}\n\n/**\n * Selects the picture for drawing, keeps existing data.\n * @param picture - The picture to write drawing data to.\n */\nexport function appendToPicture(picture?: Picture) {\n    picture ??= new Picture();\n    _k.gfx.renderer.picture = picture;\n}\n\n/**\n * Deselects the current picture for drawing, returning the picture.\n * @returns The picture which was previously selected.\n */\nexport function endPicture(): Picture {\n    const ctx = _k.gfx.renderer.ctx;\n    const gl = ctx.gl;\n\n    const picture = _k.gfx.renderer.picture;\n    if (!picture) {\n        throw new Error(\"Called endPicture when no picture was started\");\n    }\n    _k.gfx.renderer.picture = null;\n\n    picture.free();\n    picture.mesh = new Mesh(\n        ctx,\n        _k.gfx.renderer.vertexFormat,\n        picture.vertices,\n        picture.indices,\n    );\n\n    return picture;\n}\n", "import { _k } from \"../../shared\";\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 { TextureOpt } from \"../types\";\nimport { type GfxCtx, Texture } from \"./gfx\";\n\n/**\n * @group Rendering\n * @subgroup Canvas\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", "// Make is the entity factory function\n\nimport { KEvent, KEventHandler } from \"../../events/events\";\nimport { Mat23 } from \"../../math/math\";\nimport { _k } from \"../../shared\";\nimport type { Comp, CompList, GameObj } from \"../../types\";\nimport { GameObjRawPrototype } from \"./GameObjRaw\";\n\n/*\nOrder of making a game object:\n\n1. We receive an array of components and tags from add([])\n2. We create the GameObjRaw object using our prototype\n3. We call .use() or .tag() on elements in the compAndTags array\n*/\n\n/*\nWe use makeInternal() to create the root game object, and make() to create\nthe rest of the game objects.\n*/\nexport function makeInternal<T extends CompList<unknown>>(\n    id: number,\n    compsAndTags?: [...T],\n): GameObj<T[number]> {\n    const addCompIdsToTags = id == 0\n        ? false\n        : _k.globalOpt.tagComponentIds;\n\n    // The game object from the prototype\n    const obj: GameObj = Object.create(GameObjRawPrototype);\n    currentMaking.push(obj);\n\n    // Shadow individual properties\n    obj._parent = null as unknown as GameObj;\n    obj._onCurCompCleanup = null;\n    obj.children = [];\n    obj._cleanups = {};\n    obj._compStates = new Map();\n    obj._compsIds = new Set();\n    obj._anonymousCompStates = [];\n    obj._tags = new Set(\"*\");\n    obj._events = new KEventHandler();\n    obj._updateEvents = new KEvent<[]>();\n    obj._fixedUpdateEvents = new KEvent<[]>();\n    obj._drawEvents = new KEvent<[]>();\n    obj._inputEvents = [];\n    obj.paused = false;\n    obj.hidden = false;\n    obj.id = id;\n    obj.transform = new Mat23();\n\n    try {\n        // Adding components passed from add([]);\n        // We register here: The objects, because you can also pass tags to add().\n        if (!compsAndTags) return obj as GameObj<T[number]>;\n\n        let comps = [];\n        let tagList = [];\n\n        for (const compOrTag of compsAndTags) {\n            if (typeof compOrTag == \"string\") {\n                tagList.push(compOrTag);\n            }\n            else {\n                const compId = (<Comp> compOrTag).id;\n\n                if (compId) {\n                    obj._compsIds.add(compId);\n                    if (addCompIdsToTags) tagList.push(compId);\n                }\n\n                comps.push(compOrTag);\n            }\n        }\n\n        // Using .use and .tag we trigger onUse and onTag events correctly\n        for (const comp of comps) {\n            obj.use(<Comp> comp);\n        }\n\n        for (const tag of tagList) {\n            obj.tag(tag);\n        }\n\n        // We cast the type as .use() doesn't add the types\n        return obj as GameObj<T[number]>;\n    } finally {\n        currentMaking.pop();\n    }\n}\n\nexport function make<T extends CompList<unknown>>(\n    compsAndTags: [...T],\n): GameObj<T[number]> {\n    const obj = makeInternal(_k.game.gameObjLastId, compsAndTags);\n    _k.game.gameObjLastId++;\n    return obj;\n}\n\nlet currentMaking: GameObj[] = [];\nexport function internalIsMaking(obj: GameObj): boolean {\n    return currentMaking.includes(obj);\n}\n", "import { Asset, fetchJSON } from \"../../assets/asset\";\nimport { fixURL } from \"../../assets/utils\";\nimport { _k } from \"../../shared\";\nimport type { Comp, CompList, GameObj } from \"../../types\";\nimport type { GameObjRaw, InternalGameObjRaw } from \"./GameObjRaw\";\n\n/**\n * A serialized game object. Created using {@link GameObjRaw.serialize `GameObjRaw.serialize()` } method.\n *\n * @since v4000.0\n * @group Game Obj\n * @subgroup Prefabs\n */\nexport interface SerializedGameObj {\n    components: Record<string, any>;\n    tags: string[];\n    children?: SerializedGameObj[];\n}\n\nconst factoryMethods: { [key: string]: (data: object) => Comp } = {};\n\n// #region Deserialization\nexport function registerPrefabFactory(\n    id: string,\n    factoryMethod: (data: any) => Comp,\n) {\n    factoryMethods[id] = factoryMethod;\n}\n\nexport function deserializePrefabAsset(serializedPrefab: SerializedGameObj) {\n    const list: CompList<unknown> = [];\n\n    for (const id in serializedPrefab.components) {\n        if (id in factoryMethods) {\n            list.push(factoryMethods[id](serializedPrefab.components[id]));\n        }\n    }\n\n    for (const tag of serializedPrefab.tags) {\n        list.push(tag);\n    }\n\n    return list;\n}\n\nexport function deserializeComp(id: string, data: any) {\n    if (id in factoryMethods) {\n        return factoryMethods[id](data);\n    }\n    throw new Error(`No factory found to deserialize component with id ${id}`);\n}\n// #endregion\n\n// #region Loading\nexport function loadPrefab(name: string, url: string) {\n    return _k.assets.prefabAssets.add(name, fetchJSON(fixURL(url)));\n}\n// #endregion\n\n// #region Serialization\nexport function createPrefab(nameOrObject: string | GameObj, object?: GameObj) {\n    const obj: InternalGameObjRaw = object\n        ? object as InternalGameObjRaw\n        : nameOrObject as InternalGameObjRaw;\n\n    const data = obj.serialize();\n\n    if (object) {\n        _k.assets.prefabAssets.add(\n            nameOrObject as string,\n            Promise.resolve(\n                new Asset<SerializedGameObj>(Promise.resolve(data)),\n            ),\n        );\n    }\n    return data;\n}\n// #endregion\n", "// The E of ECS\n\nimport type { AppEvents } from \"../../app/app\";\nimport type { KAPLAYCtx } from \"../../core/contextType\";\nimport { throwError } from \"../../core/errors\";\nimport type { GameObjEventNames } from \"../../events/eventMap\";\nimport {\n    type KEvent,\n    KEventController,\n    type KEventHandler,\n} from \"../../events/events\";\nimport type { EventHandlersInAppButNotAddedInGameObjRaw } from \"../../events/scopes\";\nimport { drawMasked } from \"../../gfx/draw/drawMasked\";\nimport { beginPicture, endPicture, Picture } from \"../../gfx/draw/drawPicture\";\nimport { drawSubtracted } from \"../../gfx/draw/drawSubtracted\";\nimport { FrameBuffer } from \"../../gfx/FrameBuffer\";\nimport {\n    flush,\n    loadMatrix,\n    multRotate,\n    multScaleV,\n    multSkewV,\n    multTranslateV,\n    popTransform,\n    pushTransform,\n    storeMatrix,\n} from \"../../gfx/stack\";\nimport { Mat23 } from \"../../math/math\";\nimport { calcTransform } from \"../../math/various\";\nimport { _k } from \"../../shared\";\nimport type {\n    Comp,\n    CompList,\n    GameObj,\n    GameObjID,\n    GameObjInspect,\n    GetOpt,\n    QueryOpt,\n    RenderTarget,\n    Tag,\n} from \"../../types\";\nimport type { MaskComp } from \"../components/draw/mask\";\nimport type { FixedComp } from \"../components/transform/fixed\";\nimport type { LayerComp } from \"../components/transform/layer\";\nimport type { PosComp } from \"../components/transform/pos\";\nimport type { RotateComp } from \"../components/transform/rotate\";\nimport type { ScaleComp } from \"../components/transform/scale\";\nimport type { SkewComp } from \"../components/transform/skew\";\nimport type { ZComp } from \"../components/transform/z\";\nimport { internalIsMaking, make } from \"./make\";\nimport { deserializePrefabAsset, type SerializedGameObj } from \"./prefab\";\nimport { isFixed } from \"./utils\";\n\nexport enum KeepFlags {\n    Pos = 1,\n    Angle = 2,\n    Scale = 4,\n    All = 7,\n}\n\nexport type SetParentOpt = {\n    keep: KeepFlags;\n};\n\nlet _nextTreeIndex = 0;\nexport function resetTreeIndex() {\n    _nextTreeIndex = 0;\n}\n\nlet _lastTransformVersion = 0;\nlet _nextTransformVersion = 0;\n\nexport function nextTransformVersion() {\n    return _nextTransformVersion++;\n}\n\nexport function updateLastTransformVersion() {\n    return _lastTransformVersion = _nextTransformVersion;\n}\n\nexport function transformNeedsUpdate(version: number) {\n    return version >= _lastTransformVersion;\n}\n\nexport function objectTransformNeedsUpdate(obj: GameObj<any>) {\n    return obj._transformVersion >= _lastTransformVersion;\n}\n\nexport function getTransformVersion(obj: GameObj<any>): number {\n    return obj._transformVersion;\n}\n\n/**\n * Base interface of all game objects.\n *\n * @since v2000.0\n * @group Game Obj\n * @subgroup Types\n */\nexport interface GameObjRaw {\n    /**\n     * The unique id of the game obj.\n     */\n    id: GameObjID;\n    /**\n     * Get or set the parent game obj.\n     *\n     * @since v4000.0\n     */\n    parent: GameObj | null;\n    /**\n     * Get all children game objects.\n     *\n     * @readonly\n     * @since v3000.0\n     */\n    children: GameObj[];\n    /**\n     * Get the tags of a game object. For update it, use `tag()` and `untag()`.\n     *\n     * @readonly\n     * @since v3001.0\n     */\n    tags: string[];\n    /**\n     * Calculated transform matrix of a game object.\n     *\n     * @since v3000.0\n     */\n    transform: Mat23;\n    /**\n     * If draw the game obj (run \"draw\" event or not).\n     *\n     * @since v2000.0\n     */\n    hidden: boolean;\n    /**\n     * If update the game obj (run \"update\" event or not).\n     *\n     * @since v2000.0\n     */\n    paused: boolean;\n    /**\n     * The canvas to draw this game object on\n     *\n     * @since v3001.0\n     */\n    target?: RenderTarget;\n    /**\n     * Set the parent game obj with additional options.\n     *\n     * @since v4000.0\n     */\n    setParent(p: GameObj, opt: SetParentOpt): void;\n    /**\n     * Add a child.\n     *\n     * @param comps - The components to add.\n     *\n     * @returns The added game object.\n     * @since v3000.0\n     */\n    add<T extends CompList<unknown>>(comps?: [...T]): GameObj<T[number]>;\n    /**\n     * Add a prefab.\n     *\n     * @param nameOrObject - Name of registered prefab using loadPrefab() or plain obj returned by createPrefab().\n     *\n     * @returns The added game object.\n     * @since v4000.0\n     */\n    addPrefab<T extends CompList<unknown>>(\n        nameOrObject: object | string,\n        compList?: [...T],\n    ): GameObj<T[number]>;\n    /**\n     * Create a serialized version of this Game Object.\n     *\n     * @returns The serialized game object\n     * @since v4000.0\n     */\n    serialize(): SerializedGameObj;\n    /**\n     * Remove and re-add the game obj, without triggering add / destroy events.\n     *\n     * @param obj - The game object to re-add.\n     *\n     * @returns The re-added game object.\n     * @since v3000.0\n     */\n    readd<T>(obj: GameObj<T>): GameObj<T>;\n    /**\n     * Remove a child.\n     *\n     * @param obj - The game object to remove.\n     *\n     * @since v3000.0\n     */\n    remove(obj: GameObj): void;\n    /**\n     * Remove all children with a certain tag.\n     *\n     * @param tag - The tag to remove.\n     *\n     * @since v3000.0\n     */\n    removeAll(tag: Tag): void;\n    /**\n     * Remove this game obj from scene.\n     *\n     * @since v2000.0\n     */\n    destroy(): void;\n    /**\n     * Remove all children.\n     *\n     * @since v3000.0\n     */\n    removeAll(): void;\n    /**\n     * If game obj is attached to the scene graph.\n     *\n     * @returns true if attached, false otherwise.\n     * @since v2000.0\n     */\n    exists(): boolean;\n    /**\n     * Check if is an ancestor (recursive parent) of another game object\n     *\n     * @returns true if is ancestor, false otherwise.\n     * @since v3000.0\n     */\n    isAncestorOf(obj: GameObj): boolean;\n    /**\n     * Get a list of all game objs with certain tag.\n     *\n     * @param tag - The tag to get.\n     *\n     * @since v3000.0\n     */\n    get<T = any>(tag: Tag | Tag[], opts?: GetOpt): GameObj<T>[];\n    /**\n     * Get a list of all game objs with certain properties.\n     *\n     * @param opt - The properties to get.\n     *\n     * @since v3001.0\n     */\n    query(opt: QueryOpt): GameObj[];\n    /**\n     * Update this game object and all children game objects.\n     *\n     * @since v3000.0\n     */\n    update(): void;\n    /**\n     * Update this game object and all children game objects.\n     *\n     * @since v3001.0\n     */\n    fixedUpdate(): void;\n    /**\n     * Draw this game object and all children game objects.\n     *\n     * @since v3000.0\n     */\n    draw(): void;\n    drawTree(): void;\n    /**\n     * Gather debug info of all comps.\n     *\n     * @since v2000.0\n     */\n    inspect(): GameObjInspect;\n    /**\n     * Draw debug info in inspect mode\n     *\n     * @since v3000.0\n     */\n    drawInspect: () => void;\n    /**\n     * This method is called to transform and collect objects which should be drawn layered\n     */\n    collect(objects: GameObj<any>[]): void;\n    /**\n     * This method is called to transform objects\n     */\n    transformTree(force: boolean): void;\n    /**\n     * Add a component.\n     *\n     * @example\n     * ```js\n     * const obj = add([\n     *    sprite(\"bean\"),\n     * ]);\n     *\n     * // Add opacity\n     * obj.use(opacity(0.5));\n     * ```\n     *\n     * @since v2000.0\n     */\n    use(comp: Comp): void;\n    /**\n     * Remove a component with its id (the component name)\n     *\n     * @param comp - The component id to remove. It means the name, if sprite, then it's \"sprite\".\n     *\n     * @example\n     * ```js\n     * // Remove sprite component\n     * obj.unuse(\"sprite\");\n     * ```\n     *\n     * @since v2000.0\n     */\n    unuse(comp: string): void;\n    /**\n     * Check if game object has a certain component.\n     *\n     * @param compId - The component id(s) to check.\n     * @param op - The operator to use when searching for multiple components. Default is \"and\".\n     *\n     * @example\n     * ```js\n     * // Check if game object has sprite component\n     * if(obj.has(\"sprite\")) {\n     *     debug.log(\"has sprite component\");\n     * }\n     *\n     * // Check if game object has tags\n     * obj.has([\"tag1\", \"tag2\"]); // AND, it has both tags\n     * obj.has([\"tag1\", \"tag2\"], \"or\"); // OR, it has either tag1 or tag2\n     * ```\n     *\n     * @returns true if has the component(s), false otherwise.\n     * @since v3001.0.5\n     * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0\n     */\n    has(compId: string | string[], op?: \"and\" | \"or\"): boolean;\n    /**\n     * Get state for a specific comp.\n     *\n     * @param id - The component id.\n     *\n     * @since v2000.0\n     */\n    c(id: string): Comp | null;\n    /**\n     * Add a tag(s) to the game obj.\n     *\n     * @param tag - The tag(s) to add.\n     *\n     * @example\n     * ```js\n     * // add enemy tag\n     * obj.tag(\"enemy\");\n     *\n     * // add multiple tags\n     * obj.tag([\"enemy\", \"boss\"]);\n     * ```\n     *\n     * @since v3001.0.5\n     * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0\n     */\n    tag(tag: Tag | Tag[]): void;\n    /**\n     * Remove a tag(s) from the game obj.\n     *\n     * @param tag - The tag(s) to remove.\n     *\n     * @example\n     * ```js\n     * // remove enemy tag\n     * obj.untag(\"enemy\");\n     *\n     * // remove multiple tags\n     * obj.untag([\"enemy\", \"boss\"]);\n     * ```\n     *\n     * @since v3001.0.5\n     * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0\n     */\n    untag(tag: Tag | Tag[]): void;\n    /**\n     * If there's certain tag(s) on the game obj.\n     *\n     * @param tag - The tag(s) for checking.\n     * @param op - The operator to use when searching for multiple tags. Default is \"and\".\n     *\n     * @since v3001.0.5\n     * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0\n     */\n    is(tag: Tag | Tag[], op?: \"and\" | \"or\"): boolean;\n    /**\n     * Register an event.\n     *\n     * @param event - The event name.\n     * @param action - The action to run when event is triggered.\n     *\n     * @returns The event controller.\n     * @since v2000.0\n     */\n    on(\n        event: GameObjEventNames | (string & {}),\n        action: (...args: any) => void,\n    ): KEventController;\n    /**\n     * Trigger an event.\n     *\n     * @param event - The event name.\n     * @param args - The arguments to pass to the event action.\n     *\n     * @since v2000.0\n     */\n    trigger(event: string, ...args: any): void;\n    /**\n     * Clear all events.\n     */\n    clearEvents: () => void;\n    /**\n     * Register an event that runs when the game obj is added to the scene.\n     *\n     * @returns The event controller.\n     * @since v2000.0\n     */\n    onAdd(action: () => void): KEventController;\n    /**\n     * Register an event that runs every frame as long as the game obj exists.\n     *\n     * @returns The event controller.\n     * @since v2000.1\n     */\n    onUpdate(action: () => void): KEventController;\n    /**\n     * Register an event that runs every frame as long as the game obj exists.\n     *\n     * @returns The event controller.\n     * @since v2000.1\n     */\n    onFixedUpdate(action: () => void): KEventController;\n    /**\n     * Register an event that runs every frame as long as the game obj exists (this is the same as `onUpdate()`, but all draw events are run after all update events).\n     *\n     * @returns The event controller.\n     * @since v2000.1\n     */\n    onDraw(action: () => void): KEventController;\n    /**\n     * Register an event that runs when the game obj is destroyed.\n     *\n     * @returns The event controller.\n     * @since v2000.1\n     */\n    onDestroy(action: () => void): KEventController;\n    /**\n     * Register an event that runs when a component is used.\n     *\n     * @returns The event controller.\n     * @since v4000.0\n     */\n    onUse(action: (id: string) => void): KEventController;\n    /**\n     * Register an event that runs when a component is unused.\n     *\n     * @returns The event controller.\n     * @since v4000.0\n     */\n    onUnuse(action: (id: string) => void): KEventController;\n    /**\n     * Register an event that runs when a tag is added.\n     *\n     * @returns The event controller.\n     * @since v4000.0\n     */\n    onTag(action: (tag: string) => void): KEventController;\n    /**\n     * Register an event that runs when a tag is removed.\n     *\n     * @returns The event controller.\n     * @since v4000.0\n     */\n    onUntag(action: (tag: string) => void): KEventController;\n    onKeyDown: KAPLAYCtx[\"onKeyDown\"];\n    onKeyPress: KAPLAYCtx[\"onKeyPress\"];\n    onKeyPressRepeat: KAPLAYCtx[\"onKeyPressRepeat\"];\n    onKeyRelease: KAPLAYCtx[\"onKeyRelease\"];\n    onCharInput: KAPLAYCtx[\"onCharInput\"];\n    onMouseDown: KAPLAYCtx[\"onMouseDown\"];\n    onMousePress: KAPLAYCtx[\"onMousePress\"];\n    onMouseRelease: KAPLAYCtx[\"onMouseRelease\"];\n    onMouseMove: KAPLAYCtx[\"onMouseMove\"];\n    onTouchStart: KAPLAYCtx[\"onTouchStart\"];\n    onTouchMove: KAPLAYCtx[\"onTouchMove\"];\n    onTouchEnd: KAPLAYCtx[\"onTouchEnd\"];\n    onScroll: KAPLAYCtx[\"onScroll\"];\n    onGamepadButtonDown: KAPLAYCtx[\"onGamepadButtonDown\"];\n    onGamepadButtonPress: KAPLAYCtx[\"onGamepadButtonPress\"];\n    onGamepadButtonRelease: KAPLAYCtx[\"onGamepadButtonRelease\"];\n    onGamepadStick: KAPLAYCtx[\"onGamepadStick\"];\n    onButtonDown: KAPLAYCtx[\"onButtonDown\"];\n    onButtonPress: KAPLAYCtx[\"onButtonPress\"];\n    onButtonRelease: KAPLAYCtx[\"onButtonRelease\"];\n    onTabShow: KAPLAYCtx[\"onTabShow\"];\n    onTabHide: KAPLAYCtx[\"onTabHide\"];\n    onShow: KAPLAYCtx[\"onShow\"];\n    onHide: KAPLAYCtx[\"onHide\"];\n}\n\nexport type InternalGameObjRaw = GameObjRaw & {\n    /** @readonly */\n    _parent: GameObj;\n    /** @readonly */\n    _compsIds: Set<string>;\n    /** @readonly */\n    _compStates: Map<string, Comp>;\n    /** @readonly */\n    _anonymousCompStates: Comp[];\n    /** @readonly */\n    _cleanups: Record<string, (() => any)[]>;\n    /** @readonly */\n    _events: KEventHandler<any>;\n    /** @readonly */\n    _fixedUpdateEvents: KEvent<[]>;\n    /** @readonly */\n    _updateEvents: KEvent<[]>;\n    /** @readonly */\n    _drawEvents: KEvent<[]>;\n    /** @readonly */\n    _inputEvents: KEventController[];\n    /** @readonly */\n    _onCurCompCleanup: Function | null;\n    /** @readonly */\n    _tags: Set<Tag>;\n    /** @readonly */\n    _drawLayerIndex: number;\n    /** @readonly */\n    _treeIndex: number;\n    /** @readonly */\n    _transformVersion: number;\n\n    /**\n     * Adds a component or anonymous component.\n     */\n    _addComp(comp: Comp): void;\n    /**\n     * Removes a component without checking for dependencies\n     */\n    _removeComp(id: string): void;\n    /**\n     * Check if any id of a component's require is not present in `_compsIds`, if\n     * there's, throw an error.\n     *\n     * @param comp - The component for checking.\n     */\n    _checkDependencies(comp: Comp): void;\n    /**\n     * Check if any component (in `_compStates`) is dependent of compId, if\n     * there's, throw an error.\n     *\n     * @param compId - Component ID for searching.\n     */\n    _checkDependents(compId: string): void;\n};\n\ntype GameObjTransform =\n    & GameObj<PosComp | RotateComp | ScaleComp>\n    & InternalGameObjRaw;\ntype GameObjCamTransform =\n    & GameObj<\n        PosComp | RotateComp | ScaleComp | FixedComp | MaskComp\n    >\n    & InternalGameObjRaw;\n\nconst COMP_DESC = new Set([\"id\", \"require\"]);\nconst COMP_EVENTS = new Set([\n    \"add\",\n    \"fixedUpdate\",\n    \"update\",\n    \"draw\",\n    \"destroy\",\n    \"inspect\",\n    \"drawInspect\",\n    \"serialize\",\n]);\n\ntype GarbageCollectorArray = (() => any)[];\n\ntype HandlersInAppButAlsoInObj = EventHandlersInAppButNotAddedInGameObjRaw;\n\nexport const GameObjRawPrototype: Omit<\n    InternalGameObjRaw,\n    // TODO: Maybe too hacky, find better way\n    Exclude<AppEvents, HandlersInAppButAlsoInObj>\n> = {\n    // This chain of `as any`, is because we never should use this object\n    // directly, it's only a prototype. These properties WILL be defined\n    // (by our factory function `make`) when we create a new game object.\n    _anonymousCompStates: null as any,\n    _cleanups: null as any,\n    _compsIds: null as any,\n    _compStates: null as any,\n    _events: null as any,\n    _fixedUpdateEvents: null as any,\n    _inputEvents: null as any,\n    _onCurCompCleanup: null as any,\n    _parent: null as any,\n    _tags: null as any,\n    _updateEvents: null as any,\n    _drawEvents: null as any,\n    _drawLayerIndex: null as any,\n    _treeIndex: null as any,\n    children: null as any,\n    hidden: null as any,\n    id: null as any,\n    transform: null as any,\n    _transformVersion: null as any,\n    target: null as any,\n\n    // #region Setters and Getters\n    set parent(p: GameObj) {\n        // We assume this will never be ran in root\n        // so this is GameObj\n\n        if (this.id === null) {\n            throw new Error(\"Can't re-parent destroyed object\");\n        }\n\n        if (this._parent === p) return;\n        const index = this._parent\n            ? this._parent.children.indexOf(this as unknown as GameObj)\n            : -1;\n        if (index !== -1) {\n            this._parent.children.splice(index, 1);\n        }\n        this._parent = p;\n        if (p) {\n            p.children.push(this as unknown as GameObj);\n            this._transformVersion = nextTransformVersion();\n        }\n    },\n\n    paused: false,\n\n    get parent() {\n        return this._parent;\n    },\n\n    get tags() {\n        return Array.from(this._tags);\n    },\n\n    // #endregion\n\n    // #region Object\n    setParent(\n        this: GameObjTransform,\n        p: GameObj,\n        opt: SetParentOpt,\n    ) {\n        if (this._parent === p) return;\n        const oldTransform = this._parent?.transform;\n        const newTransform = p.transform;\n        if ((opt.keep & KeepFlags.Pos) && this.pos !== undefined) {\n            oldTransform.transformPointV(this.pos, this.pos);\n            newTransform.inverse.transformPointV(this.pos, this.pos);\n        }\n        if ((opt.keep & KeepFlags.Angle) && this.angle !== undefined) {\n            this.angle += newTransform.getRotation()\n                - oldTransform.getRotation();\n        }\n        if ((opt.keep & KeepFlags.Scale) && this.scale !== undefined) {\n            this.scale = this.scale.scale(\n                oldTransform.getScale().invScale(newTransform.getScale()),\n            );\n        }\n        this.parent = p;\n    },\n\n    add<T2 extends CompList<unknown>>(\n        this: InternalGameObjRaw,\n        a: [...T2],\n    ): GameObj<T2[number]> {\n        if (this.id === null) {\n            throw new Error(\"Can't add child to destroyed object\");\n        }\n\n        const obj = make(a);\n\n        if (obj.parent) {\n            throw new Error(\n                \"Cannot add a game obj that already has a parent.\",\n            );\n        }\n\n        obj.parent = this;\n\n        calcTransform(obj, obj.transform);\n\n        // Run global events first, so things that listen for onAdd()\n        // see the object with *only* components added during make(),\n        // and *then* run the components' add() which may add other components\n        // and trigger onUse()\n        _k.game.gameObjEvents.trigger(\"add\", obj);\n        obj.trigger(\"add\", obj);\n\n        return obj;\n    },\n\n    addPrefab<T extends CompList<unknown>>(\n        name: string | SerializedGameObj,\n        comps?: T,\n    ) {\n        if (this.id === null) {\n            throw new Error(\"Can't add child to destroyed object\");\n        }\n\n        let data: SerializedGameObj;\n\n        if (typeof name === \"string\") {\n            const prefabAsset = _k.assets.prefabAssets.get(name);\n\n            if (prefabAsset) {\n                data = prefabAsset.data!;\n            }\n            else {\n                throw new Error(`Can't add unknown prefab named ${name}`);\n            }\n        }\n        else {\n            data = name;\n        }\n\n        const deserializedCompList = deserializePrefabAsset(data);\n        if (comps) deserializedCompList.push(...comps as Comp[]);\n\n        const obj = this.add(deserializedCompList) as GameObj<T[number]>;\n\n        if (data.children) {\n            for (const child of data.children) {\n                obj.addPrefab(child);\n            }\n        }\n\n        return obj;\n    },\n\n    serialize(this: InternalGameObjRaw) {\n        if (this.id === null) {\n            throw new Error(\"Can't serialize destroyed object\");\n        }\n\n        const data: SerializedGameObj = {\n            components: {},\n            tags: [],\n        };\n\n        for (const [id, c] of this._compStates) {\n            if (\"serialize\" in c) {\n                data.components[id] = (c.serialize as () => any)();\n            }\n        }\n\n        if (this.children.length > 0) {\n            data.children = [];\n\n            for (const children of this.children) {\n                data.children.push(children.serialize());\n            }\n        }\n\n        data.tags = [...this.tags];\n\n        return data;\n    },\n\n    readd<T>(this: InternalGameObjRaw, obj: GameObj<T>): GameObj<T> {\n        const idx = this.children.indexOf(obj);\n\n        if (idx !== -1) {\n            this.children.splice(idx, 1);\n            this.children.push(obj);\n        }\n\n        return obj;\n    },\n\n    remove(this: InternalGameObjRaw, obj: GameObj): void {\n        obj.parent = null;\n\n        const trigger = (o: GameObj) => {\n            o.trigger(\"destroy\");\n            o.clearEvents();\n            _k.game.gameObjEvents.trigger(\"destroy\", o);\n            o.children.forEach((child) => trigger(child));\n            o.id = null as any;\n        };\n\n        trigger(obj);\n    },\n\n    removeAll(this: InternalGameObjRaw, tag?: Tag): void {\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    destroy(this: InternalGameObjRaw) {\n        if (this.parent) {\n            this.parent.remove(this);\n        }\n    },\n\n    exists(this: InternalGameObjRaw) {\n        return this.id !== null && this.parent !== null;\n    },\n\n    isAncestorOf(this: InternalGameObjRaw, obj: GameObj) {\n        if (!obj.parent) {\n            return false;\n        }\n        return obj.parent === this || this.isAncestorOf(obj.parent);\n    },\n    // #endregion\n\n    // #region Get & Query\n    get<T = any>(\n        this: InternalGameObjRaw,\n        t: Tag | Tag[],\n        opts: GetOpt = {},\n    ): GameObj<T>[] {\n        const compIdAreTags = _k.globalOpt.tagComponentIds;\n\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) => t ? checkTagsOrComps(child, t) : true);\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: clean up when obj destroyed\n            events.push(_k.sceneScope.onAdd((obj) => {\n                if (isChild(obj) && checkTagsOrComps(obj, t)) {\n                    list.push(obj);\n                }\n            }));\n            events.push(_k.sceneScope.onDestroy((obj) => {\n                if (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            // If tags are components, we need to use these callbacks, whether watching tags or components\n            // If tags are not components, we only need to use these callbacks if this query looks at components\n            if (compIdAreTags || opts.only !== \"tags\") {\n                events.push(_k.sceneScope.onUse((obj, id) => {\n                    if (isChild(obj) && checkTagsOrComps(obj, t)) {\n                        const idx = list.findIndex((o) => o.id === obj.id);\n                        if (idx == -1) {\n                            list.push(obj);\n                        }\n                    }\n                }));\n                events.push(_k.sceneScope.onUnuse((obj, id) => {\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            }\n            // If tags are components, we don't need to use these callbacks\n            // If tags are not components, we only need to use these callbacks if this query looks at tags\n            if (!compIdAreTags && opts.only !== \"comps\") {\n                events.push(_k.sceneScope.onTag((obj, tag) => {\n                    if (isChild(obj) && checkTagsOrComps(obj, t)) {\n                        const idx = list.findIndex((o) => o.id === obj.id);\n                        if (idx == -1) {\n                            list.push(obj);\n                        }\n                    }\n                }));\n                events.push(_k.sceneScope.onUntag((obj, tag) => {\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            }\n            this.onDestroy(() => {\n                for (const ev of events) {\n                    ev.cancel();\n                }\n            });\n        }\n\n        return list as GameObj<T>[];\n    },\n\n    query(this: GameObjTransform, 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) => o !== this)\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 => o.pos && this.pos.sdist(o.pos) > sdist);\n            }\n        }\n        if (opt.name) {\n            list = list.filter(o => o.name === opt.name);\n        }\n        return list;\n    },\n    // #endregion\n\n    // #region Lifecycle\n    update(this: GameObj<LayerComp> & InternalGameObjRaw) {\n        if (this.paused) return;\n        this._updateEvents.trigger();\n        this._drawLayerIndex = this.layerIndex\n            ?? (this.parent\n                ? this.parent._drawLayerIndex\n                : _k.game.defaultLayerIndex);\n        const children = this.children.slice();\n        for (let i = 0; i < children.length; i++) {\n            children[i].update();\n        }\n    },\n\n    fixedUpdate(this: InternalGameObjRaw) {\n        if (this.paused) return;\n        this._fixedUpdateEvents.trigger();\n        const children = this.children.slice();\n        for (let i = 0; i < children.length; i++) {\n            children[i].fixedUpdate();\n        }\n    },\n\n    draw(this: InternalGameObjRaw) {\n        this.drawTree();\n    },\n\n    drawTree(this: GameObjCamTransform) {\n        if (this.hidden) return;\n\n        const objects = new Array<\n            & GameObj<LayerComp | ZComp | FixedComp | MaskComp>\n            & InternalGameObjRaw\n        >();\n\n        // For each child call collect\n        for (let i = 0; i < this.children.length; i++) {\n            if (this.children[i].hidden) continue;\n            this.children[i].collect(objects);\n        }\n\n        // Sort objects on layer, then z\n        objects.sort((o1, o2) => {\n            const l1 = o1._drawLayerIndex;\n            const l2 = o2._drawLayerIndex;\n            return (l1 - l2) || (o1.z ?? 0) - (o2.z ?? 0);\n        });\n\n        // If this subtree is masking, the root is drawn into the mask, then the children are drawn\n        if (this.mask) {\n            const maskFunc = {\n                intersect: drawMasked,\n                subtract: drawSubtracted,\n            }[this.mask];\n            if (!maskFunc) {\n                throw new Error(`Invalid mask func: \"${this.mask}\"`);\n            }\n            maskFunc(() => {\n                // Draw children masked\n                const f = _k.gfx.fixed;\n                // We push once, then update the current transform only\n                pushTransform();\n                for (let i = 0; i < objects.length; i++) {\n                    _k.gfx.fixed = isFixed(objects[i]);\n                    loadMatrix(objects[i].transform);\n                    objects[i]._drawEvents.trigger();\n                }\n                popTransform();\n                _k.gfx.fixed = f;\n            }, () => {\n                pushTransform();\n                loadMatrix(this.transform);\n                // Draw mask\n                this._drawEvents.trigger();\n                popTransform();\n            });\n        }\n        else {\n            // If this subtree is rendered to a target, enable target\n            if (this.target) {\n                if (!this.target?.refreshOnly || !this.target?.isFresh) {\n                    flush();\n                    if (this.target.destination instanceof FrameBuffer) {\n                        this.target.destination.bind();\n                    }\n                    else if (this.target.destination instanceof Picture) {\n                        beginPicture(this.target.destination);\n                    }\n                }\n            }\n\n            if (!this.target?.refreshOnly || !this.target?.isFresh) {\n                const f = _k.gfx.fixed;\n                pushTransform();\n                // Parent is drawn before children if !childrenOnly\n                if (!this.target?.childrenOnly) {\n                    _k.gfx.fixed = isFixed(this);\n                    loadMatrix(this.transform);\n                    this._drawEvents.trigger();\n                }\n                // Draw children\n                for (let i = 0; i < objects.length; i++) {\n                    // An object with a mask is drawn at draw time, but the transform still needs to be calculated,\n                    // so we push the parent's transform and pretend we are\n                    _k.gfx.fixed = isFixed(objects[i]);\n                    if (objects[i].mask) {\n                        loadMatrix(objects[i].parent!.transform);\n                        objects[i].drawTree();\n                    }\n                    else {\n                        loadMatrix(objects[i].transform);\n                        objects[i]._drawEvents.trigger();\n                    }\n                }\n                popTransform();\n                _k.gfx.fixed = f;\n            }\n\n            // If this subtree is rendered to a target, disable target\n            if (this.target) {\n                if (!this.target?.refreshOnly || !this.target?.isFresh) {\n                    flush();\n                    if (this.target.destination instanceof FrameBuffer) {\n                        this.target.destination.unbind();\n                    }\n                    else if (this.target.destination instanceof Picture) {\n                        endPicture();\n                    }\n                }\n            }\n\n            // If this object needs the refresh flag in order to draw children, set it to fresh\n            if (this.target?.refreshOnly && !this.target?.isFresh) {\n                this.target.isFresh = true;\n            }\n\n            // If children only flag is on\n            if (this.target?.childrenOnly) {\n                // Parent is drawn on screen, children are drawn in target\n                const f = _k.gfx.fixed;\n                _k.gfx.fixed = isFixed(this);\n                pushTransform();\n                loadMatrix(this.transform);\n                this._drawEvents.trigger();\n                popTransform();\n                _k.gfx.fixed = f;\n            }\n        }\n    },\n\n    inspect(this: InternalGameObjRaw): GameObjInspect {\n        const info = {} as GameObjInspect;\n\n        for (const [tag, comp] of this._compStates) {\n            info[tag] = comp.inspect?.() ?? null;\n        }\n\n        for (const [i, comp] of this._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    drawInspect(this: GameObj<PosComp | ScaleComp | RotateComp>) {\n        if (this.hidden) return;\n\n        for (let i = 0; i < this.children.length; i++) {\n            this.children[i].drawInspect();\n        }\n\n        loadMatrix(this.transform);\n        this.trigger(\"drawInspect\");\n    },\n\n    transformTree(\n        this:\n            & GameObj<\n                | PosComp\n                | ScaleComp\n                | RotateComp\n                | SkewComp\n                | FixedComp\n                | MaskComp\n            >\n            & InternalGameObjRaw,\n        force: boolean,\n    ) {\n        const localUpdateNeeded = transformNeedsUpdate(this._transformVersion);\n        const updateNeeded = force || localUpdateNeeded;\n\n        pushTransform();\n\n        if (updateNeeded) {\n            if (this.pos) multTranslateV(this.pos);\n            if (this.angle) multRotate(this.angle);\n            if (this.scale) multScaleV(this.scale);\n\n            if (this.skew) multSkewV(this.skew);\n\n            if (!this.transform) this.transform = new Mat23();\n            storeMatrix(this.transform);\n\n            // If force is true, but we didn't have a newer version,\n            // we need to update the version in order to make sure that areas get updated.\n            if (force && !localUpdateNeeded) {\n                this._transformVersion = nextTransformVersion();\n            }\n        }\n        else {\n            loadMatrix(this.transform);\n        }\n\n        this._treeIndex = _nextTreeIndex++;\n\n        for (let i = 0; i < this.children.length; i++) {\n            // if (this.children[i].hidden) continue;\n            this.children[i].transformTree(updateNeeded);\n        }\n\n        popTransform();\n    },\n\n    collect(\n        this: GameObj<\n            PosComp | ScaleComp | RotateComp | FixedComp | MaskComp\n        >,\n        objects: GameObj<any>[],\n    ) {\n        // Add to objects\n        objects.push(this);\n\n        // Recurse on children\n        for (let i = 0; i < this.children.length; i++) {\n            // While we could do this test in collect, it would mean an extra function call\n            // so it is better to do this preemptively\n            if (this.children[i].hidden) continue;\n            if (this.target) {\n                this.drawTree();\n            }\n            else if (!this.mask) {\n                this.children[i].collect(objects);\n            }\n        }\n    },\n    // #endregion\n\n    // #region Comps\n    _addComp(comp: Comp) {\n        const addCompIdAsTag = this.id == 0\n            ? false\n            : _k.globalOpt.tagComponentIds;\n\n        /** Garbage Collector */\n        if (comp.id) this._compsIds.add(comp.id);\n        let gc: GarbageCollectorArray;\n\n        // If that component got an ID, we need to create the cleanups[compId]\n        // data for cleaning later on removing\n        if (comp.id) {\n            gc = this._cleanups[comp.id] = [];\n            this._compStates.set(comp.id, comp);\n        }\n        else {\n            gc = [];\n            this._anonymousCompStates.push(comp);\n        }\n\n        // We assign every property to the GameObj prototype\n        for (const key in comp) {\n            // These are properties from the component data (id, require), shouldn't\n            // be added to the game obj prototype, that's why we continue\n            if (COMP_DESC.has(key)) {\n                continue;\n            }\n\n            const prop = Object.getOwnPropertyDescriptor(comp, key);\n            if (!prop) continue;\n\n            if (typeof prop.value === \"function\") {\n                // @ts-expect-error Yeah\n                comp[key] = comp[key].bind(this);\n            }\n\n            if (prop.set) {\n                Object.defineProperty(comp, key, {\n                    set: prop.set.bind(this),\n                });\n            }\n\n            if (prop.get) {\n                Object.defineProperty(comp, key, {\n                    get: prop.get.bind(this),\n                });\n            }\n\n            // For component events: add, update, destroy\n            if (COMP_EVENTS.has(key)) {\n                // Automatically clean up events created by components in add() stage\n                if (key == \"add\") {\n                    const func = () => {\n                        this._onCurCompCleanup = (c: any) => gc.push(c);\n                        comp[key]?.();\n                        this._onCurCompCleanup = null;\n                    };\n\n                    gc.push(this.on(key, <any> func).cancel);\n                }\n                else {\n                    const func = comp[<keyof typeof comp> key];\n\n                    gc.push(this.on(key, <any> func).cancel);\n                }\n            }\n            else {\n                // @ts-ignore\n                if (this[key] === undefined) {\n                    // Assign comp fields to game obj\n                    Object.defineProperty(this, key, {\n                        get: () => comp[<keyof typeof comp> key],\n                        set: (val) => comp[<keyof typeof comp> key] = val,\n                        configurable: true,\n                        enumerable: true,\n                    });\n                    // @ts-ignore\n                    gc.push(() => delete this[key]);\n                }\n                else {\n                    const originalCompId = this._compStates.values().find(c =>\n                        (c as any)[key] !== undefined\n                    )?.id;\n                    throw new Error(\n                        `Duplicate component property: \"${key}\" while adding component \"${comp.id}\"`\n                            + (originalCompId\n                                ? ` (originally added by \"${originalCompId}\")`\n                                : \"\"),\n                    );\n                }\n            }\n        }\n\n        // We add it to gc in case of obj.unuse()\n        if (comp.destroy) {\n            gc.push(comp.destroy.bind(this));\n        }\n\n        if (comp.id && addCompIdAsTag) {\n            this.tag(comp.id);\n        }\n\n        // If the object already exists and add hook is present, run it\n        if (this.exists() && comp.add) {\n            this._onCurCompCleanup = (c: any) => gc.push(c);\n            comp.add.call(this);\n            this._onCurCompCleanup = null;\n        }\n\n        if (\n            this.id != 0 && comp.id\n            && !internalIsMaking(this as unknown as GameObj)\n        ) {\n            this.trigger(\"use\", comp.id);\n            _k.game.gameObjEvents.trigger(\n                \"use\",\n                this as unknown as GameObj,\n                comp.id,\n            );\n        }\n    },\n\n    _removeComp(this: InternalGameObjRaw, id) {\n        const addCompIdAsTag = this.id === 0\n            ? false\n            : _k.globalOpt.tagComponentIds;\n\n        this._compsIds.delete(id);\n        this._compStates.delete(id);\n        if (addCompIdAsTag) this._tags.delete(id);\n\n        if (!internalIsMaking(this as unknown as GameObj)) {\n            this.trigger(\"unuse\", id);\n            _k.game.gameObjEvents.trigger(\"unuse\", this, id);\n        }\n\n        if (this._cleanups[id]) {\n            this._cleanups[id].forEach((e) => e());\n            delete this._cleanups[id];\n        }\n    },\n\n    _checkDependencies(comp: Comp) {\n        if (!comp.require) return;\n\n        for (const dep of comp.require) {\n            if (!this._compsIds.has(dep)) {\n                throwError(\n                    `Component \"${comp.id}\" requires component \"${dep}\"`,\n                );\n            }\n        }\n    },\n\n    _checkDependents(compId: string) {\n        for (const comp of this._compStates.values()) {\n            if (comp.require && comp.require.includes(compId)) {\n                throwError(\n                    `Can't remove ${compId} component, it is required by \"${comp.id}\" component\"`,\n                );\n            }\n        }\n    },\n\n    use(this: InternalGameObjRaw, comp: Comp) {\n        if (!comp || typeof comp != \"object\") {\n            throw new Error(\n                `You can only pass objects to .use(), you passed a \"${typeof comp}\"`,\n            );\n        }\n\n        if (comp.id && this.has(comp.id)) {\n            this._removeComp(comp.id);\n        }\n\n        this._addComp(comp);\n        this._checkDependencies(comp);\n    },\n\n    // Remove components\n    unuse(this: InternalGameObjRaw, id: string) {\n        if (!this.has(id)) return;\n\n        this._removeComp(id);\n        this._checkDependents(id);\n    },\n\n    has(\n        this: InternalGameObjRaw,\n        compList: string | string[],\n        op: \"and\" | \"or\" = \"and\",\n    ): boolean {\n        if (Array.isArray(compList)) {\n            if (op === \"and\") {\n                return compList.every((c) => this._compStates.has(c));\n            }\n            else {\n                return compList.some(c => this._compStates.has(c));\n            }\n        }\n        else {\n            return this._compStates.has(compList);\n        }\n    },\n\n    c(this: InternalGameObjRaw, id: string): Comp | null {\n        return this._compStates.get(id) ?? null;\n    },\n\n    // #endregion\n\n    // #region Tags\n    tag(this: InternalGameObjRaw, tag: Tag | Tag[]): void {\n        if (Array.isArray(tag)) {\n            for (const t of tag) {\n                this._tags.add(t);\n                if (!internalIsMaking(this as unknown as GameObj)) {\n                    this.trigger(\"tag\", t);\n                    _k.game.gameObjEvents.trigger(\"tag\", this as GameObj, t);\n                }\n            }\n        }\n        else {\n            this._tags.add(tag);\n            if (!internalIsMaking(this as unknown as GameObj)) {\n                this.trigger(\"tag\", tag);\n                _k.game.gameObjEvents.trigger(\"tag\", this as GameObj, tag);\n            }\n        }\n    },\n\n    untag(this: InternalGameObjRaw, tag: Tag | Tag[]): void {\n        if (Array.isArray(tag)) {\n            for (const t of tag) {\n                this._tags.delete(t);\n                this.trigger(\"untag\", t);\n                _k.game.gameObjEvents.trigger(\"untag\", this, t);\n            }\n        }\n        else {\n            this._tags.delete(tag);\n            this.trigger(\"untag\", tag);\n            _k.game.gameObjEvents.trigger(\"untag\", this, tag);\n        }\n    },\n\n    is(\n        this: InternalGameObjRaw,\n        tag: Tag | Tag[],\n        op: \"or\" | \"and\" = \"and\",\n    ): boolean {\n        if (Array.isArray(tag)) {\n            if (op === \"and\") {\n                return tag.every(tag => this._tags.has(tag));\n            }\n            else {\n                return tag.some(tag => this._tags.has(tag));\n            }\n        }\n        else {\n            return this._tags.has(tag);\n        }\n    },\n    // #endregion\n\n    // #region Events\n    on(\n        this: InternalGameObjRaw,\n        name: string,\n        action: (...args: unknown[]) => void,\n    ): KEventController {\n        const ctrl = ((func) => {\n            switch (name) {\n                case \"fixedUpdate\":\n                    return this._fixedUpdateEvents.add(func);\n                case \"update\":\n                    return this._updateEvents.add(func);\n                case \"draw\":\n                    return this._drawEvents.add(func);\n                default:\n                    return this._events.on(name, func);\n            }\n        })(action.bind(this));\n\n        if (this._onCurCompCleanup) {\n            this._onCurCompCleanup(() => ctrl.cancel());\n        }\n\n        return ctrl;\n    },\n\n    trigger(this: InternalGameObjRaw, name: string, ...args: unknown[]): void {\n        this._events.trigger(name, ...args);\n    },\n\n    clearEvents(this: InternalGameObjRaw) {\n        this._events.clear();\n        this._drawEvents.clear();\n        this._updateEvents.clear();\n        this._fixedUpdateEvents.clear();\n        while (this._inputEvents.length) this._inputEvents.pop()?.cancel();\n    },\n    // #endregion\n\n    // #region Helper Events\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    onTag(action: (id: string) => void): KEventController {\n        return this.on(\"tag\", action);\n    },\n\n    onUntag(action: (id: string) => void): KEventController {\n        return this.on(\"untag\", 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    // #endregion\n};\n", "import { _k } from \"../../shared\";\n\n/**\n * @group Plugins\n */\nexport type System = {\n    name: string;\n    run: () => void;\n    when: SystemPhase[];\n};\n\nexport enum SystemPhase {\n    BeforeUpdate,\n    BeforeFixedUpdate,\n    BeforeDraw,\n    AfterUpdate,\n    AfterFixedUpdate,\n    AfterDraw,\n}\n\nexport const system = (\n    name: string,\n    action: () => void,\n    when: SystemPhase[],\n) => {\n    const systems = _k.game.systems;\n    const replacingSystemIdx = systems.findIndex((s) => s.name === name);\n\n    // if existent system, remove it\n    if (replacingSystemIdx != -1) {\n        const replacingSystem = systems[replacingSystemIdx];\n        const when = replacingSystem.when;\n\n        for (const loc of when) {\n            const idx = _k.game.systemsByEvent[loc].findIndex(\n                (s) => s.name === name,\n            );\n            _k.game.systemsByEvent[loc].splice(idx, 1);\n        }\n    }\n\n    const system: System = {\n        name,\n        run: action,\n        when,\n    };\n\n    for (const loc of when) {\n        _k.game.systemsByEvent[loc].push(system);\n    }\n\n    systems.push({ name, run: action, when });\n};\n", "import { DEF_ANCHOR } from \"../../../constants/general\";\nimport type { KEventController } from \"../../../events/events\";\nimport { toWorld } from \"../../../game/camera\";\nimport { anchorPt } from \"../../../gfx/anchor\";\nimport { drawCircle } from \"../../../gfx/draw/drawCircle\";\nimport { drawPolygon } from \"../../../gfx/draw/drawPolygon\";\nimport { drawRect } from \"../../../gfx/draw/drawRect\";\nimport { multTranslate, popTransform, pushTransform } from \"../../../gfx/stack\";\nimport { rgb } from \"../../../math/color\";\nimport { Circle, Polygon, Rect, shapeFactory, vec2 } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type {\n    Comp,\n    Cursor,\n    GameObj,\n    MouseButton,\n    Shape,\n    Tag,\n} from \"../../../types\";\nimport {\n    type InternalGameObjRaw,\n    objectTransformNeedsUpdate,\n} from \"../../entity/GameObjRaw\";\nimport { exists, isFixed } from \"../../entity/utils\";\nimport type { Collision } from \"../../systems/Collision\";\nimport { system, SystemPhase } from \"../../systems/systems\";\nimport type { AnchorComp } from \"../transform/anchor\";\nimport type { FixedComp } from \"../transform/fixed\";\nimport type { PosComp } from \"../transform/pos\";\nimport type { ZComp } from \"../transform/z\";\n\nexport function usesArea() {\n    return _k.game.areaCount > 0;\n}\n\nlet _nextRenderAreaVersion = 0;\n\nexport function nextRenderAreaVersion() {\n    return _nextRenderAreaVersion++;\n}\n\nlet _nextLocalAreaVersion = 0;\n\nexport function nextLocalAreaVersion() {\n    return _nextLocalAreaVersion++;\n}\n\nlet _nextWorldAreaVersion = 0;\n\nexport function nextWorldAreaVersion() {\n    return _nextWorldAreaVersion++;\n}\n\nexport function getRenderAreaVersion(obj: GameObj<any>) {\n    return obj._renderAreaVersion;\n}\n\nexport function getLocalAreaVersion(obj: GameObj<any>) {\n    return obj._localAreaVersion;\n}\n\nlet _topMostOnlyActivate = false;\nexport function _setTopMostOnlyActivate(value: boolean) {\n    _topMostOnlyActivate = value;\n}\n\nfunction clickHandler(button: MouseButton) {\n    const screenPos = _k.app.mousePos();\n    const worldPos = toWorld(screenPos);\n    const objects: Array<GameObj<AreaComp | ZComp>> = new Array();\n    // non-fixed objects\n    _k.game.retrieve(\n        new Rect(worldPos.sub(1, 1), 3, 3),\n        obj => {\n            if (\n                !(obj as unknown as GameObj<FixedComp>).fixed\n                && obj.worldArea().contains(worldPos)\n            ) objects.push(obj as GameObj<AreaComp | ZComp>);\n        },\n    );\n\n    // fixed objects\n    _k.game.retrieve(new Rect(screenPos.sub(1, 1), 3, 3), obj => {\n        if (\n            (obj as unknown as GameObj<FixedComp>).fixed\n            && obj.worldArea().contains(screenPos)\n        ) objects.push(obj as GameObj<AreaComp | ZComp>);\n    });\n\n    if (objects.length) {\n        if (_topMostOnlyActivate) {\n            objects.sort((o1, o2) => {\n                const l1 =\n                    (o1 as unknown as InternalGameObjRaw)._drawLayerIndex;\n                const l2 =\n                    (o2 as unknown as InternalGameObjRaw)._drawLayerIndex;\n                const to1 = (o1 as unknown as InternalGameObjRaw)._treeIndex;\n                const to2 = (o2 as unknown as InternalGameObjRaw)._treeIndex;\n                return (l1 - l2) || (o1.z ?? 0) - (o2.z ?? 0) || (to1 - to2);\n            });\n            const obj = objects.at(-1)!;\n            _k.game.gameObjEvents.trigger(\"click\", obj);\n            obj.trigger(\"click\", button);\n        }\n        else {\n            objects.forEach(obj => {\n                _k.game.gameObjEvents.trigger(\"click\", obj);\n                obj.trigger(\"click\", button);\n            });\n        }\n    }\n}\n\nlet clickHandlerRunning = false;\nexport function startClickHandler() {\n    if (clickHandlerRunning) return;\n    clickHandlerRunning = true;\n\n    if (_k.game.fakeMouse) {\n        _k.game.fakeMouse.on(\"press\", clickHandler);\n    }\n\n    _k.app.onMousePress(clickHandler);\n}\n\nfunction hoverHandler() {\n    let oldObjects: Set<GameObj<AreaComp>> = new Set();\n\n    return (screenPos: Vec2) => {\n        const worldPos = toWorld(screenPos);\n        const newObjects: Set<GameObj<AreaComp>> = new Set();\n\n        // non-fixed objects\n        _k.game.retrieve(new Rect(worldPos.sub(1, 1), 3, 3), obj => {\n            if (\n                !(obj as unknown as GameObj<FixedComp>).fixed\n                && obj.worldArea().contains(worldPos)\n            ) {\n                newObjects.add(obj);\n            }\n        });\n        // fixed objects\n        _k.game.retrieve(new Rect(screenPos.sub(1, 1), 3, 3), obj => {\n            if (\n                (obj as unknown as GameObj<FixedComp>).fixed\n                && obj.worldArea().contains(screenPos)\n            ) {\n                newObjects.add(obj);\n            }\n        });\n\n        newObjects.difference(oldObjects).forEach(obj => {\n            _k.game.gameObjEvents.trigger(\"hover\", obj);\n            obj.trigger(\"hover\");\n        });\n        oldObjects.difference(newObjects).forEach(obj => {\n            _k.game.gameObjEvents.trigger(\"hoverEnd\", obj);\n            obj.trigger(\"hoverEnd\");\n        });\n        newObjects.intersection(oldObjects).forEach(obj => {\n            _k.game.gameObjEvents.trigger(\"hoverUpdate\", obj);\n            obj.trigger(\"hoverUpdate\");\n        });\n        oldObjects = newObjects;\n    };\n}\n\n/*let hoverHandlerRunning = false;\nfunction startHoverHandler() {\n    if (hoverHandlerRunning) return;\n    hoverHandlerRunning = true;\n\n    if (_k.game.fakeMouse) {\n        _k.game.fakeMouse.on(\"fakeMouseMove\", hoverHandler());\n    }\n    _k.app.onMouseMove(hoverHandler());\n}*/\n\nlet systemInstalled = false;\nexport function startHoverSystem() {\n    if (systemInstalled) return;\n    systemInstalled = true;\n\n    const mouseHover = hoverHandler();\n    const fakeMouseHover = hoverHandler();\n\n    system(\"hover\", () => {\n        if (_k.game.fakeMouse) {\n            fakeMouseHover(_k.game.fakeMouse.screenPos);\n            return;\n        }\n\n        mouseHover(_k.app.mousePos());\n    }, [\n        SystemPhase.BeforeUpdate, // Because we need the transform to be up to date\n    ]);\n}\n\n/**\n * The {@link area `area()`} component.\n *\n * @group Components\n * @subgroup 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     * Restitution (\"bounciness\") of the object.\n     */\n    restitution?: number;\n    /**\n     * Friction of the object.\n     */\n    friction?: number;\n    /**\n     * Whether collision detection should be done even without body.\n     */\n    isSensor: boolean;\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     * Returns true if the objects collide in screen space\n     * @param other\n     */\n    isVisuallyColliding(other: 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) => void,\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(): Shape;\n    /**\n     * Get the bounding box of the geometry data for the collider in world coordinate space.\n     */\n    worldBbox(): Rect;\n    /**\n     * Get the geometry data for the collider in screen coordinate space.\n     */\n    screenArea(): Shape;\n\n    serialize(): any;\n}\n\n/**\n * Options for the {@link area `area()`} component.\n *\n * @group Components\n * @subgroup 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     * Bounciness factor between 0 and 1.\n     *\n     * @since v4000.0\n     */\n    restitution?: number;\n    /**\n     * Friction factor between 0 and 1.\n     *\n     * @since v4000.0\n     */\n    friction?: number;\n    /**\n     * Whether collision detection should be done even without body.\n     *\n     * @since v4000.0\n     */\n    isSensor?: boolean;\n}\n\nexport function area(\n    opt: AreaCompOpt = {},\n): AreaComp & { _localAreaVersion: number } {\n    // The id => collision map of objects colliding with this object\n    const colliding: Record<string, Collision> = {};\n    // The ids of the objects which are colliding with this object during this frame\n    const collidingThisFrame = new Set();\n    // Events to cancel in destroy when the component gets removed\n    const events: KEventController[] = [];\n    // We overwrite the shape rather than allocating a new one\n    let _worldShape: Shape | undefined;\n    let _worldBBox: Rect | undefined;\n    let _screenShape: Shape | undefined;\n\n    let _shape: Shape | null = opt.shape ?? null;\n    let _scale: Vec2 = opt.scale ? vec2(opt.scale) : vec2(1);\n    let _offset: Vec2 = opt.offset ?? vec2(0);\n    let _cursor: Cursor | null = opt.cursor ?? null;\n\n    let _localAreaVersion = -1; // Track local changes in area properties\n    let _worldAreaVersion = -1; // Track local changes in world area\n    let _worldBBoxVersion = -1; // Track world area changes for bbox\n    let _cachedTransformVersion = -1; // Currently used transform\n    let _cachedRenderAreaVersion = -1; // Currently used render shape\n    let _cachedLocalAreaVersion = -1; // Currently used local area\n\n    return {\n        id: \"area\",\n        collisionIgnore: opt.collisionIgnore ?? [],\n        restitution: opt.restitution,\n        friction: opt.friction,\n        isSensor: opt.isSensor ?? false,\n\n        add(this: GameObj<AreaComp>) {\n            _k.game.areaCount++;\n            if (this.area.cursor) {\n                events.push(\n                    this.onHover(() => _k.app.setCursor(this.area.cursor!)),\n                );\n            }\n\n            events.push(\n                this.onCollideUpdate((obj, col) => {\n                    if (!exists(obj)) return;\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\n        destroy() {\n            _k.game.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            multTranslate(this.area.offset.x, this.area.offset.y);\n\n            const opts = {\n                outline: {\n                    width: 4 / _k.gfx.viewport.scale,\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        get _localAreaVersion() {\n            return _localAreaVersion;\n        },\n\n        area: {\n            set shape(value: Shape | null) {\n                _shape = value;\n                _localAreaVersion = nextLocalAreaVersion();\n            },\n            get shape(): Shape | null {\n                return _shape;\n            },\n            set scale(value: Vec2) {\n                _scale = this.scale;\n                _localAreaVersion = nextLocalAreaVersion();\n            },\n            get scale(): Vec2 {\n                return _scale;\n            },\n            set offset(value: Vec2) {\n                _offset = value;\n                _localAreaVersion = nextLocalAreaVersion();\n            },\n            get offset() {\n                return _offset;\n            },\n            set cursor(value: Cursor | null) {\n                _cursor = value;\n                // TODO: attach/detach hover\n            },\n            get cursor(): Cursor | null {\n                return _cursor;\n            },\n        },\n\n        isClicked(): boolean {\n            if (_k.game.fakeMouse) {\n                return _k.game.fakeMouse.isPressed && this.isHovering();\n            }\n\n            return _k.app.isMousePressed() && this.isHovering();\n        },\n\n        isHovering(this: GameObj<AreaComp>) {\n            if (_k.game.fakeMouse) {\n                const mpos = isFixed(this)\n                    ? _k.game.fakeMouse.pos\n                    : toWorld(_k.game.fakeMouse.pos);\n\n                return this.hasPoint(mpos);\n            }\n\n            const mpos = isFixed(this)\n                ? _k.app.mousePos()\n                : toWorld(_k.app.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(\n            this: GameObj<AreaComp>,\n            otherOrTag: GameObj<AreaComp> | string,\n        ) {\n            if (typeof otherOrTag === \"string\") {\n                return this.getCollisions().some(c =>\n                    c.source === this && c.target.is(otherOrTag)\n                    || c.target === this && c.source.is(otherOrTag)\n                );\n            }\n            else {\n                if (!otherOrTag.id) {\n                    /*throw new Error(\n                        \"isColliding() requires the object to have an id\",\n                    );*/\n                    return false;\n                }\n                return Boolean(colliding[otherOrTag.id]);\n            }\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        isVisuallyColliding(other) {\n            return this.screenArea().collides(other.screenArea());\n        },\n\n        onClick(\n            this: GameObj<AreaComp>,\n            action: () => void,\n            btn: MouseButton = \"left\",\n        ): KEventController {\n            startClickHandler();\n            return this.on(\"click\", action);\n        },\n\n        onHover(this: GameObj, action: () => void): KEventController {\n            startHoverSystem();\n            return this.on(\"hover\", action);\n        },\n\n        onHoverUpdate(this: GameObj, action: () => void): KEventController {\n            startHoverSystem();\n            return this.on(\"hoverUpdate\", action);\n        },\n\n        onHoverEnd(this: GameObj, action: () => void): KEventController {\n            startHoverSystem();\n            return this.on(\"hoverEnd\", action);\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(\"collideEnd\", (obj) => obj.is(tag) && cb?.(obj));\n            }\n            else {\n                throw new Error(\n                    \"onCollideEnd() requires either a function or a tag\",\n                );\n            }\n        },\n\n        hasPoint(\n            this: GameObj<AreaComp | PosComp | AnchorComp>,\n            pt: Vec2,\n        ): boolean {\n            const localArea = this.localArea();\n            pt = this.transform.inverse.transform(pt);\n            Vec2.sub(pt, this.area.offset, pt);\n            Vec2.scalec(pt, 1 / this.area.scale.x, 1 / this.area.scale.y, pt);\n            if (localArea instanceof Rect && this.anchor !== \"topleft\") {\n                const offset = anchorPt(this.anchor || DEF_ANCHOR)\n                    .add(1, 1)\n                    .scale(-0.5 * localArea.width, -0.5 * localArea.height);\n                Vec2.sub(pt, offset, pt);\n            }\n            return this.localArea().contains(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(this: GameObj<AreaComp | { renderArea(): Shape }>): Shape {\n            return this.area.shape ? this.area.shape : this.renderArea();\n        },\n\n        // TODO: cache\n        worldArea(this: GameObj<AreaComp | AnchorComp>): Shape {\n            const renderAreaVersion = getRenderAreaVersion(this);\n            if (\n                !_worldShape\n                || _cachedTransformVersion !== (this as any)._transformVersion // Transform changed\n                || (renderAreaVersion !== undefined // Render area (shape) changed\n                    && _cachedRenderAreaVersion !== renderAreaVersion) // Render area (shape) changed\n                || _cachedLocalAreaVersion !== _localAreaVersion // Area settings changed\n            ) {\n                const localArea = this.localArea();\n\n                // World transform\n                const transform = this.transform.clone();\n                // Optional area offset\n                if (this.area.offset.x !== 0 || this.area.offset.y !== 0) {\n                    transform.translateSelfV(this.area.offset);\n                }\n                // Optional area scale\n                if (this.area.scale.x !== 1 || this.area.scale.y !== 1) {\n                    transform.scaleSelfV(this.area.scale);\n                }\n                // Optional anchor offset (Rect only??)\n                if (localArea instanceof Rect && this.anchor !== \"topleft\") {\n                    const offset = anchorPt(this.anchor || DEF_ANCHOR)\n                        .add(1, 1)\n                        .scale(-0.5 * localArea.width, -0.5 * localArea.height);\n                    transform.translateSelfV(offset);\n                }\n\n                _worldShape = localArea.transform(transform, _worldShape);\n\n                _cachedTransformVersion = (this as any)._transformVersion;\n                _cachedRenderAreaVersion = renderAreaVersion ?? 0;\n                _cachedLocalAreaVersion = _localAreaVersion;\n                _worldAreaVersion = nextWorldAreaVersion();\n            }\n            return _worldShape;\n        },\n\n        worldBbox(this: GameObj<AreaComp>): Rect {\n            const renderAreaVersion = getRenderAreaVersion(this);\n            if (\n                !_worldBBox || _worldAreaVersion !== _worldBBoxVersion\n                || !_worldShape\n                || _cachedTransformVersion !== (this as any)._transformVersion // Transform changed\n                || (renderAreaVersion != undefined // Render area (shape) changed\n                    && _cachedRenderAreaVersion !== renderAreaVersion) // Render area (shape) changed\n                || _cachedLocalAreaVersion !== _localAreaVersion // Area settings changed\n            ) {\n                _worldBBox = this.worldArea().bbox(_worldBBox);\n                _worldBBoxVersion = _worldAreaVersion;\n            }\n            return _worldBBox;\n        },\n\n        screenArea(this: GameObj<AreaComp | FixedComp>): Shape {\n            const area = this.worldArea();\n            if (isFixed(this)) {\n                return area;\n            }\n            else {\n                return _screenShape = area.transform(\n                    _k.game.cam.transform,\n                    _screenShape,\n                );\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: (${\n                    this.area.scale?.x?.toFixed(\n                        1,\n                    )\n                }x, ${this.area.scale.y?.toFixed(1)}y)`;\n            }\n        },\n\n        serialize() {\n            const data: any = {};\n            if (this.area.shape) data.shape = this.area.shape.serialize();\n            if (this.area.scale) {\n                data.scale = this.area.scale instanceof Vec2\n                    ? this.area.scale.serialize()\n                    : opt.scale;\n            }\n            if (this.area.offset) data.offset = this.area.offset.serialize();\n            if (opt.cursor) data.cursor = opt.cursor;\n            // Make a copy, since it might be changed later\n            if (this.collisionIgnore) {\n                data.collisionIgnore = this.collisionIgnore.slice();\n            }\n            if (this.restitution) data.restitution = this.restitution;\n            if (this.friction) data.friction = this.friction;\n            return data;\n        },\n    };\n}\n\nexport function areaFactory(data: any) {\n    const opt: any = {};\n    if (data.shape) opt.shape = shapeFactory(data.shape);\n    if (data.scale) {\n        opt.scale = typeof data.scale === \"number\"\n            ? data.scale\n            : Vec2.deserialize(data.scale);\n    }\n    if (data.offset) opt.offset = Vec2.deserialize(data.offset);\n    if (data.cursor) opt.cursor = opt.cursor;\n    // Make a copy, since it might be changed later\n    if (data.collisionIgnore) {\n        opt.collisionIgnore = data.collisionIgnore.slice();\n    }\n    if (data.restitution) opt.restitution = data.restitution;\n    if (data.friction) opt.friction = data.friction;\n    return area(opt);\n}\n", "import { getRenderProps } from \"../../../game/utils\";\nimport { drawRect } from \"../../../gfx/draw/drawRect\";\nimport { Rect, vec2 } from \"../../../math/math\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\nimport type { FillComp } from \"./fill\";\n/**\n * The serialized {@link rect `rect()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedRectComp {\n    width: number;\n    height: number;\n    radius?: number | [number, number, number, number];\n    fill?: boolean;\n}\n\n/**\n * The {@link rect `rect()`} component.\n *\n * @group Components\n * @subgroup 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    serialize(): SerializedRectComp;\n}\n\n/**\n * Options for the {@link rect `rect()`} component.\n *\n * @group Components\n * @subgroup 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(\n    w: number,\n    h: number,\n    opt: RectCompOpt = {},\n): RectComp & { _renderAreaVersion: number } {\n    let _shape: Rect | undefined;\n    let _width = w;\n    let _height = h;\n    return {\n        id: \"rect\",\n        get width() {\n            return _width;\n        },\n        set width(value) {\n            if (_width != value) {\n                _width = value;\n                if (_shape) _shape.width = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get height() {\n            return _height;\n        },\n        set height(value) {\n            if (_height != value) {\n                _height = value;\n                if (_shape) _shape.height = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        radius: opt.radius || 0,\n        draw(this: GameObj<RectComp & FillComp>) {\n            drawRect(Object.assign(getRenderProps(this), {\n                width: _width,\n                height: _height,\n                radius: this.radius,\n                fill: this.fill ?? opt.fill,\n            }));\n        },\n        renderArea() {\n            if (!_shape) {\n                _shape = new Rect(vec2(0), _width, _height);\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n        _renderAreaVersion: 0,\n        inspect() {\n            return `rect: (${Math.ceil(_width)}w, ${Math.ceil(_height)}h)`;\n        },\n        serialize(this: GameObj<RectComp & FillComp>) {\n            const data: SerializedRectComp = { width: _width, height: _height };\n            if (this.radius) data.radius = this.radius;\n            if (this.fill ?? opt.fill) data.fill = opt.fill;\n            return data;\n        },\n    };\n}\n\nexport function rectFactory(data: SerializedRectComp) {\n    const opt: RectCompOpt = {};\n    if (data.radius) opt.radius = data.radius;\n    if (data.fill) opt.fill = data.fill;\n\n    return rect(\n        data.width,\n        data.height,\n        opt,\n    );\n}\n", "import type { Comp } from \"../../../types\";\n\n/**\n * The serialized {@link fixed `fixed()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedFixedComp {\n    fixed?: boolean;\n}\n\n/**\n * The {@link fixed `fixed()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface FixedComp extends Comp {\n    /**\n     * If the obj is unaffected by camera\n     */\n    fixed: boolean;\n\n    serialize(): SerializedFixedComp;\n}\n\nexport function fixed(fixed = true): FixedComp {\n    return {\n        id: \"fixed\",\n        fixed: fixed,\n        serialize() {\n            return { fixed: this.fixed };\n        },\n    };\n}\n\nexport function fixedFactory(data: SerializedFixedComp) {\n    return fixed(data.fixed);\n}\n", "import { color } from \"../ecs/components/draw/color\";\nimport { opacity } from \"../ecs/components/draw/opacity\";\nimport { rect } from \"../ecs/components/draw/rect\";\nimport { fixed } from \"../ecs/components/transform/fixed\";\nimport { destroy } from \"../ecs/entity/utils\";\nimport { center, height, width } from \"../gfx/stack\";\nimport { type Color, rgb } from \"../math/color\";\nimport { type Mat23, vec2, type Vec2Args } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport { _k } from \"../shared\";\nimport { deprecateMsg } from \"../utils/log\";\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(): Mat23 {\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 shake(intensity: number = 12) {\n    _k.game.cam.shake += intensity;\n}\n\nexport function toScreen(p: Vec2): Vec2 {\n    return _k.game.cam.transform.transformPointV(p, new Vec2());\n}\n\nexport function toWorld(p: Vec2): Vec2 {\n    return _k.game.cam.transform.inverse.transformPointV(p, new Vec2());\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\nexport function camTransform(): Mat23 {\n    deprecateMsg(\"camTransform\", \"getCamTransform\");\n\n    return getCamTransform();\n}\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", "import type { Shader, Uniform } from \"../assets/shader\";\nimport { IDENTITY_MATRIX } from \"../constants/math\";\nimport { getCamTransform } from \"../game/camera\";\nimport {\n    BlendMode,\n    type ImageSource,\n    type KAPLAYOpt,\n    type TextureOpt,\n} from \"../types\";\nimport { deepEq } from \"../utils/deepEq\";\nimport type { Picture } from \"./draw/drawPicture\";\n\nexport type GfxCtx = ReturnType<typeof initGfx>;\n\n/**\n * @group Rendering\n * @subgroup Canvas\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\n        const gl = ctx.gl;\n        const glText = ctx.gl.createTexture();\n\n        if (!glText) {\n            throw new Error(\"[rendering] 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 Rendering\n * @subgroup Shaders\n */\nexport type VertexFormat = {\n    name: string;\n    size: number;\n}[];\n\n/**\n * @group Rendering\n * @subgroup Canvas\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 | null = null;\n    curBlend: BlendMode = BlendMode.Normal;\n    curFixed: boolean | undefined = undefined;\n\n    picture: Picture | null = null;\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        vertices: number[],\n        indices: number[],\n        shader: Shader,\n        tex: Texture | null = null,\n        uniform: Uniform | null = null,\n        blend: BlendMode,\n        width: number,\n        height: number,\n        fixed: boolean,\n    ) {\n        // If we have a picture, redirect data to the picture instead\n        if (this.picture) {\n            const index = this.picture.indices.length;\n            const count = indices.length;\n            const indexOffset = this.picture.vertices.length / this.stride;\n            let l = vertices.length;\n            for (let i = 0; i < l; i++) {\n                this.picture.vertices.push(vertices[i]);\n            }\n            l = indices.length;\n            for (let i = 0; i < l; i++) {\n                this.picture.indices.push(indices[i] + indexOffset);\n            }\n            const material = {\n                tex: tex || undefined,\n                shader,\n                uniform: uniform || undefined,\n                blend,\n            };\n            if (this.picture.commands.length) {\n                const lastCommand =\n                    this.picture.commands[this.picture.commands.length - 1];\n                const lastMaterial = lastCommand.material;\n                if (\n                    lastMaterial.tex == material.tex\n                    && lastMaterial.shader == material.shader\n                    && lastMaterial.uniform == material.uniform\n                    && lastMaterial.blend == material.blend\n                ) {\n                    lastCommand.count += count;\n                    return;\n                }\n            }\n            const command = {\n                material,\n                index,\n                count,\n            };\n            this.picture.commands.push(command);\n            return;\n        }\n\n        // If texture, shader, blend mode or uniforms (including fixed) have changed, flush first\n        // If the buffers are full, flush first\n        if (\n            primitive !== this.curPrimitive\n            || tex !== this.curTex\n            || shader !== this.curShader\n            || ((this.curUniform != uniform)\n                && !deepEq(this.curUniform, uniform))\n            || blend !== this.curBlend\n            || fixed !== this.curFixed\n            || this.vqueue.length + vertices.length * this.stride\n                > this.maxVertices\n            || this.iqueue.length + indices.length > this.maxIndices\n        ) {\n            this.flush(width, height);\n            this.setBlend(blend);\n        }\n        const indexOffset = this.vqueue.length / this.stride;\n        let l = vertices.length;\n        for (let i = 0; i < l; i++) {\n            this.vqueue.push(vertices[i]);\n        }\n        l = indices.length;\n        for (let i = 0; i < l; i++) {\n            this.iqueue.push(indices[i] + indexOffset);\n        }\n        this.curPrimitive = primitive;\n        this.curShader = shader;\n        this.curTex = tex;\n        this.curUniform = uniform;\n        this.curFixed = fixed;\n    }\n\n    flush(width: number, height: number) {\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        // Bind vertex data\n        this.ctx.pushArrayBuffer(this.glVBuf);\n        gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.vqueue));\n\n        // Bind index data\n        this.ctx.pushElementArrayBuffer(this.glIBuf);\n        gl.bufferSubData(\n            gl.ELEMENT_ARRAY_BUFFER,\n            0,\n            new Uint16Array(this.iqueue),\n        );\n\n        // Set vertex format\n        this.ctx.setVertexFormat(this.vertexFormat);\n\n        // Bind Shader\n        this.curShader.bind();\n\n        // Send user uniforms\n        if (this.curUniform) {\n            this.curShader.send(this.curUniform);\n        }\n\n        // Send system uniforms\n        this.curShader.send({\n            width,\n            height,\n            camera: this.curFixed ? IDENTITY_MATRIX : getCamTransform(),\n            transform: IDENTITY_MATRIX,\n        });\n\n        // Bind texture\n        this.curTex?.bind();\n\n        // Draw vertex buffer using active indices\n        gl.drawElements(\n            this.curPrimitive,\n            this.iqueue.length,\n            gl.UNSIGNED_SHORT,\n            0,\n        );\n\n        // Unbind texture and shader\n        this.curTex?.unbind();\n        this.curShader.unbind();\n\n        // Unbind buffers\n        this.ctx.popArrayBuffer();\n        this.ctx.popElementArrayBuffer();\n\n        // Reset local buffers\n        this.vqueue.length = 0;\n        this.iqueue.length = 0;\n\n        // Increase draw\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    setBlend(blend: BlendMode) {\n        if (blend !== this.curBlend) {\n            const gl = this.ctx.gl;\n            this.curBlend = blend;\n            switch (this.curBlend) {\n                case BlendMode.Normal:\n                    gl.blendFuncSeparate(\n                        gl.ONE,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                        gl.ONE,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                    );\n                    break;\n                case BlendMode.Add:\n                    gl.blendFuncSeparate(\n                        gl.ONE,\n                        gl.ONE,\n                        gl.ONE,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                    );\n                    break;\n                case BlendMode.Multiply:\n                    gl.blendFuncSeparate(\n                        gl.DST_COLOR,\n                        gl.ZERO,\n                        gl.ONE,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                    );\n                    break;\n                case BlendMode.Screen:\n                    gl.blendFuncSeparate(\n                        gl.ONE_MINUS_DST_COLOR,\n                        gl.ONE,\n                        gl.ONE,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                    );\n                    break;\n                case BlendMode.Overlay:\n                    gl.blendFuncSeparate(\n                        gl.DST_COLOR,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                        gl.ONE,\n                        gl.ONE_MINUS_SRC_ALPHA,\n                    );\n            }\n        }\n    }\n}\n\n/**\n * @group Rendering\n * @subgroup Shaders\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        vertices: 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(\n            gl.ARRAY_BUFFER,\n            new Float32Array(vertices),\n            gl.STATIC_DRAW,\n        );\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, index?: GLuint, count?: GLuint): void {\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            index ?? this.count,\n            gl.UNSIGNED_SHORT,\n            count ?? 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: KAPLAYOpt = {}) {\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.enableVertexAttribArray(i);\n            gl.vertexAttribPointer(\n                i,\n                f.size,\n                gl.FLOAT,\n                false,\n                stride * 4,\n                offset,\n            );\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 { drawImageSourceAt } from \"../assets/utils\";\nimport { Quad, Rect, testRectRect } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport type { ImageSource, TexFilter } from \"../types\";\nimport { type GfxCtx, Texture } from \"./gfx\";\n\nexport type Frame = { tex: Texture; q: Quad; id: number };\n\nenum UsedCorner {\n    TOPRIGHT = 1,\n    BOTTOMLEFT = 2,\n}\n\ninterface TexMap {\n    tex: Texture;\n    el: HTMLCanvasElement;\n    ctx: CanvasRenderingContext2D;\n}\n\nclass FilterTexPacker {\n    _textures: Texture[] = [];\n    _big: Frame[] = [];\n    _used = new Map<number, {\n        rect: Rect;\n        tex: Texture;\n        used: number;\n    }>();\n    _curMap: TexMap = null as any;\n    _tex2Map = new Map<Texture, TexMap>();\n\n    constructor(\n        private _p: TexPacker,\n        private _f: TexFilter,\n        private _gfx: GfxCtx,\n        private _w: number,\n        private _h: number,\n        private _pad: number,\n    ) {\n        this._newTexture();\n    }\n\n    private _hasPendingRefresh = false;\n    private _newTexture(): TexMap {\n        this._sync();\n        const el = document.createElement(\"canvas\");\n        el.width = this._w;\n        el.height = this._h;\n        const tex = Texture.fromImage(this._gfx, el, { filter: this._f });\n        this._textures.push(tex);\n\n        const ctx = el.getContext(\"2d\");\n        if (!ctx) throw new Error(\"Failed to get 2d context\");\n\n        this._tex2Map.set(tex, this._curMap = { tex, el, ctx });\n        return this._curMap;\n    }\n    _sync() {\n        if (this._hasPendingRefresh) {\n            this._curMap.tex.update(this._curMap.el);\n            this._hasPendingRefresh = false;\n        }\n    }\n\n    _single(img: ImageSource): Frame {\n        const f = this._p._saveFrame(\n            this,\n            Texture.fromImage(this._gfx, img, { filter: this._f }),\n            new Quad(0, 0, 1, 1),\n        );\n        this._big.push(f);\n        return f;\n    }\n\n    _blit(\n        img: ImageSource,\n        x: number,\n        y: number,\n        chopX: number,\n        chopY: number,\n        imgWidth: number,\n        imgHeight: number,\n    ) {\n        const curCtx = this._curMap.ctx;\n        drawImageSourceAt(\n            curCtx,\n            img,\n            x,\n            y,\n            chopX,\n            chopY,\n            imgWidth,\n            imgHeight,\n        );\n        this._hasPendingRefresh = true;\n    }\n\n    _add(img: ImageSource, chopQuad: Quad | undefined): Frame {\n        const imgWidth = img.width * (chopQuad?.w ?? 1);\n        const imgHeight = img.height * (chopQuad?.h ?? 1);\n        const chopX = img.width * (chopQuad?.x ?? 0);\n        const chopY = img.height * (chopQuad?.y ?? 0);\n        const pad = this._pad;\n        const paddedWidth = imgWidth + pad;\n        const paddedHeight = imgHeight + pad;\n        let { el: curEl, ctx: curCtx, tex: curTex } = this._curMap;\n\n        const maxX = curEl.width, maxY = curEl.height;\n        const rectToAdd = new Rect(new Vec2(), paddedWidth, paddedHeight);\n        const p = rectToAdd.pos;\n\n        if (paddedWidth > maxX || paddedHeight > maxY) {\n            // No chance of ever fitting.\n            return this._single(img);\n        }\n\n        // find position\n        let x = pad, y = pad, found = false;\n        const doesitfit = () => {\n            // goes offscreen?\n            if (x + paddedWidth > maxX || y + paddedHeight > maxY) return false;\n            // try it\n            p.set(x, y);\n            for (let { rect, tex } of this._used.values()) {\n                if (curTex !== tex) continue;\n                if (testRectRect(rect, rectToAdd)) return false;\n            }\n            return found = true;\n        };\n\n        // initial check for (0, 0)\n        if (!doesitfit()) {\n            for (let entry of this._used.values()) {\n                const { tex, rect: { pos, width, height }, used } = entry;\n                if (curTex !== tex) continue;\n                // try to the right\n                if ((used & UsedCorner.TOPRIGHT) === 0) {\n                    x = pos.x + width;\n                    y = pos.y;\n                    if (doesitfit()) {\n                        entry.used |= UsedCorner.TOPRIGHT;\n                        break;\n                    }\n                }\n                // try below\n                if ((used & UsedCorner.BOTTOMLEFT) === 0) {\n                    x = pos.x;\n                    y = pos.y + height;\n                    if (doesitfit()) {\n                        entry.used |= UsedCorner.BOTTOMLEFT;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // no room --> go to next texture and put at (pad, pad)\n        if (!found) {\n            x =\n                y =\n                p.x =\n                p.y =\n                    pad;\n            ({ tex: curTex, ctx: curCtx, el: curEl } = this._newTexture());\n        }\n\n        this._blit(img, x, y, chopX, chopY, imgWidth, imgHeight);\n\n        const f = this._p._saveFrame(\n            this,\n            curTex,\n            new Quad(x / maxX, y / maxY, imgWidth / maxX, imgHeight / maxY),\n        );\n\n        this._used.set(f.id, {\n            rect: rectToAdd,\n            tex: curTex,\n            used: 0,\n        });\n\n        return f;\n    }\n    _addPrepacked(img: ImageSource, frames: Quad[]): Frame[] {\n        const main = this._add(img, undefined);\n        return frames.map(frame =>\n            this._p._saveFrame(\n                this,\n                main.tex,\n                main.q.scale(frame),\n            )\n        );\n    }\n    _free() {\n        this._textures.forEach(tex => tex.free());\n        this._big.forEach(f => f.tex.free());\n        this._used.clear();\n        this._big = [];\n    }\n    _remove(packerId: number) {\n        const entry = this._used.get(packerId);\n\n        if (!entry) {\n            const big = this._big.findIndex(f => f.id === packerId);\n            if (big < 0) {\n                throw new Error(\n                    \"Image not found in packer (was this loaded via a prepacked spritesheet?)\",\n                );\n            }\n            this._big.splice(big, 1)[0]!.tex.free();\n            return;\n        }\n        const { rect: { pos: { x, y }, width, height }, tex } = entry;\n        this._tex2Map.get(tex)!.ctx.clearRect(x, y, width, height);\n\n        this._used.delete(packerId);\n        this._hasPendingRefresh = true;\n    }\n}\n\nexport class TexPacker {\n    _packers: Partial<Record<string, FilterTexPacker>> = {};\n    _last = 0;\n    _idsToPackers: Record<number, FilterTexPacker> = {};\n    constructor(\n        private _gfx: GfxCtx,\n        private _w: number,\n        private _h: number,\n        private _pad: number,\n    ) {}\n    _getPacker(filter: TexFilter, name: string = filter): FilterTexPacker {\n        return (this._packers[name] ??= new FilterTexPacker(\n            this,\n            filter,\n            this._gfx,\n            this._w,\n            this._h,\n            this._pad,\n        ));\n    }\n    _saveFrame(packer: FilterTexPacker, tex: Texture, quad: Quad): Frame {\n        const id = this._last++;\n        this._idsToPackers[id] = packer;\n        return {\n            id,\n            tex,\n            q: quad,\n        };\n    }\n    /**\n     * create the default 1x1 white pixel used for primitives at uv = (1, 1) on the nearest filter texture\n     *\n     * must be called prior to initializing anything else, as it doesn't check for\n     * collisions with anything!\n     */\n    _createWhitePixel(): Frame {\n        const packer = this._getPacker(\"nearest\");\n        const { el: { width, height }, tex } = packer._curMap;\n        const whitePixel = new ImageData(\n            new Uint8ClampedArray([255, 255, 255, 255]),\n            1,\n            1,\n        );\n        packer._blit(whitePixel, width - 1, height - 1, 0, 0, 1, 1);\n        packer._sync();\n        packer._used.set(-1, {\n            rect: new Rect(new Vec2(width - 1, height - 1), 1, 1),\n            tex: tex,\n            used: UsedCorner.BOTTOMLEFT | UsedCorner.TOPRIGHT, // it's bottom right so nothing can go right or below it\n        });\n        return {\n            tex,\n            q: new Quad(\n                (width - 1) / width,\n                (height - 1) / height,\n                1 / width,\n                1 / height,\n            ),\n            id: -1,\n        };\n    }\n    add(img: ImageSource, filter: TexFilter, chopQuad?: Quad): Frame {\n        return this._getPacker(filter)._add(img, chopQuad);\n    }\n    addPrepacked(img: ImageSource, filter: TexFilter, frames: Quad[]): Frame[] {\n        return this._getPacker(filter)._addPrepacked(img, frames);\n    }\n    // create a image with a single texture\n    addSingle(img: ImageSource, filter: TexFilter): Frame {\n        return this._getPacker(filter)._single(img);\n    }\n    syncIfPending() {\n        Object.values(this._packers).forEach(p => p!._sync());\n    }\n    _remove(id: number) {\n        this._idsToPackers[id]?._remove(id);\n        delete this._idsToPackers[id];\n    }\n    _free() {\n        Object.values(this._packers).forEach(p => p!._free());\n        this._packers = {};\n    }\n}\n", "import { SPRITE_ATLAS_HEIGHT, SPRITE_ATLAS_WIDTH } from \"../constants/general\";\nimport type { SerializedGameObj } from \"../ecs/entity/prefab\";\nimport { KEvent, KEventHandler } from \"../events/events\";\nimport type { GfxCtx } from \"../gfx/gfx\";\nimport type { AppGfxCtx } from \"../gfx/gfxApp\";\nimport { TexPacker } from \"../gfx/TexPacker\";\nimport { _k } from \"../shared\";\nimport type { ImageSource, MustKAPLAYOpt } from \"../types\";\nimport type { BitmapFontData } from \"./bitmapFont\";\nimport type { FontData } from \"./font\";\nimport type { ShaderData } from \"./shader\";\nimport type { SoundData } from \"./sound\";\nimport type { LoadSpriteSrc, SpriteData } from \"./sprite\";\nimport { fixURL } from \"./utils\";\n\n/**\n * An asset is a resource that is loaded asynchronously.\n *\n * It can be a sprite, a sound, a font, a shader, etc.\n */\nexport class Asset<D> {\n    loaded: boolean = false;\n    data: D | null = null;\n    error: Error | null = null;\n    _bucketOnLoad: (() => void) | undefined;\n    private onLoadEvents: KEvent<[D]> = new KEvent();\n    private onErrorEvents: KEvent<[Error]> = new KEvent();\n    private onFinishEvents: KEvent<[]> = new KEvent();\n\n    constructor(loader: Promise<D>) {\n        loader.then((data) => {\n            this.loaded = true;\n            this._bucketOnLoad?.();\n            this.data = data;\n            this.onLoadEvents.trigger(data);\n        }).catch((err) => {\n            this.error = err;\n\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\n/**\n * @group Assets\n * @subgroup Types\n */\nexport class AssetBucket<D> {\n    assets: Map<string, Asset<D>> = new Map();\n    waiters: KEventHandler<any> = new KEventHandler();\n    errorWaiters: KEventHandler<any> = new KEventHandler();\n    lastUID: number = 0;\n    constructor(public onGet?: () => void) {}\n\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        asset.onLoad(d => {\n            this.waiters.trigger(id, d);\n        });\n        asset.onError(d => {\n            this.errorWaiters.trigger(id, d);\n        });\n\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        this.waiters.trigger(id, data);\n        this.errorWaiters.remove(id);\n\n        return asset;\n    }\n    // if not found return undefined\n    get(handle: string): Asset<D> | undefined {\n        const asset = this.assets.get(handle);\n        if (asset) {\n            if (asset.loaded) this.onGet?.();\n            else asset._bucketOnLoad = this.onGet;\n        }\n        return asset;\n    }\n    progress(): number {\n        if (this.assets.size === 0) {\n            return 1;\n        }\n        let loaded = 0;\n\n        this.assets.forEach((asset) => {\n            if (asset.loaded) {\n                loaded++;\n            }\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    waitFor(name: string, timeout: number): PromiseLike<D> {\n        const asset = this.get(name);\n        if (asset) {\n            if (asset.loaded) return Promise.resolve(asset.data!);\n            else {\n                return Promise.race([\n                    new Promise<D>((res, rej) => {\n                        asset.onLoad(res);\n                        asset.onError(rej);\n                    }),\n                    new Promise<never>((_, rej) =>\n                        setTimeout(\n                            () => rej(\"timed out waiting for asset \" + name),\n                            timeout,\n                        )\n                    ),\n                ]);\n            }\n        }\n        const x = Promise.withResolvers<D>();\n        this.waiters.onOnce(name, x.resolve);\n        this.errorWaiters.onOnce(name, x.reject);\n        setTimeout(\n            () => x.reject(\"timed out waiting for asset \" + name),\n            timeout,\n        );\n        return x.promise;\n    }\n}\n\nexport function fetchURL(url: string) {\n    return fetch(url).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\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 spriteSrcToImage(src: LoadSpriteSrc): Promise<ImageSource> {\n    return typeof src === \"string\" ? loadImg(src) : Promise.resolve(src);\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\n/** @ignore */\nexport type InternalAssetsCtx = ReturnType<typeof initAssets>;\n\n/** @ignore */\nexport const initAssets = (\n    ggl: GfxCtx,\n    opt: MustKAPLAYOpt,\n    appGfx: AppGfxCtx,\n) => {\n    const packer = new TexPacker(\n        ggl,\n        SPRITE_ATLAS_WIDTH,\n        SPRITE_ATLAS_HEIGHT,\n        opt.spriteAtlasPadding,\n    );\n    const assets = {\n        urlPrefix: \"\",\n        // asset holders\n        sprites: new AssetBucket<SpriteData>(() => packer.syncIfPending()),\n        fonts: new AssetBucket<FontData>(),\n        bitmapFonts: new AssetBucket<BitmapFontData>(() =>\n            packer.syncIfPending()\n        ),\n        sounds: new AssetBucket<SoundData>(),\n        shaders: new AssetBucket<ShaderData>(),\n        custom: new AssetBucket<any>(),\n        prefabAssets: new AssetBucket<SerializedGameObj>(),\n        music: {} as Record<string, string>,\n        packer,\n        // if we finished initially loading all assets\n        loaded: false,\n    };\n\n    // Set up the white pixel to start everything\n    appGfx.whitePixel = assets.packer._createWhitePixel();\n\n    return assets;\n};\n", "import { _k } from \"../shared\";\nimport { dataURLToArrayBuffer, isDataURL } from \"../utils/dataURL\";\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 fromAudioBuffer(buf: AudioBuffer): SoundData {\n        return new SoundData(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 | AudioBuffer,\n): Asset<SoundData> {\n    const fixedSrc = fixURL(src);\n    let sound: Promise<SoundData> | SoundData;\n\n    if (typeof fixedSrc === \"string\") {\n        sound = SoundData.fromURL(fixedSrc);\n    }\n    else if (fixedSrc instanceof ArrayBuffer) {\n        sound = SoundData.fromArrayBuffer(fixedSrc);\n    }\n    else {\n        sound = Promise.resolve(SoundData.fromAudioBuffer(fixedSrc));\n    }\n\n    return _k.assets.sounds.add(name, sound);\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 keyof typeof _k.assets.music] = musicUrl;\n}\n", "/** @ignore */\nexport interface InternalAudioCtx {\n    ctx: AudioContext;\n    masterNode: GainNode;\n}\n\n/** @ignore */\nexport function createEmptyAudioBuffer(ctx: AudioContext) {\n    return ctx.createBuffer(1, 1, 44100);\n}\n\n/** @ignore */\nexport const initAudio = (): InternalAudioCtx => {\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        return {\n            ctx,\n            masterNode,\n        };\n    })();\n\n    return audio;\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", "// Global event handlers\n\nimport { type Asset, getFailedAssets } from \"../assets/asset\";\nimport {\n    startClickHandler,\n    startHoverSystem,\n} from \"../ecs/components/physics/area\";\nimport type { Collision } from \"../ecs/systems/Collision\";\nimport type { GameObjEventNames, GameObjEvents } from \"../events/eventMap\";\nimport type { KEventController } from \"../events/events\";\nimport { _k } from \"../shared\";\nimport type { GameObj, Tag } from \"../types\";\nimport { overload2 } from \"../utils/overload\";\nimport type { TupleWithoutFirst } from \"../utils/types\";\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 on = <Ev extends GameObjEventNames | string & {}>(\n    event: Ev,\n    tag: Tag,\n    cb: (\n        obj: GameObj,\n        ...args: TupleWithoutFirst<GameObjEvents[Ev]>\n    ) => void,\n): KEventController => {\n    let paused = false;\n    let obj2Handler = new Map<GameObj, KEventController>();\n\n    const handleNew = (obj: GameObj) => {\n        const ec = obj.on(event, (...args) => {\n            cb(obj, ...<TupleWithoutFirst<GameObjEvents[Ev]>> args);\n        });\n        ec.paused = paused;\n\n        let h;\n        if (h = obj2Handler.get(obj)) h.cancel();\n\n        obj2Handler.set(obj, ec);\n    };\n\n    const ecOnTag = _k.appScope.onTag((obj, newTag) => {\n        if (newTag === tag) handleNew(obj);\n    });\n\n    const ecOnAdd = _k.appScope.onAdd(obj => {\n        if (obj.is(tag)) handleNew(obj);\n    });\n\n    const ecOnUntag = _k.appScope.onUntag((obj, oldTag) => {\n        if (oldTag === tag) {\n            const ec = obj2Handler.get(obj)!;\n            ec.cancel();\n            obj2Handler.delete(obj);\n        }\n    });\n\n    const ecOnDestroy = _k.appScope.onDestroy((obj) => {\n        if (obj.is(tag)) {\n            // event is automatically cancelled by GameObjRaw.remove\n            obj2Handler.delete(obj);\n        }\n    });\n\n    _k.game.root.get(tag, { recursive: true }).forEach(handleNew);\n\n    return {\n        get paused() {\n            return paused;\n        },\n        set paused(p) {\n            paused = p;\n            obj2Handler.forEach(ec => ec.paused = p);\n        },\n        cancel() {\n            obj2Handler.forEach(ec => ec.cancel());\n            obj2Handler.clear();\n            ecOnTag.cancel();\n            ecOnAdd.cancel();\n            ecOnUntag.cancel();\n            ecOnDestroy.cancel();\n        },\n    };\n};\n\nexport const onAdd = overload2((action: (obj: GameObj) => void) => {\n    return _k.game.gameObjEvents.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.gameObjEvents.on(\"destroy\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"destroy\", tag, action);\n});\n\nexport const onUse = overload2(\n    (action: (obj: GameObj, compId: string) => void) => {\n        return _k.game.gameObjEvents.on(\"use\", action);\n    },\n    (tag: Tag, action: (obj: GameObj, compId: string) => void) => {\n        return on(\"use\", tag, action);\n    },\n);\n\nexport const onUnuse = overload2(\n    (action: (obj: GameObj, compId: string) => void) => {\n        return _k.game.gameObjEvents.on(\"unuse\", action);\n    },\n    (tag: Tag, action: (obj: GameObj, compId: string) => void) => {\n        return on(\"unuse\", tag, action);\n    },\n);\n\nexport const onTag = overload2(\n    (action: (obj: GameObj, compId: string) => void) => {\n        return _k.game.gameObjEvents.on(\"tag\", action);\n    },\n    (tag: Tag, action: (obj: GameObj, compId: string) => void) => {\n        return on(\"tag\", tag, action);\n    },\n);\n\nexport const onUntag = overload2(\n    (action: (obj: GameObj, compId: string) => void) => {\n        return _k.game.gameObjEvents.on(\"untag\", action);\n    },\n    (tag: Tag, action: (obj: GameObj, compId: string) => 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(\n        \"collide\",\n        t1,\n        (a, b, col) => b.is(t2) && f(a, b, col),\n    );\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(\n        \"collideUpdate\",\n        t1,\n        (a, b, col) => b.is(t2) && f(a, b, col),\n    );\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(\n        \"collideEnd\",\n        t1,\n        (a, b, col) => b.is(t2) && f(a, b, col),\n    );\n}\n\nexport const onFixedUpdate = overload2((action: () => void) => {\n    return _k.app.state.events.on(\"fixedUpdate\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"fixedUpdate\", tag, action);\n});\n\nexport const onUpdate = overload2((action: () => void) => {\n    return _k.app.state.events.on(\"update\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"update\", tag, action);\n});\n\nexport const onDraw = overload2((action: () => void) => {\n    return _k.app.state.events.on(\"draw\", action);\n}, (tag: Tag, action: (obj: GameObj) => void) => {\n    return on(\"draw\", tag, action);\n});\n\nexport const onClick = (tag: Tag, action: (obj: GameObj) => void) => {\n    startClickHandler();\n    return on(\"click\", tag, action);\n};\n\nexport function onHover(tag: Tag, action: (obj: GameObj) => void) {\n    startHoverSystem();\n    return on(\"hover\", tag, action);\n}\n\nexport function onHoverEnd(tag: Tag, action: (obj: GameObj) => void) {\n    startHoverSystem();\n    return on(\"hoverEnd\", tag, action);\n}\n\nexport function onHoverUpdate(tag: Tag, action: (obj: GameObj) => void) {\n    startHoverSystem();\n    return on(\"hoverUpdate\", tag, action);\n}\n\n// #region just ev handlers\nexport function onError(action: (err: Error) => void) {\n    return _k.game.events.on(\"error\", action);\n}\n\nexport function onLoading(action: (progress: number) => void) {\n    return _k.game.events.on(\"loading\", action);\n}\n\nexport function onLoad(cb: () => void) {\n    if (_k.assets.loaded) {\n        cb();\n    }\n    else {\n        return _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\nexport function onSceneLeave(\n    action: (newScene?: string) => void,\n): KEventController {\n    return _k.game.events.on(\"sceneLeave\", action);\n}\n// #endregion\n", "// Related to load and save data\n\nexport 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\nexport function setData(key: string, data: any) {\n    window.localStorage[key] = JSON.stringify(data);\n}\n", "import { Quad } from \"../math/math\";\nimport { _k } from \"../shared\";\nimport { getFileName } from \"../utils/dataURL\";\nimport { type Asset, fetchJSON } from \"./asset\";\nimport { type LoadSpriteSrc, type SpriteAnim, SpriteData } from \"./sprite\";\nimport { fixURL } from \"./utils\";\n\n/**\n * @group Assets\n * @subgroup Data\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.fromSpriteSrc(imgSrc, {\n                frames: frames,\n                anims: anims,\n                repack: false,\n            });\n        }),\n    );\n}\n", "import type { Frame } from \"../gfx/TexPacker\";\nimport { Quad } from \"../math/math\";\nimport { _k } from \"../shared\";\nimport type { TexFilter } from \"../types\";\nimport { type Asset, fetchJSON, load, spriteSrcToImage } from \"./asset\";\nimport {\n    fixFramesPixelsToFractionOfImage,\n    type LoadSpriteOpt,\n    type LoadSpriteSrc,\n    SpriteData,\n} from \"./sprite\";\nimport { fixURL, slice } from \"./utils\";\n\n/**\n * @group Assets\n * @subgroup Data\n */\nexport type SpriteAtlasData = Record<string, SpriteAtlasEntry>;\n\n/**\n * A sprite in a sprite atlas.\n *\n * @group Assets\n * @subgroup Types\n */\nexport type SpriteAtlasEntry = Omit<LoadSpriteOpt, \"repack\"> & {\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    repack = true,\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        spriteSrcToImage(src).then(img => {\n            const packer = _k.assets.packer;\n            const map: Record<string, SpriteData> = {};\n            const wholeImageWidth = img.width, wholeImageHeight = img.height;\n\n            const mainFramesByFilter: Partial<Record<TexFilter, Frame>> = {};\n\n            for (const name in data) {\n                let {\n                    x: spriteSectionX,\n                    y: spriteSectionY,\n                    width: spriteSectionWidth,\n                    height: spriteSectionHeight,\n                    frames,\n                    sliceX,\n                    sliceY,\n                    anims,\n                    slice9,\n                    filter,\n                } = data[name];\n                filter ??= _k.globalOpt.texFilter ?? \"nearest\";\n                const mainQuad = new Quad(\n                    spriteSectionX / wholeImageWidth,\n                    spriteSectionY / wholeImageHeight,\n                    spriteSectionWidth / wholeImageWidth,\n                    spriteSectionHeight / wholeImageHeight,\n                );\n                if (frames) {\n                    frames = fixFramesPixelsToFractionOfImage(\n                        frames,\n                        spriteSectionWidth,\n                        spriteSectionHeight,\n                    );\n                }\n                else {\n                    frames = slice(sliceX || 1, sliceY || 1);\n                }\n\n                let spr: SpriteData;\n\n                if (repack) {\n                    spr = new SpriteData(\n                        frames.map(q =>\n                            packer.add(img, filter, mainQuad.scale(q))\n                        ),\n                        anims,\n                        slice9,\n                    );\n                }\n                else {\n                    const ourFrame = (mainFramesByFilter[filter] ??= packer.add(\n                        img,\n                        filter,\n                    ));\n                    spr = new SpriteData(\n                        frames.map(q =>\n                            packer._saveFrame(\n                                packer._getPacker(filter),\n                                ourFrame.tex,\n                                ourFrame.q.scale(mainQuad).scale(q),\n                            )\n                        ),\n                        anims,\n                        slice9,\n                    );\n                }\n                _k.assets.sprites.addLoaded(name, spr);\n                map[name] = spr;\n            }\n            return map;\n        }),\n    );\n}\n", "import { KEvent } from \"../events/events\";\nimport { clamp } from \"../math/clamp\";\nimport { _k } from \"../shared\";\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    el.volume = opt.volume ?? 1;\n    el.playbackRate = opt.speed ?? 1;\n\n    const src = _k.audio.ctx.createMediaElementSource(el);\n\n    src.connect(opt.connectTo ?? _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            throw new Error(\n                \"Music cannot be detuned (limitation of the browser APIs, womp womp)\",\n            );\n        },\n\n        get detune() {\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        connect(node?: AudioNode) {\n            src.disconnect();\n            src.connect(node ?? _k.audio.masterNode);\n        },\n    };\n}\n", "import { Asset } from \"../assets/asset\";\nimport { resolveSound, type SoundData } from \"../assets/sound\";\nimport { KEvent, type KEventController } from \"../events/events\";\nimport { _k } from \"../shared\";\nimport type { MusicData } from \"../types\";\nimport { playMusic } from \"./playMusic\";\n\n// TODO: enable setting on load, make part of SoundData\n/**\n * Audio play configurations.\n *\n * @group Audio\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     * If the audio node should start out connected to another audio node rather than\n     * KAPLAY's default volume node. Defaults to undefined, i.e. use KAPLAY's volume node.\n     */\n    connectTo?: AudioNode;\n}\n\n/**\n * @group Audio\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     * Disconnect the audio node from whatever it is currently connected to\n     * and connect it to the passed-in audio node, or to Kaplay's default volume node\n     * if no node is passed.\n     */\n    connect(node?: AudioNode): void;\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(opt.connectTo ?? _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    const snd = resolveSound(\n        // @ts-expect-error Resolve Type Error\n        src,\n    );\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        connect(node?: AudioNode) {\n            gainNode.disconnect();\n            gainNode.connect(node ?? _k.audio.masterNode);\n        },\n    };\n}\n", "import { _k } from \"../shared\";\nimport { type AudioPlay, type AudioPlayOpt, play } from \"./play\";\n\n// core KAPLAY logic\nexport function burp(opt?: AudioPlayOpt): AudioPlay {\n    if (!_k.game.defaultAssets.burp) {\n        throw new Error(\"You can't use burp in kaplay/mini\");\n    }\n\n    return play(_k.game.defaultAssets.burp, opt);\n}\n", "import { _k } from \"../shared\";\nimport { deprecateMsg } from \"../utils/log\";\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 { SoundData } from \"../assets/sound\";\nimport { play } from \"../audio/play\";\nimport { _k } from \"../shared\";\nimport { downloadBlob } from \"../utils/dataURL\";\n\n/**\n * Screen recording control handle.\n *\n * @group Data\n */\nexport interface Recording {\n    /**\n     * Pause the recording.\n     */\n    pause(): void;\n    /**\n     * Resume the recording.\n     */\n    resume(): void;\n    /**\n     * Stop the recording and get the video data as a Blob. This\n     * finalizes the recording, so trying to do anything else with it\n     * later will throw an error.\n     *\n     * @since v3000.0\n     */\n    stop(): Promise<Blob>;\n    /**\n     * Stop the recording and downloads the file. Like `stop()`, this finalizes\n     * the recording, and trying to do anything else with it later will throw\n     * an error.\n     *\n     * @param filename - The suggested file name to initially present to the player\n     * (they can always change it in their browser's save dialog). If none is specified\n     * the format is 'kaplay-{current date and time}.{file extension}'.\n     */\n    download(filename?: string): void;\n    /**\n     * The currently used MIME type that was selected when the recording was\n     * started.\n     */\n    readonly mimeType: string;\n    /**\n     * The recommended file extension for the output file, minus the dot. For\n     * MP4 this will be `\"mp4\"`, for WEBM, `\"webm\"`, etc.\n     *\n     * This value is calculated using the MIME type and so it might be wrong.\n     * For example if you're in Safari and manage to get a recording started using\n     * the `video/quicktime` format, this property will report `\"quicktime\"`, even\n     * though the correct file extension is `.mov`.\n     */\n    readonly fileExt: string;\n}\n\n// https://stackoverflow.com/a/57168358/23626926\n\nconst a = new AudioBuffer({ length: 1, sampleRate: 44100 });\na.getChannelData(0).set([.01], 0);\nconst dummy = new SoundData(a);\n\nexport const record = (frameRate?: number, mimeTypes?: string[]): Recording => {\n    if (_k.debug.curRecording !== null) {\n        throw new Error(\"Recording is already in progress.\");\n    }\n\n    const options: MediaRecorderOptions = {};\n\n    if (mimeTypes !== undefined) {\n        const mimeType = mimeTypes.find(mime =>\n            MediaRecorder.isTypeSupported(mime)\n        );\n\n        if (mimeType === undefined) {\n            throw new Error(\n                `None of the provided MIME types (${\n                    mimeTypes.join(\", \")\n                }) are supported for recording${\n                    mimeTypes.some(mime => /^video\\//.test(mime))\n                        ? \"\"\n                        : \" (hint: it must look like 'video/xxx')\"\n                }.`,\n            );\n        }\n\n        options.mimeType = mimeType;\n    }\n\n    const audioDest = _k.audio.ctx.createMediaStreamDestination();\n\n    _k.audio.masterNode.connect(audioDest);\n\n    const audioStream = audioDest.stream;\n    const [firstAudioTrack] = audioStream.getAudioTracks();\n    const canvasStream = _k.app.canvas.captureStream(frameRate);\n    const [firstCanvasTrack] = canvasStream.getVideoTracks();\n\n    const recorder = new MediaRecorder(\n        new MediaStream([firstAudioTrack, firstCanvasTrack]),\n        options,\n    );\n\n    // dummy to make audio work\n    play(dummy);\n\n    const chunks: any[] = [];\n\n    const defaultExt = /\\/(.+?)(;|$)/.exec(recorder.mimeType)![1]!;\n    recorder.ondataavailable = (e) => {\n        if (e.data.size > 0) {\n            chunks.push(e.data);\n        }\n    };\n\n    recorder.onerror = () => {\n        _k.audio.masterNode.disconnect(audioDest);\n        canvasStream.getTracks().forEach(t => t.stop());\n    };\n\n    recorder.start();\n\n    var finalized = false;\n\n    const checkFinalized = () => {\n        if (finalized) {\n            throw new Error(\n                \"Recording has been finalized, you must start a new recording\",\n            );\n        }\n    };\n\n    const rec: Recording = {\n        resume() {\n            checkFinalized();\n            recorder.resume();\n        },\n\n        pause() {\n            checkFinalized();\n            recorder.pause();\n        },\n\n        stop(): Promise<Blob> {\n            checkFinalized();\n            finalized = true;\n            _k.debug.curRecording = null;\n            recorder.stop();\n            // cleanup\n            _k.audio.masterNode.disconnect(audioDest);\n            canvasStream.getTracks().forEach(t => t.stop());\n            return new Promise((resolve) => {\n                recorder.onstop = () => {\n                    resolve(\n                        new Blob(chunks, {\n                            type: recorder.mimeType,\n                        }),\n                    );\n                };\n            });\n        },\n\n        get mimeType() {\n            return recorder.mimeType;\n        },\n\n        get fileExt() {\n            return defaultExt;\n        },\n\n        download(\n            filename = `kaplay-${new Date().toISOString()}.${defaultExt}`,\n        ) {\n            this.stop().then((blob) => downloadBlob(filename, blob));\n        },\n    };\n\n    _k.debug.curRecording = rec;\n\n    return rec;\n};\n", "import { BlendMode, type Comp } from \"../../../types\";\n\n/**\n * The serialized {@link blend `blend()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedBlendComp {\n    blend: BlendMode;\n}\n\n/**\n * The {@link blend `blend()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface BlendComp extends Comp {\n    blend: BlendMode;\n    serialize(): SerializedBlendComp;\n}\n\nexport function blend(blend: BlendMode): BlendComp {\n    return {\n        id: \"blend\",\n        blend: blend ?? BlendMode.Normal,\n        inspect() {\n            return `blend: ${\n                this.blend == BlendMode.Normal\n                    ? \"normal\"\n                    : this.blend == BlendMode.Add\n                    ? \"add\"\n                    : this.blend == BlendMode.Multiply\n                    ? \"multiply\"\n                    : \"screen\"\n            }`;\n        },\n        serialize() {\n            return { blend: this.blend };\n        },\n    };\n}\n\nexport function blendFactory(data: SerializedBlendComp) {\n    return blend(data.blend);\n}\n", "import { getRenderProps } from \"../../../game/utils\";\nimport { drawCircle } from \"../../../gfx/draw/drawCircle\";\nimport { Circle, Rect } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\nimport type { AnchorComp } from \"../transform/anchor\";\nimport type { FillComp } from \"./fill\";\nimport type { outline } from \"./outline\";\n\n/**\n * The serialized {@link circle `circle()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedCircleComp {\n    radius: number;\n    fill?: boolean;\n}\n\n/**\n * The {@link circle `circle()`} component.\n *\n * @group Components\n * @subgroup 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(): Circle;\n    serialize(): SerializedCircleComp;\n}\n\n/**\n * Options for the {@link circle `circle()``} component.\n *\n * @group Components\n * @subgroup 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(\n    radius: number,\n    opt: CircleCompOpt = {},\n): CircleComp & { _renderAreaVersion: number } {\n    let _shape: Circle | undefined;\n    let _radius = radius;\n    return {\n        id: \"circle\",\n        get radius() {\n            return _radius;\n        },\n        set radius(value: number) {\n            if (_radius != value) {\n                _radius = value;\n                if (_shape) _shape.radius = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        draw(this: GameObj<CircleComp & FillComp>) {\n            drawCircle(Object.assign(getRenderProps(this), {\n                radius: _radius,\n                fill: this.fill ?? opt.fill,\n            }));\n        },\n        renderArea(\n            this: GameObj<\n                AnchorComp | CircleComp | { _renderAreaVersion: number }\n            >,\n        ) {\n            if (!_shape) {\n                _shape = new Circle(\n                    new Vec2(0),\n                    _radius,\n                );\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n        _renderAreaVersion: 0,\n        inspect() {\n            return `radius: ${Math.ceil(_radius)}`;\n        },\n        serialize(this: GameObj<CircleComp & FillComp>) {\n            const data: SerializedCircleComp = { radius: _radius };\n            if (this.fill ?? opt.fill) data.fill = true;\n            return data;\n        },\n    };\n}\n\nexport function circleFactory(data: SerializedCircleComp) {\n    const opt: CircleCompOpt = {};\n    if (data.fill) opt.fill = data.fill;\n    return circle(\n        data.radius,\n        opt,\n    );\n}\n", "import type { Picture } from \"../../../gfx/draw/drawPicture\";\nimport type { FrameBuffer } from \"../../../gfx/FrameBuffer\";\nimport type { Comp, GameObj } from \"../../../types\";\n\n/**\n * Options for the {@link drawon `drawon()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport type DrawonCompOpt = {\n    childrenOnly?: boolean;\n    refreshOnly?: boolean;\n};\n\n/**\n * The {@link drawon `drawon()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface DrawonComp extends Comp {\n    refresh(): void;\n}\n\nexport function drawon(c: FrameBuffer | Picture, opt?: DrawonCompOpt) {\n    return {\n        add(this: GameObj) {\n            this.target = {\n                destination: c,\n                childrenOnly: opt?.childrenOnly,\n                refreshOnly: opt?.refreshOnly,\n            };\n        },\n        refresh(this: GameObj<DrawonComp>) {\n            if (this.target) {\n                this.target.isFresh = false;\n            }\n        },\n    };\n}\n", "import { getRenderProps } from \"../../../game/utils\";\nimport { drawEllipse } from \"../../../gfx/draw/drawEllipse\";\nimport { Ellipse } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\nimport type { AnchorComp } from \"../transform/anchor\";\nimport type { FillComp } from \"./fill\";\nimport type { outline } from \"./outline\";\n\n/**\n * The serialized {@link ellipse `ellipse()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedEllipseComp {\n    radiusX: number;\n    radiusY: number;\n    fill?: boolean;\n}\n\n/**\n * The {@link ellipse `ellipse()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface EllipseComp extends Comp {\n    draw: Comp[\"draw\"];\n    /** Semi-major axis of ellipse. */\n    radiusX: number;\n    /** Semi-minor axis of ellipse. */\n    radiusY: number;\n    /**\n     * Render area of the ellipse.\n     */\n    renderArea(): Ellipse;\n    serialize(): SerializedEllipseComp;\n}\n\n/**\n * Options for the {@link ellipse `ellipse()``} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface EllipseCompOpt {\n    /**\n     * If fill is false, the ellipse is not filled (useful if you only want to render outline with\n     * {@link outline `outline()`} component).\n     */\n    fill?: boolean;\n}\n\nexport function ellipse(\n    radiusX: number,\n    radiusY: number,\n    opt: EllipseCompOpt = {},\n): EllipseComp & { _renderAreaVersion: number } {\n    let _shape: Ellipse | undefined;\n    let _radiusX = radiusX;\n    let _radiusY = radiusY;\n    return {\n        id: \"ellipse\",\n        get radiusX() {\n            return _radiusX;\n        },\n        set radiusX(value: number) {\n            if (_radiusX != value) {\n                _radiusX = value;\n                if (_shape) _shape.radiusX = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get radiusY() {\n            return _radiusY;\n        },\n        set radiusY(value: number) {\n            if (_radiusY != value) {\n                _radiusY = value;\n                if (_shape) _shape.radiusY = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        draw(this: GameObj<EllipseComp | FillComp>) {\n            drawEllipse(Object.assign(getRenderProps(this), {\n                radiusX: this.radiusX,\n                radiusY: this.radiusY,\n                fill: this.fill ?? opt.fill,\n            }));\n        },\n        renderArea(\n            this: GameObj<\n                AnchorComp | EllipseComp | { _renderAreaVersion: number }\n            >,\n        ) {\n            if (!_shape) {\n                _shape = new Ellipse(\n                    new Vec2(0),\n                    _radiusX,\n                    _radiusY,\n                );\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n        _renderAreaVersion: 0,\n        inspect() {\n            return `radiusX: ${Math.ceil(_radiusX)} radiusY: ${\n                Math.ceil(_radiusY)\n            }`;\n        },\n        serialize(this: GameObj<EllipseComp | FillComp>) {\n            return {\n                radiusX: this.radiusX,\n                radiusY: this.radiusY,\n                fill: this.fill ?? opt.fill,\n            };\n        },\n    };\n}\n\nexport function ellipseFactory(data: SerializedEllipseComp) {\n    const opt: EllipseCompOpt = {};\n\n    if (data.fill) opt.fill = data.fill;\n\n    return ellipse(data.radiusX, data.radiusY, opt);\n}\n", "import { map } from \"../../../math/math\";\nimport { _k } from \"../../../shared\";\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 += _k.app.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 } from \"../../../types\";\n\n/**\n * The serialized {@link fill `fill()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedFillComp {\n    fill?: boolean;\n}\n\n/**\n * The {@link fill `fill()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface FillComp extends Comp {\n    /**\n     * If the obj is unaffected by camera\n     */\n    fill: boolean;\n\n    serialize(): SerializedFillComp;\n}\n\nexport function fill(fill = true): FillComp {\n    return {\n        id: \"fill\",\n        fill: fill,\n        serialize() {\n            return { fill: this.fill };\n        },\n    };\n}\n\nexport function fillFactory(data: SerializedFillComp) {\n    return fill(data.fill);\n}\n", "import type { Comp, Mask } from \"../../../types\";\n\n/**\n * The serialized {@link mask `mask()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedMaskComp {\n    mask: Mask;\n}\n\n/**\n * The {@link mask `mask()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface MaskComp extends Comp {\n    mask: Mask;\n    serialize(): SerializedMaskComp;\n}\n\nexport function mask(m: Mask = \"intersect\"): MaskComp {\n    return {\n        id: \"mask\",\n        mask: m,\n        serialize() {\n            return { mask: this.mask };\n        },\n    };\n}\n\nexport function maskFactory(data: SerializedMaskComp) {\n    return mask(data.mask);\n}\n", "import type { LineCap, LineJoin } from \"../../../gfx/draw/drawLine\";\nimport { Color, rgb, type SerializedColor } from \"../../../math/color\";\nimport type { Comp, Outline } from \"../../../types\";\n\n/**\n * The serialized {@link outline `outline()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedOutlineComp {\n    outline: {\n        width: number;\n        color: SerializedColor;\n        opacity: number;\n        join: LineJoin;\n        miterLimit: number;\n        cap: LineCap;\n    };\n}\n\n/**\n * The {@link outline `outline()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface OutlineComp extends Comp {\n    outline: Outline;\n    serialize(): SerializedOutlineComp;\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        serialize() {\n            return {\n                outline: {\n                    width: this.outline.width ?? 1,\n                    color: {\n                        r: this.outline.color?.r ?? 255,\n                        g: this.outline.color?.g ?? 255,\n                        b: this.outline.color?.b ?? 255,\n                    },\n                    opacity: this.outline.opacity ?? 1,\n                    join: this.outline.join ?? \"miter\",\n                    miterLimit: this.outline.miterLimit ?? 10,\n                    cap: this.outline.cap ?? \"butt\",\n                },\n            };\n        },\n    };\n}\n\nexport function outlineFactory(data: SerializedOutlineComp) {\n    return outline(\n        data.outline.width,\n        Color.deserialize(data.outline.color),\n        data.outline.opacity,\n        data.outline.join,\n        data.outline.miterLimit,\n        data.outline.cap,\n    );\n}\n", "import { KEvent } from \"../../../events/events\";\nimport { drawRaw } from \"../../../gfx/draw/drawRaw\";\nimport type { Texture } from \"../../../gfx/gfx\";\nimport { Color } from \"../../../math/color\";\nimport { lerp } from \"../../../math/lerp\";\nimport {\n    deg2rad,\n    map,\n    Quad,\n    rand,\n    type ShapeType,\n    vec2,\n} from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp } from \"../../../types\";\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 = 0;\n    lt: number | null = null;\n    gc: boolean = true;\n\n    constructor() {\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 *\n * @group Components\n * @subgroup Component Types\n */\nexport type EmitterOpt = {\n    /**\n     * Shape of the emitter. If given, particles spawn 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     * Position (relative) of emission.\n     */\n    position: Vec2;\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 Components\n * @subgroup 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[] | Vec2[];\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 Components\n * @subgroup Component Types\n */\nexport interface ParticlesComp extends Comp {\n    emitter: {\n        /**\n         * Relative position of the emitter\n         */\n        position: Vec2;\n        /**\n         * Relative direction of the emitter\n         */\n        direction: number;\n    };\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\n// cSpell: ignore popt eopt\n\nexport function particles(popt: ParticlesOpt, eopt: EmitterOpt): ParticlesComp {\n    let emitterLifetime = eopt.lifetime;\n\n    const particles: Particle[] = new Array<Particle>(popt.max);\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 ? popt.scales.map(s => vec2(s)) : [vec2(1)];\n    const lifetime = popt.lifeTime;\n    const spread = eopt.spread || 0;\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[] = new Array<number>(popt.max * 6);\n    const attributes = {\n        pos: new Array<number>(popt.max * 4 * 2),\n        uv: new Array<number>(popt.max * 4 * 2),\n        color: new Array<number>(popt.max * 4 * 3),\n        opacity: new Array<number>(popt.max * 4),\n    };\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        attributes.pos.fill(0);\n        attributes.uv.fill(1);\n        attributes.color.fill(255);\n        attributes.opacity.fill(1);\n\n        particles[i] = new Particle();\n    }\n\n    const onEndEvents = new KEvent();\n\n    function nextFree(index = 0): number | null {\n        for (; index < popt.max; index++) {\n            if (particles[index].gc) return index;\n        }\n        return null;\n    }\n\n    return {\n        id: \"particles\",\n        emitter: {\n            position: eopt.position || vec2(),\n            direction: eopt.direction || 0,\n        },\n        emit(n: number) {\n            n = Math.min(n, popt.max - count);\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                    this.emitter.direction - spread,\n                    this.emitter.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 = this.emitter.position.add(\n                    eopt.shape\n                        ? eopt.shape.random()\n                        : vec2(),\n                );\n\n                const p = particles[index];\n                p.t = 0;\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.gc = false;\n            }\n            count += n;\n        },\n        update() {\n            if (emitterLifetime !== undefined && emitterLifetime <= 0) {\n                return;\n            }\n\n            const DT = _k.app.dt();\n            // Update all particles\n            for (let i = 0; i < particles.length; i++) {\n                const p = particles[i];\n                if (p.gc) {\n                    continue;\n                }\n                p.t += DT;\n                if (p.lt !== null && 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 > 1 / eopt.rate\n            ) {\n                this.emit(1);\n                time -= 1 / eopt.rate;\n            }\n        },\n        draw() {\n            if (\n                (emitterLifetime !== undefined && emitterLifetime <= 0)\n                || count == 0\n            ) {\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                    attributes.opacity[i * 4] = 0;\n                    attributes.opacity[i * 4 + 1] = 0;\n                    attributes.opacity[i * 4 + 2] = 0;\n                    attributes.opacity[i * 4 + 3] = 0;\n                    continue;\n                }\n                const progress = p.progress;\n                const colorIndex = Math.floor(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(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(progress * quads.length);\n                const quad = quads[quadIndex];\n                const scaleIndex = Math.floor(progress * scales.length);\n                const scale = scales[scaleIndex];\n                // TODO: lerp scale\n                const angle = deg2rad(p.angle);\n                const c = Math.cos(angle);\n                const s = Math.sin(angle);\n\n                const hw = popt.texture.width * quad.w / 2;\n                const hh = popt.texture.height * quad.h / 2;\n\n                let j = i * 4;\n                // Left top\n                attributes.pos[j * 2] = p.pos.x + (-hw) * scale.x * c\n                    - (-hh) * scale.y * s;\n                attributes.pos[j * 2 + 1] = p.pos.y + (-hw) * scale.x * s\n                    + (-hh) * scale.y * c;\n                attributes.uv[j * 2] = quad.x;\n                attributes.uv[j * 2 + 1] = quad.y;\n                attributes.color[j * 3] = color.r;\n                attributes.color[j * 3 + 1] = color.g;\n                attributes.color[j * 3 + 2] = color.b;\n                attributes.opacity[j] = opacity;\n                // Right top\n                j++;\n                attributes.pos[j * 2] = p.pos.x + hw * scale.x * c\n                    - (-hh) * scale.y * s;\n                attributes.pos[j * 2 + 1] = p.pos.y + hw * scale.x * s\n                    + (-hh) * scale.y * c;\n                attributes.uv[j * 2] = quad.x + quad.w;\n                attributes.uv[j * 2 + 1] = quad.y;\n                attributes.color[j * 3] = color.r;\n                attributes.color[j * 3 + 1] = color.g;\n                attributes.color[j * 3 + 2] = color.b;\n                attributes.opacity[j] = opacity;\n                // Right bottom\n                j++;\n                attributes.pos[j * 2] = p.pos.x + hw * scale.x * c\n                    - hh * scale.y * s;\n                attributes.pos[j * 2 + 1] = p.pos.y + hw * scale.x * s\n                    + hh * scale.y * c;\n                attributes.uv[j * 2] = quad.x + quad.w;\n                attributes.uv[j * 2 + 1] = quad.y + quad.h;\n                attributes.color[j * 3] = color.r;\n                attributes.color[j * 3 + 1] = color.g;\n                attributes.color[j * 3 + 2] = color.b;\n                attributes.opacity[j] = opacity;\n                // Left bottom\n                j++;\n                attributes.pos[j * 2] = p.pos.x + (-hw) * scale.x * c\n                    - hh * scale.y * s;\n                attributes.pos[j * 2 + 1] = p.pos.y + (-hw) * scale.x * s\n                    + hh * scale.y * c;\n                attributes.uv[j * 2] = quad.x;\n                attributes.uv[j * 2 + 1] = quad.y + quad.h;\n                attributes.color[j * 3] = color.r;\n                attributes.color[j * 3 + 1] = color.g;\n                attributes.color[j * 3 + 2] = color.b;\n                attributes.opacity[j] = opacity;\n            }\n\n            drawRaw(\n                attributes,\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 { drawPicture, type Picture } from \"../../../gfx/draw/drawPicture\";\nimport type { Comp, GameObj } from \"../../../types\";\n\n/**\n * The {@link picture `picture()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface PictureComp extends Comp {\n    picture: Picture;\n}\n\n/**\n * Options for the {@link picture `picture()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport type PictureCompOpt = {\n    picture: Picture;\n};\n\nexport function picture(picture: Picture): PictureComp {\n    return {\n        id: \"picture\",\n        picture: picture,\n        draw(this: GameObj<PictureComp>) {\n            drawPicture(this.picture, getRenderProps(this));\n        },\n    };\n}\n", "import { getRenderProps } from \"../../../game/utils\";\nimport {\n    drawPolygon,\n    type DrawPolygonOpt,\n} from \"../../../gfx/draw/drawPolygon\";\nimport type { Texture } from \"../../../gfx/gfx\";\nimport type { Color } from \"../../../math/color\";\nimport { Polygon } from \"../../../math/math\";\nimport { type Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\nimport type { FillComp } from \"./fill\";\n\n/**\n * The {@link polygon `polygon()`} component.\n *\n * @since v3001.0\n * @group Components\n * @subgroup 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 opacity of each vertex.\n     */\n    opacities?: number[];\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 Components\n * @subgroup Component Types\n */\nexport type PolygonCompOpt = Omit<DrawPolygonOpt, \"pts\">;\n\nexport function polygon(\n    pts: Vec2[],\n    opt: PolygonCompOpt = {},\n): PolygonComp & { _renderAreaVersion: number } {\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        opacities: opt.opacities,\n        uv: opt.uv,\n        tex: opt.tex,\n        radius: opt.radius,\n        draw(this: GameObj<PolygonComp & FillComp>) {\n            drawPolygon(Object.assign(getRenderProps(this), {\n                pts: this.pts,\n                colors: this.colors,\n                opacities: this.opacities,\n                uv: this.uv,\n                tex: this.tex,\n                radius: this.radius,\n                fill: this.fill ?? opt.fill,\n                triangulate: opt.triangulate,\n            }));\n        },\n        renderArea(\n            this: GameObj<PolygonComp & { _renderAreaVersion: number }>,\n        ) {\n            // TODO: caching\n            this._renderAreaVersion = nextRenderAreaVersion();\n            return new Polygon(this.pts);\n        },\n        _renderAreaVersion: 0,\n        inspect() {\n            return `polygon: ${this.pts.map(p => `[${p.x},${p.y}]`).join(\",\")}`;\n        },\n    };\n}\n", "import type { RaycastResult } from \"../../../math/math\";\nimport type { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\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 type { Uniform } from \"../../../assets/shader\";\nimport type { Comp } from \"../../../types\";\n\n/**\n * The serialized {@link shader `shader()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializeShaderComp {\n    shader: string;\n}\n\n/**\n * The {@link shader `shader()`} component.\n *\n * @group Components\n * @subgroup 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    serialize(): SerializeShaderComp;\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        serialize() {\n            return { shader: this.shader };\n        },\n    };\n}\n\nexport function shaderFactory(data: any) {\n    return shader(data.shader);\n}\n", "import { DEF_ANCHOR } from \"../../constants/general\";\nimport { Color } from \"../../math/color\";\nimport { Quad } from \"../../math/math\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport { type Anchor, BlendMode, type RenderProps } from \"../../types\";\nimport { anchorPt } from \"../anchor\";\nimport type { Texture } from \"../gfx\";\nimport { drawRaw } from \"./drawRaw\";\nimport { drawUVQuad } from \"./drawUVQuad\";\n\n/**\n * How the texture should look like.\n *\n * @group Draw\n * @subgroup Types\n */\nexport type DrawTextureOpt = RenderProps & {\n    tex: Texture;\n    width?: number;\n    height?: number;\n    tiled?: boolean;\n    flipX?: boolean;\n    flipY?: boolean;\n    quad?: Quad;\n    anchor?: Anchor | Vec2;\n};\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\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        // cSpell: ignore fcols frows\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 attributes = {\n            pos: new Array<number>(n * 4 * 2),\n            uv: new Array<number>(n * 4 * 2),\n            color: new Array<number>(n * 4 * 3),\n            opacity: new Array<number>(n * 4),\n        };\n        let index = 0;\n\n        /*drawUVQuad(Object.assign({}, opt, {\n            scale: scale.scale(opt.scale ?? new Vec2(1)),\n        }));*/\n\n        const color = opt.color ?? Color.WHITE;\n        const opacity = opt.opacity ?? 1;\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            let s = index * 4;\n            attributes.pos[s * 2] = x + offsetX;\n            attributes.pos[s * 2 + 1] = y + offsetY;\n            attributes.uv[s * 2] = q.x;\n            attributes.uv[s * 2 + 1] = q.y;\n            attributes.color[s * 3] = color.r;\n            attributes.color[s * 3 + 1] = color.g;\n            attributes.color[s * 3 + 2] = color.b;\n            attributes.opacity[s] = opacity;\n            s++;\n            attributes.pos[s * 2] = x + w + offsetX;\n            attributes.pos[s * 2 + 1] = y + offsetY;\n            attributes.uv[s * 2] = q.x + q.w;\n            attributes.uv[s * 2 + 1] = q.y;\n            attributes.color[s * 3] = color.r;\n            attributes.color[s * 3 + 1] = color.g;\n            attributes.color[s * 3 + 2] = color.b;\n            attributes.opacity[s] = opacity;\n            s++;\n            attributes.pos[s * 2] = x + w + offsetX;\n            attributes.pos[s * 2 + 1] = y + h + offsetY;\n            attributes.uv[s * 2] = q.x + q.w;\n            attributes.uv[s * 2 + 1] = q.y + q.h;\n            attributes.color[s * 3] = color.r;\n            attributes.color[s * 3 + 1] = color.g;\n            attributes.color[s * 3 + 2] = color.b;\n            attributes.opacity[s] = opacity;\n            s++;\n            attributes.pos[s * 2] = x + offsetX;\n            attributes.pos[s * 2 + 1] = y + h + offsetY;\n            attributes.uv[s * 2] = q.x;\n            attributes.uv[s * 2 + 1] = q.y + q.h;\n            attributes.color[s * 3] = color.r;\n            attributes.color[s * 3 + 1] = color.g;\n            attributes.color[s * 3 + 2] = color.b;\n            attributes.opacity[s] = opacity;\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            attributes,\n            indices,\n            opt.fixed,\n            opt.tex,\n            opt.shader,\n            opt.uniform ?? undefined,\n            opt.blend ?? BlendMode.Normal,\n        );\n    }\n    else {\n        drawUVQuad(Object.assign({}, opt, {\n            scale: opt.scale ?? Vec2.ONE,\n            tex: opt.tex,\n            quad: q,\n            width: opt.width ?? w,\n            height: opt.height ?? h,\n        }));\n    }\n}\n", "// TODO: accept canvas\n\nimport type { Asset } from \"../../../assets/asset\";\nimport {\n    resolveSprite,\n    type SpriteAnim,\n    type SpriteData,\n} from \"../../../assets/sprite\";\nimport { DEF_ANCHOR } from \"../../../constants/general\";\nimport { KEvent, type KEventController } from \"../../../events/events\";\nimport { getRenderProps } from \"../../../game/utils\";\nimport { anchorPt } from \"../../../gfx/anchor\";\nimport { drawTexture } from \"../../../gfx/draw/drawTexture\";\nimport type { Texture } from \"../../../gfx/gfx\";\nimport { Quad, quad, Rect, vec2 } from \"../../../math/math\";\nimport { type Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj, SpriteAnimPlayOpt } from \"../../../types\";\nimport { warn } from \"../../../utils/log\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\n\n/**\n * The serialized {@link sprite `sprite()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport type SerializedSpriteComp = SpriteCompOpt & {\n    sprite: string;\n};\n\n/**\n * Current animation data.\n */\nexport interface SpriteCurAnim {\n    name: string;\n    timer: number;\n    loop: boolean;\n    speed: number;\n    /**\n     * The current index relative to the start of the\n     * associated `frames` array for this animation.\n     * This may be greater than the number of frames\n     * in the sprite.\n     */\n    frameIndex: number;\n    pingpong: boolean;\n    onEnd: () => void;\n}\n\n/**\n * The {@link sprite `sprite()`} component.\n *\n * @group Components\n * @subgroup 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    serialize(): SerializedSpriteComp;\n}\n\n/**\n * Options for the {@link sprite `sprite()`} component.\n *\n * @group Components\n * @subgroup 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 & { _renderAreaVersion: number } {\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(\"Please pass the resource name or data to sprite()\");\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 frame = spr.frames[0];\n        let q = frame.q.clone();\n\n        if (opt.quad) {\n            q = q.scale(opt.quad);\n        }\n\n        const scale = calcTexScale(frame.tex, q, opt.width, opt.height);\n\n        obj.width = frame.tex.width * q.w * scale.x;\n        obj.height = frame.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(\n                \"Sprite anim 'from' and 'to' must be defined if 'frames' is not defined\",\n            );\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    let _shape: Rect | undefined;\n    let _width = 0;\n    let _height = 0;\n\n    return {\n        id: \"sprite\",\n        // TODO: allow update\n        get width() {\n            return _width;\n        },\n        set width(value) {\n            if (_width != value) {\n                _width = value;\n                if (_shape) _shape.width = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get height() {\n            return _height;\n        },\n        set height(value) {\n            if (_height != value) {\n                _height = value;\n                if (_shape) _shape.height = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\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 frame = spriteData.frames[this.frame ?? 0];\n\n            if (!frame) {\n                throw new Error(`Frame not found: ${this.frame ?? 0}`);\n            }\n\n            if (spriteData.slice9) {\n                // TODO: use scale or width / height, or both?\n                const { left, right, top, bottom, tileMode } =\n                    spriteData.slice9;\n\n                if (opt.tiled) {\n                    warn(\n                        \"sprite(): 'tiled' option is ignored for 9-slice sprites. Use 'tileMode' in slice9 config instead.\",\n                    );\n                }\n\n                const tw = frame.tex.width * frame.q.w;\n                const th = frame.tex.height * frame.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                const props = getRenderProps(this);\n                const offset = anchorPt(props.anchor || DEF_ANCHOR);\n                const offsetX = -(offset.x + 1) * 0.5 * this.width;\n                const offsetY = -(offset.y + 1) * 0.5 * this.height;\n                for (let i = 0; i < 9; i++) {\n                    const uv = quads[i];\n                    const transform = quads[i + 9];\n                    if (transform.w == 0 || transform.h == 0) {\n                        continue;\n                    }\n                    const isCenter = i === 4;\n                    const isEdge = !!(i & 1);\n                    const shouldTile = isCenter\n                        ? tileMode === \"center\" || tileMode === \"all\"\n                        : isEdge\n                        ? tileMode === \"edges\" || tileMode === \"all\"\n                        : false;\n                    drawTexture(\n                        Object.assign(props, {\n                            pos: transform.pos().add(offsetX, offsetY),\n                            anchor: \"topleft\",\n                            tex: frame.tex,\n                            quad: frame.q.scale(uv),\n                            flipX: this.flipX,\n                            flipY: this.flipY,\n                            tiled: shouldTile,\n                            width: transform.w,\n                            height: transform.h,\n                        }),\n                    );\n                }\n            }\n            else {\n                drawTexture(\n                    Object.assign(getRenderProps(this), {\n                        tex: frame.tex,\n                        quad: frame.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                _k.k.onLoad(() =>\n                    setSpriteData(this, resolveSprite(src)!.data)\n                );\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 += _k.app.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                    }\n                    else if (curAnim.loop) {\n                        curAnim.frameIndex = 0;\n                    }\n                    else {\n                        this.frame = frames.at(-1)!;\n                        const anim = curAnim;\n                        this.stop();\n                        anim.onEnd();\n                        return;\n                    }\n                }\n                else if (curAnim.frameIndex < 0) {\n                    if (curAnim.pingpong && curAnim.loop) {\n                        curAnimDir = 1;\n                        curAnim.frameIndex = 1;\n                    }\n                    else if (curAnim.loop) {\n                        curAnim.frameIndex = frames.length - 1;\n                    }\n                    else {\n                        this.frame = frames[0];\n                        const anim = curAnim;\n                        this.stop();\n                        anim.onEnd();\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                if (opt.preventRestart && curAnim.name === name) return;\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 this.getAnim(name) !== null;\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            if (!_shape) {\n                _shape = new Rect(vec2(0), _width, _height);\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n\n        _renderAreaVersion: 0,\n\n        inspect() {\n            if (typeof src === \"string\") {\n                return `sprite: \"${src}\"`;\n            }\n            return null;\n        },\n\n        serialize() {\n            const data: any = { sprite: this.sprite };\n            if (opt.frame) data.frame = opt.frame;\n            if (opt.tiled) data.tiled = opt.tiled;\n            if (opt.width) data.width = opt.width;\n            if (opt.height) data.height = opt.height;\n            if (opt.anim) data.anim = opt.anim;\n            if (opt.animSpeed) data.animSpeed = opt.animSpeed;\n            if (this.flipX) data.flipX = this.flipX;\n            if (this.flipY) data.flipY = this.flipY;\n            if (opt.quad) {\n                data.quad = {\n                    x: opt.quad.x,\n                    y: opt.quad.y,\n                    w: opt.quad.w,\n                    h: opt.quad.h,\n                };\n            }\n            return data;\n        },\n    };\n}\n\nexport function spriteFactory(data: SerializedSpriteComp) {\n    const opt: SpriteCompOpt = {};\n    if (data.frame) opt.frame = data.frame;\n    if (data.tiled) opt.tiled = data.tiled;\n    if (data.width) opt.width = data.width;\n    if (data.height) opt.height = data.height;\n    if (data.anim) opt.anim = data.anim;\n    if (data.animSpeed) opt.animSpeed = data.animSpeed;\n    if (data.flipX) opt.flipX = data.flipX;\n    if (data.flipY) opt.flipY = data.flipY;\n    if (data.quad) {\n        opt.quad = quad(data.quad.x, data.quad.y, data.quad.w, data.quad.h);\n    }\n    return sprite(data.sprite, opt);\n}\n", "import type { BitmapFontData } from \"../../../assets/bitmapFont\";\nimport { DEF_TEXT_SIZE } from \"../../../constants/general\";\nimport { getRenderProps } from \"../../../game/utils\";\nimport {\n    drawFormattedText,\n    type FormattedText,\n} from \"../../../gfx/draw/drawFormattedText\";\nimport type {\n    CharTransform,\n    CharTransformFunc,\n    TextAlign,\n} from \"../../../gfx/draw/drawText\";\nimport { formatText } from \"../../../gfx/formatText\";\nimport { Rect, vec2 } from \"../../../math/math\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\n\n/**\n * The serialized {@link text `text()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedTextComp {\n    text: string;\n    size?: number;\n    font?: string;\n    width?: number;\n    align?: TextAlign;\n    lineSpacing?: number;\n    letterSpacing?: number;\n    indentAll?: boolean;\n}\n\n/**\n * The {@link text `text()`} component.\n *\n * @group Components\n * @subgroup 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 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    _renderAreaVersion: number;\n    /**\n     * The text data object after formatting, that contains the\n     * renering info as well as the parse data of the formatting tags.\n     */\n    formattedText(): FormattedText;\n\n    serialize(): SerializedTextComp;\n}\n\n/**\n * Options for the {@link text `text()`} component.\n *\n * @group Components\n * @subgroup 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    let theFormattedText: FormattedText;\n    function update(obj: GameObj<TextComp | any>) {\n        theFormattedText = 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            transform: obj.textTransform,\n            styles: obj.textStyles,\n            indentAll: opt.indentAll,\n        }));\n\n        if (!opt.width) {\n            obj.width = theFormattedText.width / (obj.scale?.x || 1);\n        }\n\n        obj.height = theFormattedText.height / (obj.scale?.y || 1);\n    }\n\n    let _shape: Rect | undefined;\n    let _width = opt.width ?? 0;\n    let _height = 0;\n\n    const obj: TextComp = {\n        id: \"text\",\n        set text(nt) {\n            t = nt;\n            // @ts-expect-error\n            update(this);\n        },\n        get text() {\n            return t;\n        },\n        textSize: opt.size ?? DEF_TEXT_SIZE,\n        font: opt.font!,\n        get width() {\n            return _width;\n        },\n        set width(value) {\n            if (_width != value) {\n                _width = value;\n                if (_shape) _shape.width = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get height() {\n            return _height;\n        },\n        set height(value) {\n            if (_height != value) {\n                _height = value;\n                if (_shape) _shape.height = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        align: opt.align!,\n        lineSpacing: opt.lineSpacing!,\n        letterSpacing: opt.letterSpacing!,\n        textTransform: opt.transform!,\n        textStyles: opt.styles!,\n\n        formattedText(this: GameObj<TextComp>) {\n            return theFormattedText;\n        },\n\n        add(this: GameObj<TextComp>) {\n            _k.k.onLoad(() => update(this));\n        },\n\n        draw(this: GameObj<TextComp>) {\n            drawFormattedText(theFormattedText);\n        },\n\n        update(this: GameObj<TextComp>) {\n            update(this);\n        },\n\n        renderArea() {\n            if (!_shape) {\n                _shape = new Rect(vec2(0), _width, _height);\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n\n        _renderAreaVersion: 0,\n\n        serialize() {\n            return {\n                text: this.text,\n                size: this.textSize,\n                font: typeof this.font === \"string\" ? this.font : undefined,\n                width: this.width,\n                align: this.align,\n                lineSpacing: this.lineSpacing,\n                letterSpacing: this.letterSpacing,\n                indentAll: opt.indentAll,\n            };\n        },\n    };\n\n    // @ts-expect-error\n    update(obj);\n\n    // @ts-ignore Deep check in text related methods\n    return obj;\n}\n\nexport function textFactory(data: SerializedTextComp) {\n    return text(data.text, {\n        align: data.align,\n        font: data.font,\n        width: data.width,\n        size: data.size,\n        indentAll: data.indentAll,\n        letterSpacing: data.letterSpacing,\n        lineSpacing: data.letterSpacing,\n    });\n}\n", "import { getRenderProps } from \"../../../game/utils\";\nimport { drawUVQuad } from \"../../../gfx/draw/drawUVQuad\";\nimport { Rect, vec2 } from \"../../../math/math\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\n\n/**\n * The {@link uvquad `uvquad()`} component.\n *\n * @group Components\n * @subgroup 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}\n\nexport function uvquad(\n    w: number,\n    h: number,\n): UVQuadComp & { _renderAreaVersion: number } {\n    let _shape: Rect | undefined;\n    let _width = w;\n    let _height = h;\n    return {\n        id: \"uvquad\",\n        get width() {\n            return _width;\n        },\n        set width(value) {\n            if (_width != value) {\n                _width = value;\n                if (_shape) _shape.width = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get height() {\n            return _height;\n        },\n        set height(value) {\n            if (_height != value) {\n                _height = value;\n                if (_shape) _shape.height = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        draw(this: GameObj<UVQuadComp>) {\n            drawUVQuad(Object.assign(getRenderProps(this), {\n                width: _width,\n                height: _height,\n            }));\n        },\n        renderArea() {\n            if (!_shape) {\n                _shape = new Rect(vec2(0), _width, _height);\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n        _renderAreaVersion: 0,\n        inspect() {\n            return `uvquad: (${Math.ceil(_width)}w, ${Math.ceil(_height)})h`;\n        },\n    };\n}\n", "import { getRenderProps } from \"../../../game/utils\";\nimport { drawRect } from \"../../../gfx/draw/drawRect\";\nimport { drawUVQuad } from \"../../../gfx/draw/drawUVQuad\";\nimport { Texture } from \"../../../gfx/gfx\";\nimport { Rect, vec2 } from \"../../../math/math\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { nextRenderAreaVersion } from \"../physics/area\";\nimport type { PosComp } from \"../transform/pos\";\n\nexport interface VideoComp extends Comp {\n    width: number;\n    height: number;\n    currentTime: number;\n    duration: number;\n    play(): void;\n    pause(): void;\n    mute: boolean;\n    renderArea(): Rect;\n}\n\nexport type VideoCompOpt = {\n    width: number;\n    height: number;\n};\n\n// region video\nexport function video(\n    url: string,\n    opt: VideoCompOpt,\n): VideoComp & { _renderAreaVersion: number } {\n    const _video: HTMLVideoElement = document.createElement(\"video\");\n    let _playing = false;\n    let _timeupdate = false;\n    let _canCopyVideo = false;\n    let _texture = new Texture(_k.gfx.ggl, opt.width, opt.height);\n    let _shape: Rect | undefined;\n    let _width = opt.width;\n    let _height = opt.height;\n    return {\n        id: \"video\",\n        get width() {\n            return _width;\n        },\n        set width(value) {\n            if (_width != value) {\n                _width = value;\n                if (_shape) _shape.width = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get height() {\n            return _height;\n        },\n        set height(value) {\n            if (_height != value) {\n                _height = value;\n                if (_shape) _shape.height = value;\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n        },\n        get currentTime() {\n            return _video.currentTime;\n        },\n        set currentTime(value) {\n            _video.currentTime = value;\n        },\n        get duration() {\n            return _video.duration;\n        },\n        play() {\n            _video.play();\n        },\n        pause() {\n            _video.pause();\n        },\n        get mute() {\n            return _video.muted;\n        },\n        set mute(value) {\n            _video.muted = value;\n        },\n        add() {\n            _video.playsInline = true;\n            // _video.muted = true; Don't use this, sound will not work\n            _video.loop = true;\n            _video.autoplay = false;\n            _video.crossOrigin = \"anonymous\";\n\n            _video.addEventListener(\n                \"playing\",\n                () => {\n                    _playing = true;\n                    updateCopyFlag();\n                },\n                true,\n            );\n\n            _video.addEventListener(\n                \"timeupdate\",\n                () => {\n                    _timeupdate = true;\n                    updateCopyFlag();\n                },\n                true,\n            );\n\n            if (url.startsWith(\"http\")) { // Make sure redirects work\n                // console.log(`Fetching ${url}`);\n\n                fetch(url, {\n                    method: \"HEAD\",\n                    mode: \"no-cors\",\n                }).then((response) => {\n                    _video.src = response.url ? response.url : url;\n                });\n            }\n            else {\n                // console.log(`Not fetching ${url}`);\n\n                _video.src = url;\n            }\n\n            function updateCopyFlag() {\n                // console.log(`${_playing} ${_timeupdate}`);\n\n                if (_playing && _timeupdate) {\n                    _canCopyVideo = true;\n                }\n            }\n        },\n        update() {\n            if (_canCopyVideo) {\n                const gl = _k.gfx.ggl.gl;\n                _texture.bind();\n                gl.texImage2D(\n                    gl.TEXTURE_2D,\n                    0,\n                    gl.RGBA,\n                    gl.RGBA,\n                    gl.UNSIGNED_BYTE,\n                    _video,\n                );\n                _texture.unbind();\n\n                // console.log(`${this.currentTime}/${this.duration}`);\n            }\n        },\n        draw(this: GameObj<PosComp | VideoComp>) {\n            if (_canCopyVideo) {\n                drawUVQuad(Object.assign(getRenderProps(this), {\n                    width: this.width,\n                    height: this.height,\n                    tex: _texture,\n                }));\n            }\n            else {\n                drawRect(Object.assign(getRenderProps(this), {\n                    width: this.width,\n                    height: this.height,\n                }));\n            }\n        },\n        renderArea() {\n            if (!_shape) {\n                _shape = new Rect(vec2(0), _width, _height);\n                this._renderAreaVersion = nextRenderAreaVersion();\n            }\n            return _shape;\n        },\n        _renderAreaVersion: 0,\n    };\n}\n", "import type { KEventController } from \"../../../events/events\";\nimport type { Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport type { PosComp } from \"../transform/pos\";\nimport type { TileComp } from \"./tile\";\n\n/**\n * The {@link agent `agent()`} component.\n *\n * @group Components\n * @subgroup 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 Components\n * @subgroup 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", "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", "import { toScreen, toWorld } from \"../../../game/camera\";\nimport { drawCircle } from \"../../../gfx/draw/drawCircle\";\nimport { rgb } from \"../../../math/color\";\nimport { vec2, type Vec2Args } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport {\n    type InternalGameObjRaw,\n    nextTransformVersion,\n} from \"../../entity/GameObjRaw\";\nimport { isFixed } from \"../../entity/utils\";\nimport type { FixedComp } from \"./fixed\";\n\n/**\n * The serialized {@link pos `pos()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedPosComp {\n    pos: { x: number; y: number };\n}\n\n/**\n * The {@link pos `pos()`} component.\n *\n * @group Components\n * @subgroup 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: Vec2;\n    /**\n     * Get / Set the position of the object relative to the root.\n     *\n     * @since v2000.0\n     */\n    worldPos: Vec2;\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     * Serialize the current state comp\n     */\n    serialize(): SerializedPosComp;\n}\n\nexport function pos(...args: Vec2Args): PosComp {\n    const _pos = vec2(...args);\n    const _posReadOnly = vec2(...args);\n\n    return {\n        id: \"pos\",\n\n        add() {\n            (this as any as InternalGameObjRaw)._transformVersion =\n                nextTransformVersion();\n        },\n\n        get pos(): Vec2 {\n            return _posReadOnly;\n        },\n        set pos(value: Vec2) {\n            _pos.x = value.x;\n            _pos.y = value.y;\n            _posReadOnly.x = value.x;\n            _posReadOnly.y = value.y;\n            (this as any as InternalGameObjRaw)._transformVersion =\n                nextTransformVersion();\n        },\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(_k.app.dt()));\n        },\n\n        // move to a destination, with optional speed\n        // Address 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 * _k.app.dt()) {\n                this.pos = vec2(dest);\n                return;\n            }\n            this.move(diff.unit().scale(speed));\n        },\n\n        // Set the position of the object relative to the root\n        set worldPos(pos: Vec2) {\n            const obj = this as unknown as GameObj<PosComp>;\n            this.pos = obj.parent\n                ? obj.parent.transform.inverse.transformPointV(pos, vec2())\n                : pos;\n        },\n\n        get worldPos(): Vec2 {\n            const obj = this as unknown as GameObj<PosComp>;\n            return obj.parent\n                ? obj.parent.transform.transformPointV(obj.pos, vec2())\n                : obj.pos;\n        },\n\n        // Transform a local point to a world point\n        toWorld(this: GameObj<PosComp>, p: Vec2): Vec2 {\n            return this.transform.transformPointV(p, vec2());\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.transform.inverse.transformPointV(p, vec2());\n        },\n\n        // Transform a screen point (relative to the camera) to a local point (relative to this)\n        set screenPos(pos: Vec2) {\n            const obj = this as unknown as GameObj<PosComp>;\n            this.worldPos = isFixed(obj)\n                ? pos\n                : toWorld(pos);\n        },\n\n        get screenPos() {\n            const obj = this as unknown as GameObj<PosComp>;\n            const pos = obj.worldPos;\n            return isFixed(obj)\n                ? pos\n                : toScreen(pos);\n        },\n\n        // Transform a local point (relative to this) to a screen point (relative to the camera)\n        toScreen(this: GameObj<PosComp | FixedComp>, pos: Vec2): Vec2 {\n            pos = this.toWorld(pos);\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>, pos: Vec2): Vec2 {\n            return isFixed(this)\n                ? this.fromWorld(pos)\n                : this.fromWorld(toWorld(pos));\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 / _k.gfx.viewport.scale,\n            });\n        },\n\n        serialize() {\n            return { pos: this.pos.serialize() };\n        },\n    };\n}\n\nexport function posFactory(data: SerializedPosComp) {\n    return pos(data.pos.x, data.pos.y);\n}\n", "import { vec2 } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { type Comp, type Edge, EdgeMask, type GameObj } from \"../../../types\";\nimport type { LevelComp } from \"./level\";\n\n/**\n * The {@link tile `tile()`} component.\n *\n * @group Components\n * @subgroup 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 Components\n * @subgroup 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 type { KEventController } from \"../../../events/events\";\nimport {\n    raycastGrid,\n    type RaycastResult,\n    vec2,\n    type Vec2Args,\n} from \"../../../math/math\";\nimport { calcTransform } from \"../../../math/various\";\nimport { type Vec2 } from \"../../../math/Vec2\";\nimport {\n    type Comp,\n    type CompList,\n    EdgeMask,\n    type GameObj,\n} from \"../../../types\";\nimport { BinaryHeap } from \"../../../utils/binaryheap\";\nimport { deserializeComp } from \"../../entity/prefab\";\nimport { pos, type PosComp } from \"../transform/pos\";\nimport { tile } from \"./tile\";\n\n/**\n * The {@link level `level()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface LevelComp extends Comp {\n    tileWidth(): number;\n    tileHeight(): number;\n    numRows(): number;\n    numColumns(): number;\n    /**\n     * Spawn a tile from a symbol defined previously.\n     */\n    spawn(sym: string, p: Vec2): GameObj | null;\n    spawn(sym: string, x: number, y: number): GameObj | null;\n    /**\n     * Spawn a tile from a component list.\n     *\n     * @returns The spawned game object, or null if the obj hasn't components.\n     */\n    spawn<T>(obj: CompList<T>, p: Vec2): GameObj<T> | null;\n    spawn<T>(sym: CompList<T>, x: number, y: number): GameObj<T> | null;\n    /**\n     * Total width of level in pixels.\n     */\n    levelWidth(): number;\n    /**\n     * Total height of level in pixels.\n     */\n    levelHeight(): number;\n    /**\n     * Get all game objects that's currently inside a given tile.\n     */\n    getAt(tilePos: Vec2): GameObj[];\n    /**\n     * Raycast all game objects on the given path.\n     */\n    raycast(origin: Vec2, direction: Vec2): RaycastResult;\n    /**\n     * Convert tile position to pixel position.\n     */\n    tile2Pos(tilePos: Vec2): Vec2;\n    tile2Pos(x: number, y: number): Vec2;\n    /**\n     * Convert pixel position to tile position.\n     */\n    pos2Tile(pos: Vec2): Vec2;\n    pos2Tile(x: number, y: number): Vec2;\n    /**\n     * Find the path to navigate from one tile to another tile.\n     *\n     * @returns A list of traverse points in tile positions.\n     */\n    getTilePath(from: Vec2, to: Vec2, opts?: PathFindOpt): Vec2[] | null;\n    /**\n     * Find the path to navigate from one tile to another tile.\n     *\n     * @returns A list of traverse points in pixel positions.\n     */\n    getPath(from: Vec2, to: Vec2, opts?: PathFindOpt): Vec2[] | null;\n    getSpatialMap(): GameObj[][];\n    removeFromSpatialMap(obj: GameObj): void;\n    insertIntoSpatialMap(obj: GameObj): void;\n    onSpatialMapChanged(cb: () => void): KEventController;\n    onNavigationMapInvalid(cb: () => void): KEventController;\n    invalidateNavigationMap(): void;\n    onNavigationMapChanged(cb: () => void): KEventController;\n\n    serialize(): any;\n}\n\n/**\n * Options for the {@link level `level()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface LevelCompOpt {\n    /**\n     * Width of each block.\n     */\n    tileWidth: number;\n    /**\n     * Height of each block.\n     */\n    tileHeight: number;\n    /**\n     * Definition of each tile.\n     */\n    tiles: {\n        [sym: string]: (pos: Vec2) => CompList<Comp>;\n    };\n    /**\n     * Called when encountered a symbol not defined in \"tiles\".\n     */\n    wildcardTile?: (\n        sym: string,\n        pos: Vec2,\n    ) => CompList<Comp> | null | undefined;\n}\n\n/**\n * @group Components\n * @subgroup Component Types\n */\nexport type PathFindOpt = {\n    allowDiagonals?: boolean;\n};\n\nexport function level(map: string[], opt: LevelCompOpt): LevelComp {\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(Math.floor(hash % numColumns), Math.floor(hash / numColumns));\n\n    const createSpatialMap = (level: GameObj<LevelComp>) => {\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 = (level: GameObj<LevelComp>) => {\n        let spatialMapChanged = false;\n        for (const child of level.children) {\n            const tilePos = level.pos2Tile(child.pos);\n            if (child.tilePos.x != tilePos.x || child.tilePos.y != tilePos.y) {\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 = (level: GameObj<LevelComp>) => {\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 = (level: GameObj<LevelComp>) => {\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 = (level: GameObj<LevelComp>) => {\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    return {\n        id: \"level\",\n\n        add(this: GameObj<LevelComp>) {\n            map.forEach((row, i) => {\n                const keys = row.split(\"\");\n                numColumns = Math.max(keys.length, numColumns);\n                keys.forEach((key, j) => {\n                    this.spawn(key, vec2(j, i));\n                });\n            });\n        },\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(\"Expected a symbol or a component list\");\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 = this.add(comps);\n\n            if (hasPos) {\n                obj.tilePosOffset = obj.pos.clone();\n            }\n\n            obj.tilePos = p;\n            // Stale, so recalculate\n            calcTransform(obj, obj.transform);\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(this: GameObj<LevelComp>) {\n            if (!spatialMap) {\n                createSpatialMap(this);\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(this: GameObj<LevelComp>, tilePos: Vec2) {\n            if (!spatialMap) {\n                createSpatialMap(this);\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(\n                levelOrigin,\n                direction,\n                (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                },\n                64,\n            );\n            if (hit) {\n                hit.point = hit.point.scale(this.tileWidth());\n            }\n            return hit;\n        },\n\n        update(this: GameObj<LevelComp>) {\n            if (spatialMap) {\n                updateSpatialMap(this);\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(this);\n            }\n            if (!edgeMap) {\n                createEdgeMap(this);\n            }\n            if (!connectivityMap) {\n                createConnectivityMap(this);\n            }\n\n            // Tiles are outside the grid\n            if (\n                from.x < 0\n                || from.x >= numColumns\n                || from.y < 0\n                || from.y >= numRows\n            ) {\n                return null;\n            }\n            if (to.x < 0 || to.x >= numColumns || to.y < 0 || to.y >= numRows) {\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(current, opts.allowDiagonals);\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        serialize(): any {\n            const data: any = {};\n            data.tileWidth = opt.tileWidth;\n            data.tileHeight = opt.tileHeight;\n            data.tiles = {}; // { symbol: prefab };\n            // tiles maps symbols to functions returning a list of components\n            // To serialize this, we get the list of components for each symbol, and serialize them\n            for (const key of Object.keys(opt.tiles)) {\n                const compsAndTags = opt.tiles[key](vec2());\n                const comps: any = {};\n                const tags = [];\n                for (const compOrTag of compsAndTags) {\n                    if (typeof compOrTag === \"string\") {\n                        tags.push(compOrTag);\n                    }\n                    else {\n                        if (\"id\" in compOrTag && \"serialize\" in compOrTag) {\n                            comps[compOrTag.id!] =\n                                (compOrTag.serialize as () => any)();\n                        }\n                    }\n                }\n                if (tags.length) comps.tags = tags;\n                data.tiles[key] = comps;\n            }\n            // No idea how to handle this yet\n            data.wildcardTile = {}; // prefab\n            return data;\n        },\n    };\n}\n\nexport function levelFactory(data: any) {\n    const opt: any = { tileWidth: data.tileWidth, tileHeight: data.tileHeight };\n    opt.tiles = {};\n    for (const key in Object.keys(data.tiles)) {\n        const d = data.tiles[key];\n        const tags = d.tags;\n        opt.tiles[key] = (pos: Vec2) => {\n            const comps: Comp[] = Object.keys(d).filter(k => k != \"tags\").map(\n                id => deserializeComp(id, d[id]),\n            );\n            return [...comps, ...tags];\n        };\n    }\n    return level([], opt);\n}\n", "import { BinaryHeap } from \"../utils/binaryheap\";\nimport { Vec2 } from \"./Vec2\";\n\nexport interface Graph {\n    /* Returns the reachable neighbors of this location */\n    getNeighbors(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    nodes: number[];\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.getNeighbors(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 neighbors = graph.getNeighbors(current!);\n        for (let next of neighbors) {\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 neighbors = graph.getNeighbors(current!);\n        for (let next of neighbors) {\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\nexport function floodFill(\n    graph: Graph,\n    start: number | number[],\n    predicate: (node: number) => boolean,\n) {\n    const stack = Array.isArray(start) ? start : [start];\n    const fill: Set<number> = new Set();\n    while (stack.length) {\n        const node = stack.pop()!;\n        if (!predicate(node)) {\n            continue;\n        }\n        // Fill\n        fill.add(node);\n        for (const neighbor of graph.getNeighbors(node)) {\n            // If not filled and fillable\n            if (!fill.has(neighbor) && predicate(neighbor)) {\n                // We need to look around nn later\n                stack.push(neighbor);\n            }\n        }\n    }\n    return [...fill];\n}\n\nexport function buildConnectivityMap(graph: Graph) {\n    const map: Map<number, number> = new Map();\n    let index = 0;\n    for (const node of graph.nodes) {\n        if (map.get(node) !== undefined) {\n            // This node has been processed\n            continue;\n        }\n        // Fill all connected nodes\n        for (const fill of floodFill(graph, node, () => true)) {\n            map.set(fill, index);\n        }\n        index++;\n    }\n    return map;\n}\n", "import { type Graph } from \"../../../math/navigation\";\nimport { Vec2 } from \"../../../math/Vec2\";\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 type { KEventController } from \"../../../events/events\";\nimport type { Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\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 = false;\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 type { KEventController } from \"../../../events/events\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj, QueryOpt } from \"../../../types\";\nimport { raycast } from \"../draw/raycast\";\nimport type { PosComp } from \"../transform/pos\";\n\n/**\n * The {@link sentry `sentry()`} component.\n *\n * @group Components\n * @subgroup 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 Components\n * @subgroup 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 += _k.app.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 type { KEventController } from \"../../../events/events\";\nimport { clamp } from \"../../../math/clamp\";\nimport { Color } from \"../../../math/color\";\nimport { type EaseFunc, easings } from \"../../../math/easings\";\nimport { lerp, type LerpValue } from \"../../../math/lerp\";\nimport { catmullRom, hermiteFirstDerivative, vec2 } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\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\n/**\n * The {@link animate `animate()`} component.\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         * @param time - Time to move the animation to in seconds\n         */\n        seek(time: number): void;\n        /**\n         * Returns the duration of the animation\n         */\n        duration: number;\n        /**\n         * Returns the animation with the specified name\n         * @param name - Name of the animation to retrieve\n         */\n        get(name: string): Anim;\n        /**\n         * Play the animation with the specified name\n         * @param name\n         */\n        play(name: string): void;\n        /**\n         * Stop playing the current animation\n         */\n        stop(): void;\n    };\n    /**\n     * Serializes the animation of this object to plain Javascript types\n     */\n    serializeAnimations(): Record<string, AnimationChannels>;\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     *\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 *\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 AnimationChannels = Record<string, AnimationChannel>;\n\ntype Animation = {\n    name: string;\n    followMotion?: boolean;\n    relative?: boolean;\n    anims?: Record<string, AnimationChannels>;\n    children?: Animation[];\n};\n\nclass Anim {\n    name: string;\n    opts: AnimateCompOpt;\n    channels: AnimateChannel[] = [];\n    isFinished: boolean = false;\n\n    constructor(name: string, opts: AnimateCompOpt) {\n        this.name = name;\n        this.opts = opts;\n    }\n\n    get duration() {\n        return this.channels.reduce(\n            (acc, channel) => Math.max(channel.duration, acc),\n            0,\n        );\n    }\n\n    // Add channel\n    animate<T extends LerpValue>(\n        name: string,\n        keys: T[],\n        opts: AnimateOpt,\n    ) {\n        this.unanimate(name);\n        if (typeof keys[0] === \"number\") {\n            this.channels.push(\n                new AnimateChannelNumber(\n                    name,\n                    keys as number[],\n                    opts,\n                    this.opts.relative || false,\n                ),\n            );\n        }\n        else if (keys[0] instanceof Vec2) {\n            this.channels.push(\n                new AnimateChannelVec2(\n                    name,\n                    keys as Vec2[],\n                    opts,\n                    this.opts.relative || false,\n                    name === \"pos\" && (this.opts.followMotion || false),\n                ),\n            );\n        }\n        else if (keys[0] instanceof Color) {\n            this.channels.push(\n                new AnimateChannelColor(\n                    name,\n                    keys as Color[],\n                    opts,\n                    this.opts.relative || false,\n                ),\n            );\n        }\n    }\n\n    // Remove channel\n    unanimate(name: string) {\n        const index = this.channels.findIndex(c => c.name === name);\n        if (index >= 0) {\n            this.channels.splice(index, 1);\n        }\n    }\n\n    unanimateAll() {\n        this.channels.length = 0;\n    }\n\n    // Play methods\n    play() {\n        this.isFinished = false;\n    }\n\n    stop() {\n        this.isFinished = true;\n    }\n\n    serialize() {\n        return this.channels.reduce(\n            (o: Record<string, AnimationChannel>, c) => {\n                o[c.name] = c.serialize();\n                return o;\n            },\n            {},\n        );\n    }\n\n    // Internal update\n    _update(obj: GameObj<AnimateComp>, t: number) {\n        if (this.isFinished) {\n            return;\n        }\n        let allFinished: boolean = true;\n        let localFinished: boolean;\n        for (const c of this.channels) {\n            localFinished = c.update(obj, t);\n            if (localFinished && !c.isFinished) {\n                c.isFinished = true;\n                obj.trigger(\n                    \"animateChannelFinished\",\n                    c.name,\n                );\n            }\n            allFinished &&= localFinished;\n        }\n        if (allFinished) {\n            this.isFinished = true;\n            obj.trigger(\n                \"animateFinished\",\n            );\n        }\n    }\n}\n\nexport function animate(gopts: AnimateCompOpt = {}): AnimateComp {\n    const anims: Anim[] = [];\n    let currentAnim: Anim | null = null;\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                if (currentAnim) {\n                    currentAnim.play();\n                }\n            },\n            get duration() {\n                return currentAnim?.duration || 0;\n            },\n            get(name: string): Anim {\n                let anim = anims.find(anim => anim.name === name);\n                if (!anim) {\n                    anim = new Anim(name, gopts);\n                    anims.push(anim);\n                }\n                return anim;\n            },\n            play(name: string = \"\") {\n                currentAnim = anims.find(anim => anim.name === name) || null;\n                if (!currentAnim) {\n                    throw new Error(\n                        `Trying to play unknown animation called ${name}`,\n                    );\n                }\n                t = 0;\n                currentAnim.play();\n            },\n            stop() {\n                if (currentAnim) {\n                    currentAnim.stop();\n                }\n            },\n        },\n\n        // Component events\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.clone();\n                }\n                if (this.has(\"opacity\")) {\n                    this.base.opacity = (this as any).opacity;\n                }\n            }\n        },\n        update(this: GameObj<AnimateComp>) {\n            t += _k.app.dt();\n            if (currentAnim || (currentAnim = this.animation.get(\"\"))) {\n                // debug.log(`playing ${currentAnim.name}`)\n                currentAnim._update(this, t);\n            }\n        },\n\n        // The following methods work on the default animation (named \"\") for compatibility\n        animate<T extends LerpValue>(\n            name: string,\n            keys: T[],\n            opts: AnimateOpt,\n        ) {\n            this.animation.get(\"\").animate(name, keys, opts);\n        },\n        unanimate(name: string) {\n            this.animation.get(\"\").unanimate(name);\n        },\n        unanimateAll() {\n            this.animation.get(\"\").unanimateAll();\n        },\n\n        // Play events\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\n        // Serialization\n        serializeAnimations() {\n            return anims.reduce((o: any, anim) => {\n                o[anim.name] = anim.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 *\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 || name };\n    if (obj.has(\"animate\")) {\n        serialization.anims = (obj as GameObj<AnimateComp>)\n            .serializeAnimations();\n        console.log(serialization);\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.anims) {\n        for (const name in animation.anims) {\n            const anim = obj.animation.get(name);\n            const propchannels = animation.anims[name];\n            for (const prop in propchannels) {\n                const channel = propchannels[prop];\n                obj.animate(\n                    prop,\n                    deserializeKeys(channel.keys),\n                    deserializeOptions(channel),\n                );\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 type { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport type { PosComp } from \"../transform/pos\";\n\n/**\n * The {@link fakeMouse `fakeMouse()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface FakeMouseComp extends Comp {\n    /**\n     * Whether the fake mouse is pressed.\n     */\n    get isPressed(): boolean;\n    /**\n     * Trigger press (onClick).\n     */\n    press(): void;\n    /**\n     * Trigger release.\n     */\n    release(): void;\n    /**\n     * Register an event that runs when the fake mouse performs a click.\n     */\n    onPress(action: () => void): void;\n    /**\n     * Register an event that runs when the fake mouse releases.\n     */\n    onRelease(action: () => void): void;\n}\n\n/**\n * Options for the {@link fakeMouse `fakeMouse()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport type FakeMouseOpt = {\n    /**\n     * Whether the fake mouse should follow the real mouse. Defaults to `true`.\n     */\n    followMouse?: boolean;\n};\n\ntype FakeMouse = GameObj<FakeMouseComp | PosComp>;\n\nexport const fakeMouse = (opt: FakeMouseOpt = {\n    followMouse: true,\n}): FakeMouseComp => {\n    let isPressed = false;\n    let lastPos: Vec2;\n\n    return {\n        id: \"fakeMouse\",\n        require: [\"pos\"],\n        add(this: FakeMouse) {\n            if (_k.game.fakeMouse) {\n                throw new Error(\"Fake mouse already exists\");\n            }\n\n            lastPos = this.pos.clone();\n\n            _k.game.fakeMouse = this;\n        },\n        destroy() {\n            _k.game.fakeMouse = null;\n        },\n        get isPressed() {\n            return isPressed;\n        },\n        update(this: FakeMouse) {\n            if (this.pos.x !== lastPos.x || this.pos.y !== lastPos.y) {\n                this.trigger(\"fakeMouseMove\", this.pos.clone()); // TODO: Create a deltaPos\n            }\n\n            if (opt.followMouse && _k.app.isMouseMoved()) {\n                this.screenPos = _k.app.mousePos();\n            }\n        },\n        press(this: FakeMouse) {\n            isPressed = true;\n            this.trigger(\"press\");\n        },\n        release(this: FakeMouse) {\n            isPressed = false;\n            this.trigger(\"release\");\n        },\n        onPress(this: FakeMouse, action) {\n            this.on(\"press\", action);\n        },\n        onRelease(this: FakeMouse, action) {\n            this.on(\"release\", action);\n        },\n    };\n};\n", "import type { KEventController } from \"../../../events/events\";\nimport { clamp } from \"../../../math/clamp\";\nimport type { Comp, GameObj } from \"../../../types\";\n\n/**\n * The serialized {@link health `health()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializeHealthComp {\n    hp: number;\n    maxHP: number;\n}\n\n/**\n * The {@link health `health()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface HealthComp extends Comp {\n    /**\n     * Current health points. Setting it to a lower or higher value will trigger onHurt() and onHeal().\n     * Setting it to a value greater than maxHP will set it to maxHP.\n     * Setting it to a value less than 0 will set it to 0 and trigger onDeath().\n     */\n    hp: number;\n    /**\n     * Max amount of HP.\n     */\n    maxHP: number;\n    /**\n     * Whether hp is 0.\n     */\n    readonly dead: boolean;\n    /**\n     * Register an event that runs when the hp is lowered.\n     *\n     * @since v2000.1\n     */\n    onHurt(action: (deltaHP?: number) => void): KEventController;\n    /**\n     * Register an event that runs when the hp is increased.\n     *\n     * @since v2000.1\n     */\n    onHeal(action: (deltaHP?: number) => void): KEventController;\n    /**\n     * Register an event that runs when object's HP becomes zero.\n     *\n     * @since v2000.1\n     */\n    onDeath(action: () => void): KEventController;\n    serialize(): SerializeHealthComp;\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        add() {\n            if (!this.maxHP) this.maxHP = this.hp;\n        },\n        get hp() {\n            return hp;\n        },\n        set hp(val: number) {\n            const origHP = this.hp;\n            hp = this.maxHP ? clamp(val, 0, this.maxHP) : val;\n            if (hp < origHP) {\n                (this as unknown as GameObj).trigger(\"hurt\", origHP - hp);\n            }\n            else if (hp > origHP) {\n                (this as unknown as GameObj).trigger(\"heal\", origHP - hp);\n            }\n            if (hp <= 0 && origHP > 0) {\n                (this as unknown as GameObj).trigger(\"death\");\n            }\n        },\n        get maxHP() {\n            return maxHP as number;\n        },\n        set maxHP(val: number) {\n            maxHP = val;\n        },\n        get dead() {\n            return this.hp <= 0;\n        },\n        onHurt(\n            this: GameObj,\n            action: (deltaHP?: number) => void,\n        ): KEventController {\n            return this.on(\"hurt\", action);\n        },\n        onHeal(\n            this: GameObj,\n            action: (deltaHP?: 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        serialize() {\n            return {\n                hp: this.hp,\n                maxHP: this.maxHP ?? this.hp,\n            };\n        },\n    };\n}\n", "import { easings } from \"../../../math/easings\";\nimport { _k } from \"../../../shared\";\nimport type { EmptyComp, GameObj } from \"../../../types\";\nimport type { OpacityComp } from \"../draw/opacity\";\n\n/**\n * The {@link lifespan `lifespan()`} component.\n *\n * @group Components\n * @subgroup 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 serialized {@link color `color()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializeNameComp {\n    name: string;\n}\n\n/**\n * The {@link named `named()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface NamedComp extends Comp {\n    /** The name assigned to this object. */\n    name: string;\n    serialize(): SerializeNameComp;\n}\n\nexport function named(name: string): NamedComp {\n    return {\n        id: \"named\",\n        name,\n        serialize() {\n            return {\n                name: name,\n            };\n        },\n    };\n}\n\nexport function nameFactory(data: any) {\n    return named(data.name);\n}\n", "import { KEvent, KEventController } from \"../../../events/events\";\nimport type { Comp } from \"../../../types\";\n\n/**\n * The serialized {@link state `state()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializeStateComp {\n    initState: string;\n    stateList: string[];\n    transitions: Record<string, string | string[]>;\n}\n\n/**\n * The {@link state `state()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface StateComp<T extends string> extends Comp {\n    /**\n     * Current state.\n     */\n    state: T;\n    /**\n     * Enter a state, trigger onStateEnd for previous state and onStateEnter for the new State state.\n     */\n    enterState: (state: T, ...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: T,\n        to: T,\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: T,\n        action: (...args: any) => void,\n    ) => KEventController;\n    /**\n     * Register an event that runs once when leaves a specific state.\n     */\n    onStateEnd: (state: T, action: () => void) => KEventController;\n    /**\n     * Register an event that runs every frame when in a specific state.\n     */\n    onStateUpdate: (state: T, action: () => void) => KEventController;\n    /**\n     * Register an event that runs every frame when in a specific state.\n     */\n    onStateDraw: (state: T, action: () => void) => KEventController;\n    serialize(): SerializeStateComp;\n}\n\nexport function state<T extends string>(\n    initState: T,\n    stateList?: T[],\n    transitions?: Record<T, T | T[]>,\n): StateComp<T> {\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, ...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        serialize() {\n            const data: any = {};\n            data.initState = initState;\n            if (stateList) data.stateList = stateList.slice();\n            if (transitions) data.transitions = Object.assign({}, transitions);\n            return data;\n        },\n    };\n}\n\nexport function stateFactory(data: SerializeStateComp) {\n    return state(data.initState, data.stateList, data.transitions);\n}\n", "import type { Comp } from \"../../../types\";\n\n/**\n * The serialized {@link stay `stay()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializeStayComp {\n    scenesToStay: string[];\n}\n\n/**\n * The {@link stay `stay()`} component.\n *\n * @group Components\n * @subgroup 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    serialize(): SerializeStayComp;\n}\n\nexport function stay(scenesToStay?: string[]): StayComp {\n    return {\n        id: \"stay\",\n        stay: true,\n        scenesToStay,\n        serialize() {\n            return {\n                scenesToStay: scenesToStay ?? [],\n            };\n        },\n    };\n}\n\nexport function stayFactory(data: SerializeStayComp) {\n    return stay(data.scenesToStay);\n}\n", "import type { KEventController } from \"../../../events/events\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport type { TextComp } from \"../draw/text\";\n\n/**\n * The {@link textInput `textInput()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface TextInputComp extends Comp {\n    /**\n     * Enable the text input array to be modified by user input.\n     *\n     * Setting this to true is the same as calling focus(), and will\n     * clear focus on all other active textInput objects.\n     */\n    hasFocus: boolean;\n    /**\n     * The \"real\" text that the user typed, without any escaping.\n     */\n    typedText: string;\n    /**\n     * Focuses this text input so that it will receive input, and\n     * removes focus from all other text inputs.\n     */\n    focus(): void;\n    /**\n     * Event that runs when the text input gains focus.\n     */\n    onFocus(cb: () => void): KEventController;\n    /**\n     * Event that runs when the text input loses focus.\n     */\n    onBlur(cb: () => void): KEventController;\n    /**\n     * Event that runs when the user types any character in the text input\n     * and causes its value to change.\n     *\n     * This runs *after* the display text is updated with the escaped version\n     * of the typed text, so in the event handler you can override the\n     * displayed text with another version (like if you want to add syntax\n     * highlighting or something). See also {@link TextComp.text}.\n     */\n    onInput(cb: () => void): KEventController;\n    /**\n     * Runs immediately after onBlur if the value has changed while the text\n     * input has been focused.\n     */\n    onChange(cb: () => void): KEventController;\n}\n\nexport function textInput(\n    hasFocus: boolean = true,\n    maxInputLength?: number,\n): TextInputComp {\n    let charEv: KEventController;\n    let backEv: KEventController;\n    let origText: string = \"\";\n    return {\n        id: \"textInput\",\n        get hasFocus() {\n            return hasFocus;\n        },\n        set hasFocus(newValue) {\n            if (hasFocus === newValue) return;\n            hasFocus = newValue;\n            (this as any as GameObj).trigger(hasFocus ? \"focus\" : \"blur\");\n            if (hasFocus) {\n                origText = this.typedText;\n                _k.game.allTextInputs.forEach(i => {\n                    // @ts-ignore\n                    if (i !== this) {\n                        i.hasFocus = false;\n                    }\n                });\n            }\n            else if (origText !== this.typedText) {\n                (this as any as GameObj).trigger(\"change\");\n            }\n        },\n        require: [\"text\"],\n        typedText: \"\",\n        add(this: GameObj<TextComp & TextInputComp>) {\n            _k.game.allTextInputs.add(this);\n            const flip = () => {\n                this.text = this.typedText.replace(/([\\[\\\\])/g, \"\\\\$1\");\n                this.trigger(\"input\");\n            };\n\n            charEv = _k.app.onCharInput((character) => {\n                if (\n                    this.hasFocus\n                    && (!maxInputLength\n                        || this.typedText.length < maxInputLength)\n                ) {\n                    if ((_k.app.isKeyDown(\"shift\") !== _k.app.state.capsOn)) {\n                        this.typedText += character.toUpperCase();\n                    }\n                    else {\n                        this.typedText += character;\n                    }\n                    flip();\n                }\n            });\n\n            backEv = _k.app.onKeyPressRepeat(\"backspace\", () => {\n                if (this.hasFocus) {\n                    this.typedText = this.typedText.slice(0, -1);\n                    flip();\n                }\n            });\n        },\n        destroy(this: GameObj<TextInputComp>) {\n            charEv.cancel();\n            backEv.cancel();\n            _k.game.allTextInputs.delete(this);\n        },\n        focus() {\n            this.hasFocus = true;\n        },\n        onFocus(this: GameObj, cb) {\n            return this.on(\"focus\", cb);\n        },\n        onBlur(this: GameObj, cb) {\n            return this.on(\"blur\", cb);\n        },\n        onInput(this: GameObj, cb) {\n            return this.on(\"input\", cb);\n        },\n        onChange(this: GameObj, cb) {\n            return this.on(\"change\", cb);\n        },\n    };\n}\n", "import { KEvent } from \"../../../events/events\";\nimport { easings } from \"../../../math/easings\";\nimport { lerp, type LerpValue } from \"../../../math/lerp\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\n\n/**\n * @group Timer\n */\nexport interface TimerController {\n    /**\n     * The time left for the callback to be called.\n     */\n    timeLeft: number;\n    /**\n     * If the event handler is paused.\n     */\n    paused: boolean;\n    /**\n     * Cancel the event handler.\n     */\n    cancel(): void;\n    /**\n     * Register an event when finished.\n     */\n    onEnd(action: () => void): void;\n    then(action: () => void): TimerController;\n}\n\n/**\n * Event controller for tween.\n *\n * @group Timer\n */\nexport interface TweenController extends TimerController {\n    /**\n     * The current time in the duration of the tween\n     */\n    currentTime: number;\n    /**\n     * Finish the tween now and cancel.\n     */\n    finish(): void;\n}\n\n/**\n * The {@link timer `timer()`} component.\n *\n * @group Components\n * @subgroup 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.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 timeLeft() {\n                    return t;\n                },\n                set timeLeft(val: number) {\n                    t = val;\n                },\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            if (typeof (from as any).clone == \"function\") {\n                from = (from as any).clone() as V;\n            }\n            if (typeof (to as any).clone == \"function\") {\n                to = (to as any).clone() as V;\n            }\n\n            const onEndEvents: Array<() => void> = [];\n            const ev = this.onUpdate(() => {\n                curTime += _k.app.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 currentTime() {\n                    return curTime;\n                },\n                set currentTime(val) {\n                    curTime = val;\n                },\n                get timeLeft() {\n                    return duration - curTime;\n                },\n                set timeLeft(val: number) {\n                    curTime = duration - val;\n                },\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", "// Gravity manipulation\n\nimport { vec2 } from \"../math/math\";\nimport { type Vec2 } from \"../math/Vec2\";\nimport { _k } from \"../shared\";\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 { DEF_JUMP_FORCE, MAX_VEL } from \"../../../constants/general\";\nimport type { KEventController } from \"../../../events/events\";\nimport { getGravityDirection } from \"../../../game/gravity\";\nimport { lerp } from \"../../../math/lerp\";\nimport { vec2 } from \"../../../math/math\";\nimport { calcTransform } from \"../../../math/various\";\nimport { type Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { exists } from \"../../entity/utils\";\nimport type { Collision } from \"../../systems/Collision\";\nimport type { PosComp } from \"../transform/pos\";\nimport type { AreaComp } from \"./area\";\n\n/**\n * The {@link body `body()`} component.\n *\n * @group Components\n * @subgroup 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 / (1 + damping * dt) every frame).\n     *\n     * @since v3001.0\n     */\n    damping: 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    serialize(): any;\n}\n\n/**\n * Options for the {@link body `body()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface BodyCompOpt {\n    /**\n     * How much velocity decays (velocity *= 1 / (1 + damping * dt) every frame).\n     *\n     * @since v3001.0\n     */\n    damping?: 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        damping: opt.damping ?? 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                            calcTransform(this, this.transform);\n                            calcTransform(other, other.transform);\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                            calcTransform(col2.source, col2.source.transform);\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                            // 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.trigger(\"headbutt\", col.target);\n                            col.target.trigger(\"headbutted\", this);\n                        }\n                    }\n\n                    const restitution = Math.max(\n                        col.source.restitution || 0,\n                        col.target.restitution || 0,\n                    );\n\n                    const friction = Math.sqrt(\n                        (col.source.friction || 0)\n                            * (col.target.friction || 0),\n                    );\n\n                    const projection = this.vel.project(col.normal);\n                    const rejection = this.vel.sub(projection);\n\n                    // Clear the velocity in the direction of the normal, as we've hit something\n                    if (this.vel.dot(col.normal) < 0) {\n                        // Modulate the velocity tangential to the normal\n                        this.vel = rejection.sub(projection.scale(restitution));\n                    }\n\n                    if (friction != 0) {\n                        // TODO: This should work with dt, not frame, but then friction 1 will brake in 1 second, not one frame\n                        // TODO: This should depend with gravity, stronger gravity means more friction\n                        //       getGravityDirection().scale(getGravity()).project(col.normal).len()\n                        this.vel = this.vel.sub(rejection.scale(friction));\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                    && exists(curPlatform)\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.clone();\n                }\n            }\n\n            const dt = _k.app.restDt();\n            if (dt && prevPhysicsPos) {\n                const lerpAmount = dt / _k.app.fixedDt();\n                // Check if no external changes were made\n                const p = this.pos.clone();\n                if (this.pos.x === prevDrawPos.x) {\n                    // Interpolate physics steps\n                    p.x = lerp(\n                        prevPhysicsPos!.x,\n                        nextPhysicsPos!.x,\n                        lerpAmount,\n                    );\n                    // Copy to check for changes\n                    prevDrawPos.x = p.x;\n                }\n                if (this.pos.y === prevDrawPos.y) {\n                    // Interpolate physics steps\n                    p.y = lerp(\n                        prevPhysicsPos!.y,\n                        nextPhysicsPos!.y,\n                        lerpAmount,\n                    );\n                    // Copy to check for changes\n                    prevDrawPos.y = p.y;\n                }\n                this.pos = p;\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                const p = this.pos.clone();\n                if (this.pos.x === prevDrawPos.x) {\n                    p.x = prevPhysicsPos.x;\n                }\n                if (this.pos.y === prevDrawPos.y) {\n                    p.y = prevPhysicsPos.y;\n                }\n                this.pos = p;\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                        || !exists(curPlatform)\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 * _k.app.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 * _k.app.dt();\n            this.vel.y += acc.y * _k.app.dt();\n\n            this.vel.x *= 1 / (1 + this.damping * _k.app.dt());\n            this.vel.y *= 1 / (1 + this.damping * _k.app.dt());\n\n            if (this.vel.x || this.vel.y) {\n                this.move(this.vel);\n            }\n\n            // If we need to interpolate physics, prepare interpolation data\n            const rDt = _k.app.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(_k.app.dt()));\n                nextPhysicsPos = this.pos.add(nextVel.scale(_k.app.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        serialize(): any {\n            const data: any = {};\n            if (opt.jumpForce) data.jumpForce = opt.jumpForce;\n            if (opt.maxVelocity) data.maxVelocity = opt.maxVelocity;\n            if (opt.gravityScale) data.gravityScale = opt.gravityScale;\n            if (opt.isStatic) data.isStatic = opt.isStatic;\n            if (opt.stickToPlatform) data.stickToPlatform = opt.stickToPlatform;\n            if (opt.mass) data.mass = opt.mass;\n            return data;\n        },\n    };\n}\n\nexport function bodyFactory(data: any) {\n    const opt: any = {};\n    if (data.jumpForce) opt.jumpForce = data.jumpForce;\n    if (data.maxVelocity) opt.maxVelocity = data.maxVelocity;\n    if (data.gravityScale) opt.gravityScale = data.gravityScale;\n    if (data.isStatic) opt.isStatic = opt.isStatic;\n    if (data.stickToPlatform) opt.stickToPlatform = data.stickToPlatform;\n    if (data.mass) opt.mass = data.mass;\n    return body(opt);\n}\n", "import type { KEventController } from \"../../../events/events\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport type { BodyComp } from \"./body\";\n\n/**\n * The {@link doubleJump `doubleJump()`} component.\n *\n * @group Components\n * @subgroup 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", "import { Polygon, vec2 } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport type { PosComp } from \"../transform/pos\";\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((obj, col) => {\n                if (!obj.has(\"body\")) return;\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    force: Vec2;\n    linearDrag?: number;\n};\n\nexport interface AreaEffectorComp extends Comp {\n    useGlobalAngle: boolean;\n    force: Vec2;\n    linearDrag: number;\n}\n\nexport function areaEffector(opts: AreaEffectorCompOpt): AreaEffectorComp {\n    return {\n        id: \"areaEffector\",\n        require: [\"area\"],\n        force: opts.force,\n        linearDrag: opts.linearDrag ?? 0,\n        useGlobalAngle: opts.useGlobalAngle ?? true,\n        add(this: GameObj<AreaComp | AreaEffectorComp>) {\n            this.onCollideUpdate(obj => {\n                if (!obj.has(\"body\")) return;\n                obj.addForce(\n                    this.useGlobalAngle\n                        ? this.force\n                        : this.force.rotate(this.transform.getRotation()),\n                );\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    distanceScale?: number;\n    forceMode?: ForceMode;\n    linearDrag?: number;\n};\n\nexport interface PointEffectorComp extends Comp {\n    forceMagnitude: number;\n    distanceScale: number;\n    forceMode: ForceMode;\n    linearDrag: number;\n}\n\nexport function pointEffector(opts: PointEffectorCompOpt): PointEffectorComp {\n    return {\n        id: \"pointEffector\",\n        require: [\"area\", \"pos\"],\n        forceMagnitude: opts.forceMagnitude,\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((obj, col) => {\n                if (!obj.has(\"body\")) return;\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    useGlobalAngle?: boolean;\n};\n\nexport interface ConstantForceComp extends Comp {\n    force: Vec2 | undefined;\n    useGlobalAngle: boolean;\n}\n\nexport function constantForce(opts: ConstantForceCompOpt): ConstantForceComp {\n    return {\n        id: \"constantForce\",\n        require: [\"body\"],\n        force: opts.force,\n        useGlobalAngle: opts.useGlobalAngle ?? true,\n        update(this: GameObj<BodyComp | ConstantForceComp>) {\n            if (this.force) {\n                this.addForce(\n                    this.useGlobalAngle\n                        ? this.force\n                        : this.force.rotate(this.transform.getRotation()),\n                );\n            }\n        },\n    };\n}\n\nexport type PlatformEffectorCompOpt = {\n    /**\n     * If the object is about to collide and the collision normal direction is\n     * in here (i.e. the object is moving roughly in this direction), the object won't collide.\n     *\n     * Should be a list of unit vectors `LEFT`, `RIGHT`, `UP`, or `DOWN`.\n     *\n     * Defaults to `[UP]`, i.e. the object will only be able to pass through when it\n     * is jumping upwards, but will collide when it is moving downwards or sideways.\n     */\n    ignoreSides?: Vec2[];\n    /**\n     * A function that determines whether the object should collide.\n     *\n     * If present, it overrides the `ignoreSides`; if absent, it is\n     * automatically created from `ignoreSides`.\n     */\n    shouldCollide?: (\n        this: GameObj<PlatformEffectorComp>,\n        obj: GameObj,\n        normal: Vec2,\n    ) => boolean;\n};\n\nexport interface PlatformEffectorComp extends Comp {\n    /**\n     * A set of the objects that should not collide with this, because `shouldCollide` returned true.\n     *\n     * Objects in here are automatically removed when they stop colliding, so the casual user shouldn't\n     * need to touch this much. However, if an object is added to this set before the object collides\n     * with the platform effector, it won't collide even if `shouldCollide` returns true.\n     */\n    platformIgnore: Set<GameObj>;\n}\n\nexport function platformEffector(\n    opt: PlatformEffectorCompOpt = {},\n): PlatformEffectorComp {\n    opt.ignoreSides ??= [Vec2.UP];\n    opt.shouldCollide ??= (_, normal) => {\n        return opt.ignoreSides?.findIndex(s => s.sdist(normal) < Number.EPSILON)\n            == -1;\n    };\n    return {\n        id: \"platformEffector\",\n        require: [\"area\", \"body\"],\n        platformIgnore: new Set<GameObj>(),\n        add(this: GameObj<BodyComp | AreaComp | PlatformEffectorComp>) {\n            this.onBeforePhysicsResolve(collision => {\n                if (this.platformIgnore.has(collision.target)) {\n                    collision.preventResolution();\n                }\n                else if (\n                    !opt.shouldCollide!.call(\n                        this,\n                        collision.target,\n                        collision.normal,\n                    )\n                ) {\n                    collision.preventResolution();\n                    this.platformIgnore.add(collision.target);\n                }\n            });\n            this.onCollideEnd(obj => {\n                this.platformIgnore.delete(obj);\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((obj, col) => {\n                if (!obj.has(\"body\")) return;\n                const o = obj as GameObj<BodyComp | AreaComp>;\n                const shape = o.worldArea();\n                const polygon: Polygon = shape instanceof Polygon\n                    ? shape\n                    : new Polygon(shape.bbox().points());\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 { anchorPt } from \"../../../gfx/anchor\";\nimport { vec2 } from \"../../../math/math\";\nimport { type SerializedVec2, Vec2 } from \"../../../math/Vec2\";\nimport type { Anchor, Comp } from \"../../../types\";\n\n/**\n * The serialized {@link anchor `anchor()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedAnchorComp {\n    anchor: SerializedVec2;\n}\n\n/**\n * The {@link anchor `anchor()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface AnchorComp extends Comp {\n    /**\n     * Anchor point for render.\n     */\n    anchor: Anchor | Vec2;\n\n    serialize(): SerializedAnchorComp;\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        serialize() {\n            return {\n                anchor: this.anchor instanceof Vec2\n                    ? this.anchor.serialize()\n                    : anchorPt(this.anchor).serialize(),\n            };\n        },\n    };\n}\n\nexport function anchorFactory(data: SerializedAnchorComp) {\n    return anchor(new Vec2(data.anchor.x, data.anchor.y));\n}\n", "import { drawCircle } from \"../../../gfx/draw/drawCircle\";\nimport { drawLine } from \"../../../gfx/draw/drawLine\";\nimport { drawPolygon } from \"../../../gfx/draw/drawPolygon\";\nimport {\n    loadMatrix,\n    multRotate,\n    popTransform,\n    pushMatrix,\n    pushTransform,\n} from \"../../../gfx/stack\";\nimport { clamp } from \"../../../math/clamp\";\nimport { Color } from \"../../../math/color\";\nimport { lerp } from \"../../../math/lerp\";\nimport { deg2rad, Mat23, rad2deg, vec2 } from \"../../../math/math\";\nimport {\n    calcTransform,\n    clampAngle,\n    updateChildrenTransformRecursive,\n    updateTransformRecursive,\n} from \"../../../math/various\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { system, SystemPhase } from \"../../systems/systems\";\nimport type { PosComp } from \"./pos\";\nimport type { RotateComp } from \"./rotate\";\nimport type { ScaleComp } from \"./scale\";\n\nexport type BoneOpt = {\n    /* Minimum angle should be between -180 and 180, and smaller than maximum angle */\n    minAngle?: number;\n    /* Maximum angle should be between -180 and 180, and greater than minimum angle */\n    maxAngle?: number;\n};\n\nexport interface BoneComp extends Comp {\n    /* Minimum angle should be between -180 and 180, and smaller than maximum angle */\n    minAngle: number;\n    /* Maximum angle should be between -180 and 180, and greater than minimum angle */\n    maxAngle: number;\n    setAngles(minAngle: number, maxAngle: number): void;\n}\n\nexport interface Constraint extends Comp {\n    constraint: {\n        target: GameObj;\n    };\n    apply: () => void;\n}\n\nexport type DistanceMode = \"maximum\" | \"minimum\" | \"equal\";\n\nexport type DistanceConstraintOpt = {\n    /**\n     * The desired distance between this and target\n     */\n    distance: number;\n    /**\n     * If maximum, the distance is maximum distance\n     * If equal, the distance is the desired distance\n     * If minimum, the distance is minimum distance\n     */\n    mode: DistanceMode;\n    /**\n     * Between 0 and 1. The percentage of the property being overwritten\n     */\n    strength?: number;\n};\n\nexport interface DistanceConstraintComp extends Constraint {\n    constraint: {\n        target: GameObj;\n        distance: number;\n        mode: DistanceMode;\n        strength: number;\n    };\n}\n\nexport type TranslationConstraintOpt = {\n    /**\n     * The offset added after applying the constraint\n     */\n    offset?: Vec2;\n    /**\n     * Between 0 and 1. The percentage of the property being overwritten\n     */\n    strength?: number;\n};\n\nexport interface TranslationConstraintComp extends Constraint {\n    constraint: {\n        target: GameObj;\n        offset: Vec2;\n        strength: number;\n    };\n}\n\nexport type RotationConstraintOpt = {\n    /**\n     * The offset added after applying the constraint\n     */\n    offset?: number;\n    /**\n     * The factor applied before applying the constraint. For example 0.5 will only apply half of the rotation of the target\n     */\n    scale?: number;\n    /**\n     * Between 0 and 1. The percentage of the property being overwritten\n     */\n    strength?: number;\n};\n\nexport interface RotationConstraintComp extends Constraint {\n    constraint: {\n        target: GameObj;\n        offset: number;\n        scale: number;\n        strength: number;\n    };\n}\n\nexport type ScaleConstraintOpt = {\n    /**\n     * Between 0 and 1. The percentage of the property being overwritten\n     */\n    strength?: number;\n};\n\nexport interface ScaleConstraintComp extends Constraint {\n    constraint: {\n        target: GameObj;\n        strength: number;\n    };\n}\n\nexport type TransformConstraintOpt = {\n    /**\n     * Between 0 and 1. The percentage of the property being overwritten\n     */\n    strength?: number;\n};\n\nexport interface TransformConstraintComp extends Constraint {\n    constraint: {\n        target: GameObj;\n        strength: number;\n    };\n}\n\n/**\n * \"FABRIK\": Use Forward And Backward Reaching Inverse Kinematics\n * \"CCD\" : Use Cyclic Coordinate Descent\n */\ntype InverseKinematicsAlgorithm = \"FABRIK\" | \"CCD\";\n\nexport type IKConstraintOpt = {\n    /**\n     * The algorithm to use. Default is FABRIK.\n     */\n    algorithm?: InverseKinematicsAlgorithm;\n    /**\n     * Amount of bones. Default is 1.\n     */\n    depth: number;\n    /**\n     * Amount of ik iterations. Default is 10.\n     */\n    iterations?: number;\n    /**\n     * Between 0 and 1. The percentage of the property being overwritten. Default is 1.\n     */\n    strength?: number;\n};\n\nexport interface IKConstraintComp extends Constraint {\n    constraint: {\n        target: GameObj;\n        iterations: number;\n        strength: number;\n    };\n}\n\nlet systemInstalled = false;\n\nfunction installSystem() {\n    if (systemInstalled) return;\n    systemInstalled = true;\n    // TODO: use a live query for this\n    const constraints: Set<GameObj<Constraint>> = new Set();\n    _k.appScope.onAdd(obj => {\n        if (obj.has(\"constraint\")) {\n            constraints.add(obj as GameObj<Constraint>);\n        }\n    });\n    _k.appScope.onDestroy(obj => {\n        constraints.delete(obj as GameObj<Constraint>);\n    });\n    _k.appScope.onUse((obj, id) => {\n        if (\"constraint\" === id) {\n            constraints.add(obj as GameObj<Constraint>);\n        }\n    });\n    _k.appScope.onUnuse((obj, id) => {\n        if (\"constraint\" === id) {\n            constraints.delete(obj as GameObj<Constraint>);\n        }\n    });\n\n    system(\"constraint\", () => {\n        constraints.forEach(constraint => {\n            constraint.apply();\n        });\n    }, [\n        SystemPhase.BeforeDraw, // Because we need the transform to be up to date\n    ]);\n}\n\nexport const constraint = {\n    /**\n     * A distance constraint\n     * @param target - The object to keep within distance off\n     * @param opt - Options\n     *\n     * @returns DistanceConstraintComp\n     */\n    distance(\n        target: GameObj,\n        opt: DistanceConstraintOpt,\n    ): DistanceConstraintComp {\n        installSystem();\n        return {\n            id: \"constraint\",\n            constraint: {\n                target: target,\n                distance: opt.distance,\n                mode: opt.mode || \"equal\",\n                strength: opt.strength ?? 1,\n            },\n            apply(this: GameObj<PosComp | DistanceConstraintComp>) {\n                const d = vec2(\n                    // We use world distance\n                    this.transform.e - this.constraint.target.transform.e,\n                    this.transform.f - this.constraint.target.transform.f,\n                );\n                const dd = this.constraint.distance * this.constraint.distance;\n                if (\n                    (this.constraint.mode === \"maximum\" && d.slen() > dd)\n                    || (this.constraint.mode === \"minimum\" && d.slen() < dd)\n                    || (this.constraint.mode === \"equal\" && d.slen() != dd)\n                ) {\n                    const l = d.len();\n                    // Modify world position\n                    this.transform.e = lerp(\n                        this.transform.e,\n                        this.constraint.target.transform.e\n                            + d.x / l * this.constraint.distance,\n                        this.constraint.strength,\n                    );\n                    this.transform.f = lerp(\n                        this.transform.f,\n                        this.constraint.target.transform.f\n                            + d.y / l * this.constraint.distance,\n                        this.constraint.strength,\n                    );\n                    // Modify local position\n                    if (this.parent) {\n                        const transform = this.parent?.transform.inverse.mul(\n                            this.transform,\n                        );\n                        const p = this.pos;\n                        p.x = transform.e;\n                        p.y = transform.f;\n                        this.pos = p;\n                    }\n                    else {\n                        const p = this.pos;\n                        p.x = this.transform.e;\n                        p.y = this.transform.f;\n                        this.pos = p;\n                    }\n                }\n            },\n        };\n    },\n    /**\n     * A translation constraint\n     * @param target - The object to copy the translation from\n     * @param opt - Options\n     *\n     * @returns TranslationConstraintComp\n     */\n    translation(\n        target: GameObj,\n        opt: TranslationConstraintOpt,\n    ): TranslationConstraintComp {\n        installSystem();\n        return {\n            id: \"constraint\",\n            constraint: {\n                target: target,\n                strength: opt.strength ?? 1,\n                offset: opt.offset || new Vec2(),\n            },\n            apply(this: GameObj<PosComp | TranslationConstraintComp>) {\n                // We use world translation\n                this.transform.e = lerp(\n                    this.transform.e,\n                    this.constraint.target.transform.e\n                        + this.constraint.offset.x,\n                    this.constraint.strength,\n                );\n                this.transform.f = lerp(\n                    this.transform.f,\n                    this.constraint.target.transform.f\n                        + this.constraint.offset.x,\n                    this.constraint.strength,\n                );\n                // Modify local position\n                if (this.parent) {\n                    const transform = this.parent?.transform.inverse.mul(\n                        this.transform,\n                    );\n                    const p = this.pos;\n                    p.x = transform.e;\n                    p.y = transform.f;\n                    this.pos = p;\n                }\n                else {\n                    const p = this.pos;\n                    p.x = this.transform.e;\n                    p.y = this.transform.f;\n                    this.pos = p;\n                }\n            },\n        };\n    },\n    /**\n     * A rotation constraint\n     * @param target - The object to copy the rotation from\n     * @param opt - Options\n     *\n     * @returns RotationConstraintComp\n     */\n    rotation(\n        target: GameObj,\n        opt: RotationConstraintOpt,\n    ): RotationConstraintComp {\n        installSystem();\n        return {\n            id: \"constraint\",\n            constraint: {\n                target: target,\n                scale: opt.scale ?? 1,\n                strength: opt.strength ?? 1,\n                offset: opt.offset || 0,\n            },\n            apply(this: GameObj<RotateComp | RotationConstraintComp>) {\n                // We use world rotation\n                const srcAngle = this.transform.getRotation();\n                const dstAngle = this.constraint.target.transform.getRotation();\n                const newAngle = lerp(\n                    srcAngle,\n                    dstAngle * this.constraint.scale + this.constraint.offset,\n                    this.constraint.strength,\n                );\n                const scale = this.transform.getScale();\n                // Update world angle\n                const newTransform = new Mat23();\n                newTransform.setTRS(\n                    this.transform.e,\n                    this.transform.f,\n                    newAngle,\n                    scale.x,\n                    scale.y,\n                );\n                // Modify local angle\n                if (this.parent) {\n                    const transform = this.parent?.transform.inverse.mul(\n                        newTransform,\n                    );\n                    this.angle = transform.getRotation();\n                }\n                else {\n                    this.angle = newAngle;\n                }\n                updateTransformRecursive(this);\n            },\n        };\n    },\n    /**\n     * A scale constraint\n     * @param target - The object to copy the scale from\n     * @param opt - Options\n     *\n     * @returns ScaleConstraintComp\n     */\n    scale(\n        target: GameObj,\n        opt: ScaleConstraintOpt,\n    ): ScaleConstraintComp {\n        installSystem();\n        return {\n            id: \"constraint\",\n            constraint: {\n                target: target,\n                strength: opt.strength ?? 1,\n            },\n            apply(this: GameObj<ScaleConstraintComp | ScaleComp>) {\n                // We use world scale\n                const srcScale = this.transform.getScale();\n                const dstScale = this.constraint.target.transform.getScale();\n                const newScale = lerp(\n                    srcScale,\n                    dstScale,\n                    this.constraint.strength,\n                );\n                const angle = this.transform.getRotation();\n                // Update world scale\n                this.transform.setTRS(\n                    this.transform.e,\n                    this.transform.f,\n                    angle,\n                    newScale.x,\n                    newScale.y,\n                );\n                // Modify local scale\n                if (this.parent) {\n                    const transform = this.parent?.transform.inverse.mul(\n                        this.transform,\n                    );\n                    this.scale = transform.getScale();\n                }\n                else {\n                    this.scale = newScale;\n                }\n            },\n        };\n    },\n    /**\n     * A transform constraint\n     * @param target - The object to copy the transform from\n     * @param opt - Options\n     *\n     * @returns TransformConstraintComp\n     */\n    transform(\n        target: GameObj,\n        opt: TransformConstraintOpt,\n    ): TransformConstraintComp {\n        installSystem();\n        return {\n            id: \"constraint\",\n            constraint: {\n                target: target,\n                strength: opt.strength ?? 1,\n            },\n            apply(\n                this: GameObj<\n                    PosComp | RotateComp | ScaleComp | TransformConstraintComp\n                >,\n            ) {\n                // We use world properties\n                const newX = lerp(\n                    this.transform.e,\n                    this.constraint.target.transform.e,\n                    this.constraint.strength,\n                );\n                const newY = lerp(\n                    this.transform.f,\n                    this.constraint.target.transform.f,\n                    this.constraint.strength,\n                );\n                const srcAngle = this.transform.getRotation();\n                const dstAngle = this.constraint.target.transform.getRotation();\n                const newAngle = lerp(\n                    srcAngle,\n                    dstAngle,\n                    this.constraint.strength,\n                );\n                const srcScale = this.transform.getScale();\n                const dstScale = this.constraint.target.transform.getScale();\n                const newScale = lerp(\n                    srcScale,\n                    dstScale,\n                    this.constraint.strength,\n                );\n                // Update world properties\n                this.transform.setTRS(\n                    newX,\n                    newY,\n                    newAngle,\n                    newScale.x,\n                    newScale.y,\n                );\n                // Modify local properties\n                if (this.parent) {\n                    const transform = this.parent?.transform.inverse.mul(\n                        this.transform,\n                    );\n                    this.pos = vec2(transform.e, transform.f);\n                    this.angle = transform.getRotation();\n                    this.scale = transform.getScale();\n                }\n                else {\n                    this.pos = vec2(newX, newY);\n                    this.angle = newAngle;\n                    this.scale = newScale;\n                }\n            },\n        };\n    },\n    bone(\n        minAngle?: number,\n        maxAngle?: number,\n        minLength?: number,\n        maxLength?: number,\n    ) {\n        let _minAngle = Math.max(\n            -180,\n            Math.min(minAngle ?? -180, maxAngle ?? 180),\n        );\n        let _maxAngle = Math.min(\n            180,\n            Math.max(minAngle ?? -180, maxAngle ?? 180),\n        );\n        let _minLength = minLength;\n        let _maxLength = maxLength;\n        return {\n            id: \"bone\",\n            get minAngle() {\n                return _minAngle;\n            },\n            get maxAngle() {\n                return _maxAngle;\n            },\n            setAngles(minAngle?: number, maxAngle?: number) {\n                _minAngle = Math.max(\n                    -180,\n                    Math.min(minAngle ?? -180, maxAngle ?? 180),\n                );\n                _maxAngle = Math.min(\n                    180,\n                    Math.max(minAngle ?? -180, maxAngle ?? 180),\n                );\n            },\n            get minLength() {\n                return _minLength;\n            },\n            get maxLength() {\n                return _maxLength;\n            },\n            drawInspect(this: GameObj<IKConstraintComp | RotateComp>) {\n                pushTransform();\n                multRotate(-this.angle + _minAngle);\n                drawCircle({\n                    radius: 20,\n                    start: _maxAngle - _minAngle,\n                    color: Color.RED,\n                });\n                popTransform();\n            },\n        };\n    },\n    ik(target: GameObj, opt: IKConstraintOpt): IKConstraintComp {\n        installSystem();\n        const algorithm = opt.algorithm || \"FABRIK\";\n        const depth = opt.depth ?? 1;\n        const iterations = opt.iterations ?? 10;\n        const chain: GameObj[] = [];\n        const length: number[] = [];\n        if (algorithm === \"CCD\") {\n            return {\n                id: \"constraint\",\n                constraint: {\n                    target: target,\n                    iterations: iterations,\n                    strength: opt.strength || 1,\n                },\n                apply(this: GameObj<PosComp | IKConstraintComp>) {\n                    // Get IK chain from end effector to root\n                    const endEffector = chain[0] = this;\n                    for (let i = 1; i <= depth; i++) {\n                        chain[i] = chain[i - 1].parent!;\n                    }\n                    let dx, dy;\n                    for (let it = 0; it < iterations; it++) {\n                        // Rotate every effector in the chain to point towards the target\n                        for (let i = depth; i > 0; i--) {\n                            const effector = chain[i];\n                            const effectorTransform = effector.transform;\n                            if (i !== depth) {\n                                // We updated the transform of the parent, so update this transform\n                                calcTransform(effector, effectorTransform);\n                            }\n\n                            // Angle of effector to target\n                            dx = target.transform.e\n                                - effectorTransform.e;\n                            dy = target.transform.f\n                                - effectorTransform.f;\n                            const angleToTarget = rad2deg(Math.atan2(dy, dx));\n\n                            // Angle of effector to end effector\n                            dx = endEffector.transform.e\n                                - effectorTransform.e;\n                            dy = endEffector.transform.f\n                                - effectorTransform.f;\n                            const angleToEndEffector = rad2deg(\n                                Math.atan2(dy, dx),\n                            );\n\n                            // Rotation to move end effector towards target\n                            const angleCorrection = angleToTarget\n                                - angleToEndEffector;\n\n                            // Update global transform\n                            const rotation = effectorTransform.getRotation();\n                            const scale = effectorTransform.getScale();\n                            effectorTransform.setTRS(\n                                effectorTransform.e,\n                                effectorTransform.f,\n                                rotation + angleCorrection,\n                                scale.x,\n                                scale.y,\n                            );\n                            if (effector.parent) {\n                                // Calculate local rotation\n                                const transform = effector.parent.transform\n                                    .inverse.mul(\n                                        effectorTransform,\n                                    );\n                                let newAngle = clampAngle(\n                                    transform.getRotation(),\n                                );\n                                // If constraint on angle, apply\n                                if (\n                                    effector.minAngle != undefined\n                                    && effector.maxAngle != undefined\n                                ) {\n                                    newAngle = Math.min(\n                                        Math.max(newAngle, effector.minAngle),\n                                        effector.maxAngle,\n                                    );\n                                }\n                                effector.angle = newAngle;\n                            }\n                            else {\n                                // Local rotation is global rotation\n                                let newAngle = clampAngle(\n                                    rotation + angleCorrection,\n                                );\n                                // If constraint on angle, apply\n                                if (\n                                    effector.minAngle != undefined\n                                    && effector.maxAngle != undefined\n                                ) {\n                                    newAngle = Math.min(\n                                        Math.max(newAngle, effector.minAngle),\n                                        effector.maxAngle,\n                                    );\n                                }\n                                effector.angle = newAngle;\n                            }\n\n                            if (\n                                effector.parent\n                                && effector.parent.minLength != undefined\n                                && effector.parent.maxLength != undefined\n                            ) {\n                                // Vector from parent to target\n                                const ax = target.transform.e\n                                    - effector.parent.transform.e;\n                                const ay = target.transform.f\n                                    - effector.parent.transform.f;\n                                // Vector from parent to bone\n                                const bx = effectorTransform.e\n                                    - effector.parent.transform.e;\n                                const by = effectorTransform.f\n                                    - effector.parent.transform.f;\n                                // Projection of target onto bone\n                                const s = (ax * bx + ay * by)\n                                    / (bx * bx + by * by);\n                                const px = s * bx;\n                                const py = s * by;\n                                // Desired length\n                                let len = Math.sqrt(px * px + py * py);\n                                // New length = desired length clamped\n                                const nlen = clamp(\n                                    len,\n                                    effector.parent.minLength,\n                                    effector.parent.maxLength,\n                                );\n                                // Old length\n                                const olen = Math.sqrt(\n                                    effector.pos.x * effector.pos.x\n                                        + effector.pos.y * effector.pos.y,\n                                );\n                                // Scale to desired length clamped\n                                effector.pos.x *= nlen / olen;\n                                effector.pos.y *= nlen / olen;\n                            }\n\n                            if (\n                                (effector.minAngle != undefined\n                                    && effector.maxAngle != undefined)\n                                || (effector.minLength != undefined\n                                    && effector.maxLength != undefined)\n                            ) {\n                                // We changed the local angle, so the current effector's transform needs to be updated\n                                updateTransformRecursive(effector);\n                            }\n                            else {\n                                updateChildrenTransformRecursive(effector);\n                            }\n                        }\n                    }\n                },\n                drawInspect(this: GameObj<IKConstraintComp>) {\n                    const endEffector = chain[0] = this;\n                    for (let i = 1; i <= depth; i++) {\n                        chain[i] = chain[i - 1].parent!;\n                    }\n                    let p1 = chain[depth].pos;\n                    pushTransform();\n                    for (let i = depth; i > 0; i--) {\n                        const bone = chain[i];\n                        const childBone = chain[i - 1];\n                        const len = childBone.pos.len();\n                        loadMatrix(bone.transform);\n                        drawPolygon({\n                            pts: [\n                                vec2(0, 0),\n                                vec2(len / 10, -len / 10),\n                                childBone.pos,\n                                vec2(len / 10, len / 10),\n                            ],\n                        });\n                    }\n                    popTransform();\n                },\n            };\n        }\n        else {\n            return {\n                id: \"constraint\",\n                constraint: {\n                    target: target,\n                    iterations: iterations,\n                    strength: opt.strength || 1,\n                },\n                apply(this: GameObj<PosComp | IKConstraintComp>) {\n                    // Get IK chain from end effector to root\n                    const endEffector = chain[0] = this;\n                    // The end effector does not have a length\n                    length[0] = 0;\n                    let dx, dy;\n                    for (let i = 1; i <= depth; i++) {\n                        chain[i] = chain[i - 1].parent!;\n                        dx = chain[i].transform.e\n                            - chain[i - 1].transform.e;\n                        dy = chain[i].transform.f\n                            - chain[i - 1].transform.f;\n                        // Calculate the length of the other effectors\n                        length[i] = Math.sqrt(dx * dx + dy * dy);\n                    }\n                    const root = chain[depth];\n                    const rootPosX = root.transform.e;\n                    const rootPosY = root.transform.f;\n                    // Perform FABRIK\n                    for (let it = 0; it < iterations; it++) {\n                        let l;\n                        // Forward step, pull end effector towards target\n                        endEffector.transform.e = target.transform.e;\n                        endEffector.transform.f = target.transform.f;\n                        // Pull effectors in sequence to restore length\n                        for (let i = 1; i <= depth; i++) {\n                            // Vector towards previous effector\n                            dx = chain[i].transform.e\n                                - chain[i - 1].transform.e;\n                            dy = chain[i].transform.f\n                                - chain[i - 1].transform.f;\n                            l = Math.sqrt(dx * dx + dy * dy);\n                            chain[i].transform.e = chain[i - 1].transform.e\n                                + dx * length[i] / l;\n                            chain[i].transform.f = chain[i - 1].transform.f\n                                + dy * length[i] / l;\n                        }\n                        // Backward step, pull root back to its original position\n                        root.transform.e = rootPosX;\n                        root.transform.f = rootPosY;\n                        // Pull effectors in reverse sequence to restore length\n                        for (let i = depth - 1; i >= 0; i--) {\n                            // Vector towards previous effector\n                            dx = chain[i].transform.e\n                                - chain[i + 1].transform.e;\n                            dy = chain[i].transform.f\n                                - chain[i + 1].transform.f;\n                            l = Math.sqrt(dx * dx + dy * dy);\n                            chain[i].transform.e = chain[i + 1].transform.e\n                                + dx * length[i + 1] / l;\n                            chain[i].transform.f = chain[i + 1].transform.f\n                                + dy * length[i + 1] / l;\n                        }\n                    }\n                    // Modify local position or angle depending on the presence of a rotate\n                    for (let i = depth; i >= 0; i--) {\n                        const obj = chain[i];\n                        // If i < depth, obviously the object has a rent\n                        if (i < depth || obj.parent) {\n                            const parent = obj.parent!;\n                            if (parent.has(\"rotate\")) {\n                                // If the parent has an angle, use the parent's angle and local length\n                                const parentTransform = parent.transform;\n                                // Calculate the difference in angle\n                                const angle = rad2deg(\n                                    Math.atan2(\n                                        obj.transform.f - parentTransform.f,\n                                        obj.transform.e - parentTransform.e,\n                                    ),\n                                );\n                                // Keep the translation and scale\n                                const scale = parentTransform.getScale();\n                                parentTransform.setTRS(\n                                    parentTransform.e,\n                                    parentTransform.f,\n                                    angle, // orient the parent towards the object\n                                    scale.x,\n                                    scale.y,\n                                );\n                                if (parent.parent) {\n                                    const transform = parent.parent.transform\n                                        .inverse.mul(\n                                            parent.transform,\n                                        );\n                                    parent.angle = transform.getRotation();\n                                }\n                                else {\n                                    parent.angle = angle;\n                                }\n\n                                // Update the local properties\n                                const transform = parentTransform.inverse.mul(\n                                    obj.transform,\n                                );\n                                obj.pos = vec2(transform.e, transform.f);\n                            }\n                            else {\n                                // If there is no angle, just use position\n                                const transform = obj.parent!.transform.inverse\n                                    .mul(\n                                        obj.transform,\n                                    );\n                                obj.pos = vec2(transform.e, transform.f);\n                            }\n                        }\n                        else {\n                            obj.pos = vec2(obj.transform.e, obj.transform.f);\n                        }\n                    }\n                },\n                drawInspect(this: GameObj<IKConstraintComp>) {\n                    const endEffector = chain[0] = this;\n                    for (let i = 1; i <= depth; i++) {\n                        chain[i] = chain[i - 1].parent!;\n                    }\n                    let p1 = chain[depth].pos;\n                    pushTransform();\n                    for (let i = depth; i > 0; i--) {\n                        const bone = chain[i];\n                        const childBone = chain[i - 1];\n                        loadMatrix(bone.transform);\n                        drawPolygon({\n                            pts: [\n                                vec2(0, 0),\n                                vec2(10, -10),\n                                childBone.pos,\n                                vec2(10, 10),\n                            ],\n                        });\n                    }\n                    popTransform();\n                },\n            };\n        }\n    },\n};\n", "import { vec2 } from \"../../../math/math\";\nimport { Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, GameObj } from \"../../../types\";\nimport { exists } from \"../../entity/utils\";\nimport type { PosComp } from \"./pos\";\n\n/**\n * The {@link follow `follow()`} component.\n *\n * @group Components\n * @subgroup 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 (exists(obj)) {\n                this.pos = this.follow.obj.pos.add(this.follow.offset);\n            }\n        },\n        update(this: GameObj<FollowComp | PosComp>) {\n            if (exists(obj)) {\n                this.pos = this.follow.obj.pos.add(this.follow.offset);\n            }\n        },\n    };\n}\n", "import { _k } from \"../../../shared\";\nimport type { Comp } from \"../../../types\";\n\n/**\n * The {@link layer `layer()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface LayerComp extends Comp {\n    /**\n     * Get the index of the current layer the object is assigned to.\n     *\n     * Will always be `null` if the game doesn't use layers.\n     */\n    get layerIndex(): number | null;\n    /**\n     * Get the name of the current layer the object is assigned to.\n     *\n     * Will always be `null` if the game doesn't use layers.\n     */\n    get layer(): string | null;\n    /**\n     * Set the name of the layer the object should be assigned to.\n     *\n     * Throws an error if the game uses layers and the requested layer\n     * wasn't defined.\n     */\n    set layer(name: string);\n\n    serialize(): { layer: string | null };\n}\n\nexport function layer(layer: string): LayerComp {\n    let _layerIndex = _k.game.layers?.indexOf(layer);\n    if (_layerIndex == -1) {\n        throw new Error(`Layer \"${layer}\" does not exist`);\n    }\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) {\n                throw new Error(`Layer \"${value}\" does not exist`);\n            }\n        },\n        inspect() {\n            return `layer: ${this.layer}`;\n        },\n        serialize() {\n            return { layer: this.layer };\n        },\n    };\n}\n\nexport function layerFactory(data: any) {\n    return layer(data.layer);\n}\n", "import { type SerializedVec2, Vec2 } from \"../../../math/Vec2\";\nimport type { Comp, EmptyComp, GameObj } from \"../../../types\";\nimport type { PosComp } from \"./pos\";\n\n/**\n * The serialized {@link move `move()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\ninterface SerializedMoveComp {\n    dir: SerializedVec2 | number;\n    speed: number;\n}\n\n/**\n * The {@link move `move()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface MoveComp extends Comp {\n    serialize: () => SerializedMoveComp;\n}\n\nexport function move(\n    dir: number | Vec2,\n    speed: number,\n): MoveComp {\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        serialize() {\n            return {\n                dir: dir instanceof Vec2 ? dir.serialize() : dir,\n                speed: speed,\n            };\n        },\n    };\n}\n\nexport function moveFactory(data: SerializedMoveComp) {\n    if (typeof data.dir == \"object\") {\n        return move(new Vec2(data.dir.x, data.dir.y), data.speed);\n    }\n    else {\n        return move(data.dir, data.speed);\n    }\n}\n", "import { DEF_OFFSCREEN_DIS } from \"../../../constants/general\";\nimport type { KEventController } from \"../../../events/events\";\nimport { height, width } from \"../../../gfx/stack\";\nimport { Rect, testRectPoint, vec2 } from \"../../../math/math\";\nimport { _k } from \"../../../shared\";\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 Components\n * @subgroup 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 Components\n * @subgroup 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\n// TODO: Probably a bug with offscreen about the component not persisting its functionality on scene change even when object uses stay (Be sure of creating an issue/card before merging)\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) {\n                _k.sceneScope.onUpdate(() => check(this));\n            }\n            else this.onUpdate(() => check(this));\n        },\n    };\n}\n", "import type { Comp } from \"../../../types\";\nimport {\n    type InternalGameObjRaw,\n    nextTransformVersion,\n} from \"../../entity/GameObjRaw\";\n\n/**\n * The serialized {@link rotate `rotate()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedRotateComp {\n    angle: number;\n}\n\n/**\n * The {@link rotate `rotate()`} component.\n *\n * @group Components\n * @subgroup 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    serialize(): { angle: number };\n}\n\nexport function rotate(a?: number): RotateComp {\n    let _angle = a ?? 0;\n\n    return {\n        id: \"rotate\",\n\n        get angle(): number {\n            return _angle;\n        },\n        set angle(value: number) {\n            _angle = value;\n            (this as any as InternalGameObjRaw)._transformVersion =\n                nextTransformVersion();\n        },\n\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        serialize() {\n            return { angle: this.angle };\n        },\n    };\n}\n\nexport function rotateFactory(data: SerializedRotateComp) {\n    return rotate(data.angle);\n}\n", "import { vec2, type Vec2Args } from \"../../../math/math\";\nimport { type SerializedVec2, Vec2 } from \"../../../math/Vec2\";\nimport type { Comp } from \"../../../types\";\nimport {\n    type InternalGameObjRaw,\n    nextTransformVersion,\n} from \"../../entity/GameObjRaw\";\n\n/**\n * The serialized {@link scale `scale()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedScaleComp {\n    scale: SerializedVec2;\n}\n\n/**\n * The {@link scale `scale()`} component.\n *\n * @group Components\n * @subgroup 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     * Serialize the current state comp\n     */\n    serialize(): SerializedScaleComp;\n}\n\nexport function scale(...args: Vec2Args): ScaleComp {\n    if (args.length === 0) {\n        return scale(1);\n    }\n\n    const _scale = vec2(...args);\n    const _scaleReadOnly = vec2(...args);\n\n    return {\n        id: \"scale\",\n\n        get scale(): Vec2 {\n            return _scaleReadOnly;\n        },\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            _scale.x = value.x;\n            _scale.y = value.y;\n            _scaleReadOnly.x = value.x;\n            _scaleReadOnly.y = value.y;\n            (this as any as InternalGameObjRaw)._transformVersion =\n                nextTransformVersion();\n        },\n\n        scaleTo(...args: Vec2Args) {\n            this.scale = vec2(...args);\n        },\n        scaleBy(...args: Vec2Args) {\n            this.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 {\n                return `scale: (${_scale.x.toFixed(1)}x, ${\n                    _scale.y.toFixed(1)\n                }y)`;\n            }\n        },\n        serialize() {\n            return { scale: this.scale.serialize() };\n        },\n    };\n}\n\nexport function scaleFactory(data: SerializedScaleComp) {\n    return scale(data.scale.x, data.scale.y);\n}\n", "import { vec2, type Vec2Args } from \"../../../math/math\";\nimport { type SerializedVec2, Vec2 } from \"../../../math/Vec2\";\nimport type { Comp } from \"../../../types\";\nimport {\n    type InternalGameObjRaw,\n    nextTransformVersion,\n} from \"../../entity/GameObjRaw\";\n\n/**\n * The serialized {@link skew `skew()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedSkewComp {\n    skew: SerializedVec2;\n}\n\n/**\n * The {@link skew `skew()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface SkewComp extends Comp {\n    /**\n     * The current skew of the object\n     *\n     * @returns The current skew of the object as a {@link Vec2 `Vec2`}\n     */\n    skew: Vec2;\n    /**\n     * Serialize the current state comp\n     */\n    serialize(): SerializedSkewComp;\n}\n\nexport function skew(...args: Vec2Args): SkewComp {\n    if (args.length === 0) {\n        return skew(1);\n    }\n\n    const _skew = vec2(...args);\n    const _skewReadOnly = vec2(...args);\n\n    return {\n        id: \"skew\",\n\n        get skew(): Vec2 {\n            return _skewReadOnly;\n        },\n        set skew(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            _skew.x = value.x;\n            _skew.y = value.y;\n            _skewReadOnly.x = value.x;\n            _skewReadOnly.y = value.y;\n            (this as any as InternalGameObjRaw)._transformVersion =\n                nextTransformVersion();\n        },\n\n        inspect() {\n            if (_skew.x == _skew.y) {\n                return `skew: ${_skew.x.toFixed(1)}x`;\n            }\n            else {\n                return `skew: (${_skew.x.toFixed(1)}x, ${_skew.y.toFixed(1)}y)`;\n            }\n        },\n        serialize() {\n            return { skew: this.skew.serialize() };\n        },\n    };\n}\n\nexport function skewFactory(data: SerializedSkewComp) {\n    return skew(data.skew.x, data.skew.y);\n}\n", "import type { Comp } from \"../../../types\";\n\n/**\n * The serialized {@link z `z()`} component.\n *\n * @group Components\n * @subgroup Component Serialization\n */\nexport interface SerializedZComp {\n    z: number;\n}\n\n/**\n * The {@link z `z()`} component.\n *\n * @group Components\n * @subgroup Component Types\n */\nexport interface ZComp extends Comp {\n    /**\n     * Defines the z-index of this game obj\n     */\n    z: number;\n    /**\n     * Serialize the current state comp\n     */\n    serialize(): SerializedZComp;\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        serialize() {\n            return { z: this.z };\n        },\n    };\n}\n\nexport function zFactory(data: SerializedZComp) {\n    return z(data.z);\n}\n", "import { vec2 } from \"../../../math/math\";\nimport { _k } from \"../../../shared\";\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 += _k.app.dt();\n        },\n    };\n}\n", "import type { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { CompList, GameObj } from \"../../../types\";\nimport { sprite } from \"../../components/draw/sprite\";\nimport { boom } from \"../../components/misc/boom\";\nimport { stay } from \"../../components/misc/stay\";\nimport { timer } from \"../../components/misc/timer\";\nimport { anchor } from \"../../components/transform/anchor\";\nimport { pos } from \"../../components/transform/pos\";\nimport { scale } from \"../../components/transform/scale\";\n\n/**\n * @group Game Obj\n * @subgroup Types\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    if (!_k.game.defaultAssets.boom || !_k.game.defaultAssets.ka) {\n        throw new Error(\"You can't use addKaboom with kaplay/mini\");\n    }\n\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.game.defaultAssets.boom),\n        scale(0),\n        anchor(\"center\"),\n        boom(speed, s),\n        ...opt.comps ?? [],\n    ]);\n\n    const ka = kaboom.add([\n        sprite(_k.game.defaultAssets.ka),\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 { vec2 } from \"../../../math/math\";\nimport type { Vec2 } from \"../../../math/Vec2\";\nimport { _k } from \"../../../shared\";\nimport type { GameObj } from \"../../../types\";\nimport {\n    level,\n    type LevelComp,\n    type LevelCompOpt,\n} from \"../../components/level/level\";\nimport { pos, type PosComp } from \"../../components/transform/pos\";\n\n/**\n * Options for the {@link addLevel `addLevel()`}.\n *\n * @group Game Obj\n * @subgroup Types\n */\nexport interface AddLevelOpt extends LevelCompOpt {\n    /**\n     * Position of the first block.\n     */\n    pos?: Vec2;\n}\n\nexport function addLevel(\n    map: string[],\n    opt: AddLevelOpt,\n    parent: GameObj = _k.game.root,\n): GameObj<PosComp | LevelComp> {\n    return parent.add([pos(opt.pos ?? vec2(0)), level(map, opt)]);\n}\n", "import { vec2 } from \"../../math/math\";\nimport type { Vec2 } from \"../../math/Vec2\";\nimport { _k } from \"../../shared\";\nimport type { GameObj } from \"../../types\";\n\n/**\n * Collision resolution data.\n *\n * @group Physics\n */\n\nexport class Collision {\n    /**\n     * The first game object in the collision.\n     */\n    source: GameObj;\n    /**\n     * The second game object in the collision.\n     */\n    target: GameObj;\n    /**\n     * The contact normal.\n     */\n    normal: Vec2;\n    /**\n     * The length of the displacement.\n     */\n    distance: number;\n    /**\n     * If the collision is resolved.\n     */\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    /**\n     * The displacement source game object have to make to avoid the collision.\n     */\n    get displacement() {\n        return this.normal.scale(this.distance);\n    }\n    /**\n     * Get a new collision with reversed source and target relationship.\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    /**\n     * If the 2 objects have any overlap, or they're just touching edges.\n     *\n     * @since v3000.0\n     */\n    hasOverlap() {\n        return this.distance > 0;\n    }\n    /**\n     * If the collision happened (roughly) on the left side.\n     */\n    isLeft() {\n        return this.normal.cross(_k.game.gravity || vec2(0, 1)) > 0;\n    }\n    /**\n     * If the collision happened (roughly) on the right side.\n     */\n    isRight() {\n        return this.normal.cross(_k.game.gravity || vec2(0, 1)) < 0;\n    }\n    /**\n     * If the collision happened (roughly) on the top side.\n     */\n    isTop() {\n        return this.normal.dot(_k.game.gravity || vec2(0, 1)) > 0;\n    }\n    /**\n     * If the collision happened (roughly) on the bottom side.\n     */\n    isBottom() {\n        return this.normal.dot(_k.game.gravity || vec2(0, 1)) < 0;\n    }\n    /**\n     * Prevent collision resolution if not yet resolved.\n     *\n     * @since v3000.0\n     */\n    preventResolution() {\n        this.resolved = true;\n    }\n}\n", "import { _k } from \"../shared\";\nimport { deprecateMsg } from \"../utils/log\";\n\n// Layering\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 type { KEventController } from \"../events/events\";\nimport { Mat23, vec2 } from \"../math/math\";\nimport { _k } from \"../shared\";\n\n/**\n * The function definition for a scene\n *\n * @group Scenes\n * @subgroup Types\n */\nexport type SceneDef = (...args: any) => void;\n\n/**\n * The state of a scene.\n *\n * @group Scenes\n * @subgroup Types\n */\nexport type SceneState = {\n    sceneID: string | null;\n    args: unknown[];\n};\n\nexport function scene(id: string, def: SceneDef) {\n    _k.game.scenes[id] = def;\n}\n\nexport function go(name: string, ...args: unknown[]) {\n    if (!_k.game.scenes[name]) {\n        throw new Error(`Scene not found: ${name}`);\n    }\n\n    _k.app.events.onOnce(\"frameEnd\", () => {\n        _k.game.events.trigger(\"sceneLeave\", name);\n\n        _k.game.sceneEvents.forEach((e) => e?.cancel());\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\n        // cam\n        _k.game.cam = {\n            pos: null,\n            scale: vec2(1),\n            angle: 0,\n            shake: 0,\n            transform: new Mat23(),\n        };\n\n        _k.game.currentSceneArgs = args;\n        _k.game.scenes[name](...args);\n    });\n\n    _k.game.currentScene = name;\n}\n\nexport function pushScene(id: string, ...args: unknown[]) {\n    _k.game.sceneStack.push({\n        sceneID: _k.game.currentScene,\n        args: _k.game.currentSceneArgs,\n    });\n    go(id, ...args);\n    return;\n}\n\nexport function popScene() {\n    const sceneData: SceneState | undefined = _k.game.sceneStack.pop();\n\n    if (sceneData === undefined) {\n        throw new Error(\"No more scenes to pop!\");\n    }\n\n    if (sceneData.sceneID === null) {\n        throw new Error(\"The scene ID should not be null\");\n    }\n\n    go(sceneData.sceneID, ...sceneData.args);\n}\n\nexport function getSceneName() {\n    return _k.game.currentScene;\n}\n\nexport function getSceneArgs() {\n    return _k.game.currentSceneArgs;\n}\n", "import { type ColorArgs, rgb } from \"../math/color\";\nimport { _k } from \"../shared\";\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 \"../shared\";\nimport type { Canvas } from \"../types\";\nimport { FrameBuffer } from \"./FrameBuffer\";\nimport { flush } from \"./stack\";\n\nexport const makeCanvas = (w: number, h: number): Canvas => {\n    const fb = new FrameBuffer(_k.ggl, w, h);\n\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", "import type { Vec2 } from \"../../math/Vec2\";\nimport type { RenderProps } from \"../../types\";\nimport { drawLines } from \"./drawLine\";\n\n/**\n * @group Draw\n * @subgroup Types\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(Object.assign({}, opt, {\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 } from \"../../math/math\";\nimport { type Vec2 } from \"../../math/Vec2\";\nimport { drawCurve, type DrawCurveOpt } from \"./drawCurve\";\n\n/**\n * @group Draw\n * @subgroup Types\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 { vec2 } from \"../../math/math\";\nimport type { Canvas } from \"../../types\";\nimport { height } from \"../stack\";\nimport { drawUVQuad, type DrawUVQuadOpt } from \"./drawUVQuad\";\n\n/**\n * @group Draw\n * @subgroup Types\n */\nexport type DrawCanvasOpt = DrawUVQuadOpt & {\n    canvas: Canvas;\n};\n\nexport function drawCanvas(opt: DrawCanvasOpt) {\n    const fb = opt.canvas.fb;\n    drawUVQuad(Object.assign({}, opt, {\n        tex: fb.tex,\n        width: opt.width || fb.width,\n        height: opt.height || fb.height,\n        pos: (opt.pos || vec2()).add(0, height()),\n        scale: (opt.scale || vec2(1)).scale(1, -1),\n    }));\n}\n", "import type { Asset } from \"../../assets/asset\";\nimport { resolveSprite, type SpriteData } from \"../../assets/sprite\";\nimport { Quad, vec2 } from \"../../math/math\";\nimport { type Vec2 } from \"../../math/Vec2\";\nimport type { Anchor, RenderProps } from \"../../types\";\nimport type { Texture } from \"../gfx\";\nimport { drawTexture } from \"./drawTexture\";\n\n/**\n * How the sprite should look like.\n *\n * @group Draw\n * @subgroup Types\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 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 frame = spr.data.frames[opt.frame ?? 0];\n    if (!frame) {\n        throw new Error(`Frame not found: ${opt.frame ?? 0}`);\n    }\n    const q = frame.q.scale(opt.quad ?? new Quad(0, 0, 1, 1));\n\n    const scale = calcTexScale(frame.tex, q, opt.width, opt.height);\n    const width = opt.width ?? frame.tex.width * q.w * scale.x;\n    const height = opt.height ?? frame.tex.height * q.h * scale.y;\n\n    drawTexture(\n        Object.assign({}, opt, {\n            tex: frame.tex,\n            quad: q,\n            width,\n            height,\n        }),\n    );\n}\n", "import type { Vec2 } from \"../../math/Vec2\";\nimport type { RenderProps } from \"../../types\";\nimport { drawPolygon } from \"./drawPolygon\";\n\n/**\n * How the triangle should look like.\n *\n * @group Draw\n * @subgroup Types\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 { rand } from \"../math\";\n\ntype Predicate = (value: any) => boolean;\n\nexport class DecisionNode {\n    attribute: string;\n    children: DecisionNode[] = [];\n    totalWeight = 0;\n    constructor(attribute: string) {\n        this.attribute = attribute;\n    }\n\n    addValueNode(value: any, attribute: string): DecisionNode {\n        const node = new ValueDecisionNode(value, attribute);\n        this.children.push(node);\n        return node;\n    }\n\n    addPredicateNode(predicate: Predicate, attribute: string): DecisionNode {\n        const node = new PredicateDecisionNode(predicate, attribute);\n        this.children.push(node);\n        return node;\n    }\n\n    addWeightNode(weight: any, attribute: string): DecisionNode {\n        if (weight === 0) {\n            throw Error(\"Weight nodes cannot have 0 probability\");\n        }\n        if (this.children.length > 0 && this.totalWeight == 0) {\n            throw Error(\"Weight nodes cannot be mixed with other nodes\");\n        }\n        const node = new WeightDecisionNode(weight, attribute);\n        this.children.push(node);\n        this.totalWeight += weight;\n        return node;\n    }\n\n    evaluate(answers: any): string {\n        if (this.children.length === 0) {\n            return this.attribute;\n        }\n        else {\n            // We need to pick a random node\n            if (this.totalWeight) {\n                const dice = rand(this.totalWeight);\n                let sum = 0;\n                for (const node of this.children) {\n                    sum += (node as WeightDecisionNode).weight;\n                    if (dice < sum) {\n                        return node.evaluate(answers);\n                    }\n                }\n            }\n            // We need to evaluate until a node asserts true\n            else {\n                const value = answers[this.attribute];\n                for (const node of this.children) {\n                    if (node.assert(value)) {\n                        return node.evaluate(answers);\n                    }\n                }\n            }\n        }\n        throw new Error(\"Invalid decision tree\");\n    }\n\n    assert(value: any): boolean {\n        return false;\n    }\n}\n\nclass ValueDecisionNode extends DecisionNode {\n    value: any;\n\n    constructor(value: any, attribute: string) {\n        super(attribute);\n        this.value = value;\n    }\n\n    assert(value: any): boolean {\n        return this.value == value;\n    }\n}\n\nclass PredicateDecisionNode extends DecisionNode {\n    predicate: Predicate;\n\n    constructor(predicate: Predicate, attribute: string) {\n        super(attribute);\n        this.predicate = predicate;\n    }\n\n    assert(value: any): boolean {\n        return this.predicate(value);\n    }\n}\n\nclass WeightDecisionNode extends DecisionNode {\n    weight: number;\n\n    constructor(weight: number, attribute: string) {\n        super(attribute);\n        this.weight = weight;\n    }\n\n    assert(value: any): boolean {\n        return false;\n    }\n}\n\nfunction sum(values: number[]) {\n    return values.reduce((sum, v) => sum + v, 0);\n}\n\nfunction distinct(values: any[]) {\n    return [...new Set(values)];\n}\n\nfunction entropy(outcomes: boolean[]) {\n    let positive = 0;\n    for (const outcome of outcomes) {\n        if (outcome) {\n            positive++;\n        }\n    }\n    const negative = (outcomes.length - positive) / outcomes.length;\n    positive = positive / outcomes.length;\n    return -(positive * (positive ? Math.log2(positive) : 0)\n        + negative * (negative ? Math.log2(negative) : 0));\n}\n\nfunction gain(values: any[], outcomes: boolean[]) {\n    const splitByAttribute: Record<string, boolean[]> = {};\n    for (let i = 0; i < values.length; i++) {\n        const value = values[i];\n        if (value in splitByAttribute) {\n            splitByAttribute[value].push(outcomes[i]);\n        }\n        else {\n            splitByAttribute[value] = [outcomes[i]];\n        }\n    }\n    return entropy(outcomes)\n        - sum(\n            Object.values(splitByAttribute).map(o =>\n                entropy(o) * o.length / outcomes.length\n            ),\n        );\n}\n\nexport class DecisionTree {\n    root: DecisionNode;\n\n    constructor(attribute: string) {\n        this.root = new DecisionNode(attribute);\n    }\n\n    evaluate(answers: any): string {\n        return this.root.evaluate(answers);\n    }\n\n    /**\n     * Computes a decision tree from example data\n     * @param data - Example data, a list of columns, where each column contains values for an attribute in attributes.\n     * @param attributes - The names of the columns.\n     * @param outcomes - The outcomes for each row.\n     */\n    static learnFromExamples(\n        data: any[][],\n        attributes: string[],\n        outcomes: boolean[],\n    ) {\n        function indexOfAttributeToSplitOn(\n            data: any[][],\n            attributes: string[],\n            outcomes: boolean[],\n        ) {\n            const gains = attributes.map((_, index) =>\n                gain(data[index], outcomes)\n            );\n            const maxGain = Math.max(...gains);\n            const index = gains.indexOf(maxGain);\n            return index;\n        }\n        function createBranches(\n            node: DecisionNode,\n            data: any[][],\n            attributes: string[],\n            outcomes: boolean[],\n            index: number,\n        ) {\n            const attributeColumn = data[index];\n            const values = distinct(attributeColumn);\n            // Remove the attribute column\n            const a = attributes.filter((_, i) => i != index);\n            data = data.filter((_, i) => i != index);\n            // Create a branch for each possible value of the attribute\n            for (const value of values) {\n                // Only filter the outcome for now, if the entropy is small, we will create a leaf\n                const o = outcomes.filter((_, index) =>\n                    attributeColumn[index] === value\n                );\n                const e = entropy(o);\n                if (e === 0) { // Or very small\n                    // Leaf\n                    node.addValueNode(value, o[0] ? \"true\" : \"false\");\n                }\n                else {\n                    // Branch\n                    const d = data.map(column =>\n                        column.filter((_, index) =>\n                            attributeColumn[index] === value\n                        )\n                    );\n                    // Split on the attribute with the most information gain\n                    const index = indexOfAttributeToSplitOn(\n                        d,\n                        a,\n                        o,\n                    );\n                    const attribute = attributes[index];\n                    const n = node.addValueNode(value, attribute);\n                    createBranches(n, d, a, o, index);\n                }\n            }\n        }\n        // Split on the attribute with the most information gain\n        const index = indexOfAttributeToSplitOn(data, attributes, outcomes);\n        const attribute = attributes[index];\n        const tree = new DecisionTree(attribute);\n        createBranches(tree.root, data, attributes, outcomes, index);\n        return tree;\n    }\n}\n", "type Predicate = (system: RuleSystem) => boolean;\ntype Action = (system: RuleSystem) => void;\n\nexport class Rule {\n    predicate: Predicate;\n    salience;\n    constructor(predicate: Predicate, salience: number) {\n        this.predicate = predicate;\n        this.salience = salience;\n    }\n\n    evaluate(system: RuleSystem): boolean {\n        return this.predicate(system);\n    }\n\n    execute(system: RuleSystem): void {\n    }\n}\n\nclass ActionRule extends Rule {\n    action;\n    constructor(predicate: Predicate, action: Action, salience: number) {\n        super(predicate, salience);\n        this.action = action;\n    }\n\n    execute(system: RuleSystem): void {\n        this.action(system);\n    }\n}\n\nclass AssertRule extends Rule {\n    fact;\n    grade;\n    constructor(\n        predicate: Predicate,\n        fact: string,\n        grade: number,\n        salience: number,\n    ) {\n        super(predicate, salience);\n        this.fact = fact;\n        this.grade = grade;\n    }\n\n    execute(system: RuleSystem): void {\n        system.assertFact(this.fact, this.grade);\n    }\n}\n\nclass RetractRule extends Rule {\n    fact;\n    grade;\n    constructor(\n        predicate: Predicate,\n        fact: string,\n        grade: number,\n        salience: number,\n    ) {\n        super(predicate, salience);\n        this.fact = fact;\n        this.grade = grade;\n    }\n\n    execute(system: RuleSystem) {\n        system.retractFact(this.fact, this.grade);\n    }\n}\n\nexport class RuleSystem {\n    // Rules to evaluate and execute\n    agenda: Rule[] = [];\n    // Game state\n    state: any = {};\n    // Asserted facts\n    facts: Map<string, number> = new Map<string, number>();\n\n    constructor() {\n    }\n\n    /**\n     * Adds a rule which runs an action if its predicate evaluates to true.\n     * @param predicate - Predicate to evaluate. A function taking the system as parameter.\n     * @param action - Action to execute. A function taking the system as parameter.\n     * @param salience - Priority of the rule.\n     */\n    addRuleExecutingAction(\n        predicate: Predicate,\n        action: Action,\n        salience: number = 0,\n    ) {\n        this.addRule(new ActionRule(predicate, action, salience));\n    }\n\n    /**\n     * Add a rule which asserts a fact if its predicate evaluates to true.\n     * @param predicate - Predicate to evaluate. A function taking the system as parameter.\n     * @param fact - The fact to assert.\n     * @param grade - The optional grade to use when asserting the fact.\n     * @param salience - Priority of the rule.\n     */\n    addRuleAssertingFact(\n        predicate: Predicate,\n        fact: string,\n        grade: number = 1,\n        salience: number = 0,\n    ) {\n        this.addRule(new AssertRule(predicate, fact, grade, salience));\n    }\n\n    /**\n     * Add a rule which retracts a fact if its predicate evaluates to true.\n     * @param predicate - Predicate to evaluate. A function taking the system as parameter.\n     * @param fact - The fact to retract.\n     * @param grade - The optional grade to use when retracting the fact.\n     * @param salience - Priority of the rule.\n     */\n    addRuleRetractingFact(\n        predicate: Predicate,\n        fact: string,\n        grade: number = 1,\n        salience: number = 0,\n    ) {\n        this.addRule(new RetractRule(predicate, fact, grade, salience));\n    }\n\n    /**\n     * Add a custom rule.\n     * @param rule - The rule to add.\n     */\n    addRule(rule: Rule) {\n        this.agenda.push(rule);\n    }\n\n    /**\n     * Removes all rules.\n     */\n    removeAllRules() {\n        this.agenda.length = 0;\n    }\n\n    /**\n     * Executes all rules for which the predicate evaluates to true.\n     */\n    execute() {\n        this.agenda.sort((a, b) => a.salience - b.salience);\n        for (const rule of this.agenda) {\n            if (rule.evaluate(this)) {\n                rule.execute(this);\n            }\n        }\n    }\n\n    /**\n     * Asserts a fact.\n     * @param fact - The fact to assert.\n     * @param grade - The optional grade to use.\n     */\n    assertFact(fact: string, grade: number = 1) {\n        this.facts.set(fact, Math.min(1, this.gradeForFact(fact) + grade));\n    }\n\n    /**\n     * Retracts a fact.\n     * @param fact - The fact to retract.\n     * @param grade - The optional grade to use.\n     */\n    retractFact(fact: string, grade: number = 1) {\n        this.facts.set(fact, Math.max(0, this.gradeForFact(fact) - grade));\n    }\n\n    /**\n     * Returns the grade for the specified fact.\n     * @param fact - The fact to obtain the grade from.\n     *\n     * @returns The grade for the fact.\n     */\n    gradeForFact(fact: string) {\n        return this.facts.get(fact) || 0;\n    }\n\n    /**\n     * Returns the minimum grade for the specified facts.\n     * @param facts - The facts to obtain the minimum grade from.\n     *\n     * @returns The minimum grade for the facts.\n     */\n    minimumGradeForFacts(...facts: string[]) {\n        return Math.min(...facts.map(fact => this.gradeForFact(fact)));\n    }\n\n    /**\n     * Returns the maximum grade for the specified facts.\n     * @param facts - The facts to obtain the maximum grade from.\n     *\n     * @returns The maximum grade for the facts.\n     */\n    maximumGradeForFacts(...facts: string[]) {\n        return Math.max(...facts.map(fact => this.gradeForFact(fact)));\n    }\n\n    /**\n     * Resets the facts.\n     */\n    reset() {\n        this.facts.clear();\n    }\n}\n", "type EnterCallback = (sm: StateMachine, previous: string) => void;\ntype UpdateCallback = (sm: StateMachine, current: string) => void;\ntype DrawCallback = (sm: StateMachine, current: string) => void;\ntype ExitCallback = (sm: StateMachine, next: string) => void;\ntype TransitionCallback = (sm: StateMachine, from: string, to: string) => void;\n\ntype StateCallbacks = {\n    enter?: EnterCallback;\n    update?: UpdateCallback;\n    draw?: DrawCallback;\n    exit?: ExitCallback;\n};\n\nclass State {\n    name: string;\n    callbacks: StateCallbacks;\n    transitions: Record<string, TransitionCallback> = {};\n    constructor(name: string, callbacks: StateCallbacks) {\n        this.name = name;\n        this.callbacks = callbacks;\n    }\n}\n\n/**\n * A finite state machine\n */\nexport class StateMachine {\n    stateMap: Record<string, State> = {};\n    state: State | undefined;\n\n    /**\n     * Create a machine given the states and initial state\n     * @param states - The states the machine can be in\n     * @param initialState - The initial state it will enter if given\n     */\n    constructor(states: string[]) {\n        states.forEach(name => {\n            this.stateMap[name] = new State(name, {});\n        });\n    }\n\n    /**\n     * Make the machine enter a state\n     * @param name - The new state\n     */\n    enterState(name: string) {\n        let oldStateName = this.state?.name || \"\";\n\n        // Exit old state\n        if (this.state?.callbacks.exit) {\n            this.state.callbacks.exit(this, name);\n        }\n\n        if (this.state?.transitions[name]) {\n            this.state.transitions[name](this, oldStateName, name);\n        }\n\n        // Enter new state\n        this.state = this.stateMap[name];\n        if (this.state.callbacks.enter) {\n            this.state.callbacks.enter(this, oldStateName);\n        }\n    }\n\n    /**\n     * Set a callback for when the machine enters a state\n     * @param name - The state\n     * @param cb - The callback\n     */\n    onStateEnter(\n        name: string,\n        cb: (sm: StateMachine, previous: string) => void,\n    ) {\n        const state = this.stateMap[name];\n        if (state) {\n            state.callbacks.enter = cb;\n        }\n    }\n\n    /**\n     * Set a callback for when the machine updates a state\n     * @param name - The state\n     * @param cb - The callback\n     */\n    onStateUpdate(\n        name: string,\n        cb: (sm: StateMachine, current: string) => void,\n    ) {\n        const state = this.stateMap[name];\n        if (state) {\n            state.callbacks.update = cb;\n        }\n    }\n\n    /**\n     * Set a callback for when the machine draws a state\n     * @param name - The state\n     * @param cb - The callback\n     */\n    onStateDraw(name: string, cb: (sm: StateMachine, current: string) => void) {\n        const state = this.stateMap[name];\n        if (state) {\n            state.callbacks.draw = cb;\n        }\n    }\n\n    /**\n     * Set a callback for when the machine exits a state\n     * @param name - The state\n     * @param cb - The callback\n     */\n    onStateExit(name: string, cb: (sm: StateMachine, next: string) => void) {\n        const state = this.stateMap[name];\n        if (state) {\n            state.callbacks.exit = cb;\n        }\n    }\n\n    /**\n     * Set a callback for when the machine transitions from one state to the other state\n     * @param from - The state which is exited\n     * @param to - The state which is entered\n     * @param cb - The callback\n     */\n    onStateTransition(\n        from: string,\n        to: string,\n        cb: (sm: StateMachine, from: string, to: string) => void,\n    ) {\n        const state = this.stateMap[from];\n        if (state) {\n            state.transitions[to] = cb;\n        }\n    }\n}\n", "import type { Vec2 } from \"./Vec2\";\n\n/**\n * > 0 if counter clockwise\n * < 0 if clockwise\n * == 0 if colinear\n */\nfunction orient(a: Vec2, b: Vec2, c: Vec2) {\n    const v = a.x * (b.y - c.y)\n        + b.x * (c.y - a.y)\n        + c.x * (a.y - b.y);\n    if (v < 0) return -1;\n    if (v > 0) return +1;\n    return 0;\n}\n\n/**\n * Graham scan to calculate the convex hull of a polygon\n */\nexport function buildConvexHull(points: Vec2[]) {\n    // Find the point with lowest y, then lowest x\n    let first = 0;\n    for (let i = 1; i < points.length; i++) {\n        if (points[i].y < points[first].y) {\n            first = i;\n        }\n        else if (\n            points[i].y == points[first].y && points[i].x < points[first].x\n        ) {\n            first = i;\n        }\n    }\n    // Sort points on angle, then greatest distance\n    const sorted = points.toSorted((a, b) => {\n        const o = orient(points[first], a, b);\n        if (o === 0) {\n            return points[first].sdist(a) - points[first].sdist(b);\n        }\n        return (o < 0) ? -1 : 1;\n    });\n    // Build hull, removing points which change orientation\n    const stack = [sorted[0], sorted[1]];\n    for (let i = 2; i < sorted.length; i++) {\n        while (\n            stack.length > 1\n            && orient(\n                    stack[stack.length - 2],\n                    stack[stack.length - 1],\n                    sorted[i],\n                ) >= 0\n        ) {\n            stack.pop();\n        }\n        stack.push(sorted[i]);\n    }\n    return stack;\n}\n", "import { MAX_TRIES } from \"../constants/general\";\nimport type { Shape } from \"../types\";\nimport { Circle, Ellipse, Polygon, Rect, vec2 } from \"./math\";\nimport { Vec2 } from \"./Vec2\";\n\nfunction calculateSupport(\n    shapeA: Shape,\n    shapeB: Shape,\n    direction: Vec2,\n): Vec2 {\n    // Calculate the support vector. This is done by calculating the difference between\n    // the furthest points found of the shapes along the given direction.\n    let oppositeDirection = new Vec2(-direction.x, -direction.y);\n    const supportA = shapeA.support(direction);\n    const supportB = shapeB.support(oppositeDirection);\n    return new Vec2(supportA.x - supportB.x, supportA.y - supportB.y);\n}\n\nfunction addSupport(\n    vertices: Array<Vec2>,\n    shapeA: Shape,\n    shapeB: Shape,\n    direction: Vec2,\n): boolean {\n    var support: Vec2 = calculateSupport(shapeA, shapeB, direction);\n    vertices.push(support);\n    // Returns true if both vectors are in the same direction\n    return direction.dot(support) >= 0;\n}\n\nenum EvolveResult {\n    NoIntersection,\n    FoundIntersection,\n    Evolving,\n}\n\nfunction tripleProduct(a: Vec2, b: Vec2, c: Vec2): Vec2 {\n    // AxB = (0, 0, axb)\n    // AxBxC = (-axb * c.y, axb * c.x, 0)\n    const n = a.x * b.y - a.y * b.x;\n\n    // This vector lies in the same plane as a and b and is perpendicular to c\n    return new Vec2(-n * c.y, n * c.x);\n}\n\nfunction evolveSimplex(\n    simplex: Vec2[],\n    colliderA: Shape,\n    colliderB: Shape,\n    direction: Vec2,\n): EvolveResult {\n    switch (simplex.length) {\n        case 0: {\n            // Zero points, set the direction the center of colliderA\n            // towards the center of of colliderB\n            direction.x = colliderB.gjkCenter.x - colliderA.gjkCenter.x;\n            direction.y = colliderB.gjkCenter.y - colliderA.gjkCenter.y;\n            break;\n        }\n        case 1: {\n            // Reverse the direction, to make a line\n            direction.x = direction.x *= -1;\n            direction.y = direction.y *= -1;\n            break;\n        }\n        case 2: {\n            // We now have a line ab. Take the vector ab and the vector a origin\n            const ab = new Vec2(\n                simplex[1].x - simplex[0].x,\n                simplex[1].y - simplex[0].y,\n            );\n            const a0 = new Vec2(-simplex[0].x, -simplex[0].y);\n\n            // Get the vector perpendicular to ab and a0\n            // Then get the vector perpendicular to the result and ab\n            const tp = tripleProduct(ab, a0, ab);\n            // This is our new direction to form a triangle\n            direction.x = tp.x;\n            direction.y = tp.y;\n            break;\n        }\n        case 3:\n            {\n                // We have a triangle, and need to check if it contains the origin\n                const c0 = new Vec2(-simplex[2].x, -simplex[2].y);\n                const bc = new Vec2(\n                    simplex[1].x - simplex[2].x,\n                    simplex[1].y - simplex[2].y,\n                );\n                const ca = new Vec2(\n                    simplex[0].x - simplex[2].x,\n                    simplex[0].y - simplex[2].y,\n                );\n\n                var bcNorm = tripleProduct(ca, bc, bc);\n                var caNorm = tripleProduct(bc, ca, ca);\n\n                if (bcNorm.dot(c0) > 0) {\n                    // The origin does not lie within the triangle\n                    // Remove the first point and look in the direction of bcNorm\n                    simplex.splice(0, 1);\n                    direction.x = bcNorm.x;\n                    direction.y = bcNorm.y;\n                }\n                else if (caNorm.dot(c0) > 0) {\n                    // The origin does not lie within the triangle\n                    // Remove the second point and look in the direction of caNorm\n                    simplex.splice(1, 1);\n                    direction.x = caNorm.x;\n                    direction.y = caNorm.y;\n                }\n                else {\n                    // The origin lies within the triangle\n                    return EvolveResult.FoundIntersection;\n                }\n            }\n            break;\n        default:\n            throw Error(\n                `Can\\'t have s simplex with ${simplex.length} vertices!`,\n            );\n    }\n\n    // Try to add a new support point to the simplex\n    // If successful, continue evolving\n    return addSupport(simplex, colliderA, colliderB, direction)\n        ? EvolveResult.Evolving\n        : EvolveResult.NoIntersection;\n}\n\n/**\n * Returns true if the colliders intersect.\n * @param colliderA - The first collider to test\n * @param colliderB - The second collider to test\n *\n * @returns True if the colliders intersect\n */\nfunction gjkIntersects(colliderA: Shape, colliderB: Shape): boolean {\n    const vertices: Vec2[] = [];\n    let direction = new Vec2();\n\n    var result: EvolveResult = EvolveResult.Evolving;\n    while (result === EvolveResult.Evolving) {\n        result = evolveSimplex(vertices, colliderA, colliderB, direction);\n    }\n    return result === EvolveResult.FoundIntersection;\n}\n\nenum PolygonWinding {\n    Clockwise,\n    CounterClockwise,\n}\n\ntype GjkEdge = {\n    distance: number;\n    normal: Vec2;\n    index: number;\n};\n\n/**\n * Returns the edge closest to the origin.\n * @param simplex - The simplex whose edges we will check to find the closest edge to the origin\n * @param winding - The winding order of the simplex\n *\n * @returns The edge closest to the origin.\n */\nfunction findClosestEdge(simplex: Vec2[], winding: PolygonWinding): GjkEdge {\n    let minDistance: number = Number.POSITIVE_INFINITY;\n    let minNormal = new Vec2();\n    let minIndex = 0;\n    let line = new Vec2();\n    let norm = new Vec2();\n    for (let i = 0; i < simplex.length; i++) {\n        let j = i + 1;\n        if (j >= simplex.length) j = 0;\n\n        Vec2.sub(simplex[j], simplex[i], line);\n\n        // The normal of the edge depends on the polygon winding of the simplex\n        switch (winding) {\n            case PolygonWinding.Clockwise:\n                norm.x = line.y;\n                norm.y = -line.x;\n                break;\n            case PolygonWinding.CounterClockwise:\n                norm.x = -line.y;\n                norm.y = line.x;\n                break;\n        }\n        Vec2.unit(norm, norm);\n\n        // Only keep the edge closest to the origin\n        var dist: number = norm.dot(simplex[i]);\n        if (dist < minDistance) {\n            minDistance = dist;\n            Vec2.copy(norm, minNormal);\n            minIndex = j;\n        }\n    }\n\n    return { distance: minDistance, normal: minNormal, index: minIndex };\n}\n\nexport type GjkCollisionResult = {\n    /**\n     * The direction the first shape needs to be moved to resolve the collision\n     */\n    normal: Vec2;\n    /**\n     * The distance the first shape needs to be moved to resolve the collision\n     */\n    distance: number;\n};\n\n/**\n * Returns true if the shapes collide\n * @param colliderA - The first collider to test\n * @param colliderB - The second collider to test\n *\n * @returns True if the shapes collide\n */\nfunction getIntersection(\n    colliderA: Shape,\n    colliderB: Shape,\n    simplex: Vec2[],\n): GjkCollisionResult | null {\n    const EPSILON = 0.00001;\n\n    const e0: number = (simplex[1].x - simplex[0].x)\n        * (simplex[1].y + simplex[0].y);\n    const e1: number = (simplex[2].x - simplex[1].x)\n        * (simplex[2].y + simplex[1].y);\n    const e2: number = (simplex[0].x - simplex[2].x)\n        * (simplex[0].y + simplex[2].y);\n    var winding: PolygonWinding = (e0 + e1 + e2 >= 0)\n        ? PolygonWinding.Clockwise\n        : PolygonWinding.CounterClockwise;\n\n    let intersection = new Vec2();\n    for (let i = 0; i < MAX_TRIES; i++) {\n        var edge: GjkEdge = findClosestEdge(simplex, winding);\n        // Calculate the difference for the two vertices furthest along the direction of the edge normal\n        var support = calculateSupport(colliderA, colliderB, edge.normal);\n        // Check distance to the origin\n        var distance: number = support.dot(edge.normal);\n\n        Vec2.scale(edge.normal, distance, intersection);\n\n        // If close enough, return if we need to move a distance greater than 0\n        if (Math.abs(distance - edge.distance) <= EPSILON) {\n            const len = intersection.len();\n            if (len != 0) {\n                Vec2.scale(intersection, -1 / len, intersection);\n                return { normal: intersection, distance: len };\n            }\n            else {\n                return null;\n            }\n        }\n        else {\n            simplex.splice(edge.index, 0, support);\n        }\n    }\n\n    // Return if we need to move a distance greater than 0\n    // Since we did more than the maximum amount of iterations, this may not be optimal\n    const len = intersection.len();\n    if (len != 0) {\n        Vec2.scale(intersection, -1 / len, intersection);\n        return { normal: intersection, distance: len };\n    }\n    else {\n        return null;\n    }\n}\n\n/**\n * Returns a collision result if there was a collision\n * @param colliderA - The first collider to test\n * @param colliderB - The second collider to test\n *\n * @returns A collision result or null\n */\nfunction gjkIntersection(\n    colliderA: Shape,\n    colliderB: Shape,\n): GjkCollisionResult | null {\n    const vertices: Vec2[] = [];\n    let direction = new Vec2(\n        colliderB.gjkCenter.x - colliderA.gjkCenter.x,\n        colliderB.gjkCenter.y - colliderA.gjkCenter.y,\n    );\n\n    var result: EvolveResult = EvolveResult.Evolving;\n    while (result === EvolveResult.Evolving) {\n        result = evolveSimplex(vertices, colliderA, colliderB, direction);\n    }\n    if (result !== EvolveResult.FoundIntersection) {\n        return null;\n    }\n    return getIntersection(colliderA, colliderB, vertices);\n}\n\n/**\n * Returns true if the shapes collide\n * @param shapeA - The first shape to test\n * @param shapeB - The second shape to test\n *\n * @returns True if the shapes collide\n */\nexport function gjkShapeIntersects(shapeA: Shape, shapeB: Shape): boolean {\n    return gjkIntersects(shapeA, shapeB);\n}\n\n/**\n * Returns a collision result if there was a collision\n * @param shapeA - The first shape to test\n * @param shapeB - The second shape to test\n *\n * @returns A collision result or null\n */\nexport function gjkShapeIntersection(\n    shapeA: Shape,\n    shapeB: Shape,\n): GjkCollisionResult | null {\n    return gjkIntersection(shapeA, shapeB);\n}\n", "import { clampAngle } from \"./various\";\nimport { Vec2 } from \"./Vec2\";\n\nexport function lerpAngle<V extends number | Vec2>(a: V, b: V, t: number): V {\n    if (\n        typeof a === \"number\"\n        && typeof b === \"number\"\n        && typeof t === \"number\"\n    ) {\n        return clampAngle(a + clampAngle(b - a) * t) as V;\n    }\n    else if (a instanceof Vec2 && b instanceof Vec2) {\n        return a.slerp(b, t) as V;\n    }\n\n    throw new Error(\n        `Bad value for lerpAngle(): ${a}, ${b}, ${t}. Only number or Vec2 is supported.`,\n    );\n}\n", "import { vec2 } from \"./math\";\nimport { aStarSearch, buildConnectivityMap, type Graph } from \"./navigation\";\nimport { Vec2 } from \"./Vec2\";\n\n/**\n * A navigation grid is a graph consisting of connected grid cells\n */\nexport class NavGrid implements Graph {\n    private _columns: number;\n    private _rows: number;\n    private _tileWidth: number;\n    private _tileHeight: number;\n    private _diagonals: boolean;\n    private _connMap: number[];\n    private _isConnected: (a: number, b: number) => boolean;\n\n    /**\n     * @param data - Grid data\n     * @param options - Navigation options\n     */\n    constructor(\n        width: number,\n        height: number,\n        isConnected: (a: number, b: number) => boolean,\n        { diagonals = false, tileWidth = 1, tileHeight = 1 } = {},\n    ) {\n        this._columns = width;\n        this._rows = height;\n        this._tileWidth = tileWidth;\n        this._tileHeight = tileHeight;\n        this._diagonals = diagonals;\n        this._connMap = new Array(this._columns * this._rows).fill(-1);\n        this._isConnected = isConnected;\n\n        this._buildConnectivityMap();\n    }\n\n    private _buildConnectivityMap() {\n        const map = buildConnectivityMap(this);\n        map.forEach((index, node) => this._connMap[node] = index);\n    }\n\n    private _getTile(x: number, y: number): number {\n        const column = Math.floor(x / this._tileWidth);\n        const row = Math.floor(y / this._tileHeight);\n        return row * this._columns + column;\n    }\n\n    private _getTileX(tile: number): number {\n        return tile % this._columns;\n    }\n\n    private _getTileY(tile: number): number {\n        return Math.floor(tile / this._columns);\n    }\n\n    get nodes(): number[] {\n        return [...new Array(this._columns * this._rows).keys()];\n    }\n\n    getNeighbors(tile: number): number[] {\n        const neighbors = [];\n        const x = tile % this._columns;\n        // x > 0\n        if (x > 0) {\n            neighbors.push(tile - 1);\n            if (this._diagonals) {\n                if (tile >= this._columns) {\n                    neighbors.push(tile - this._columns - 1);\n                }\n                if (tile < (this._rows - 1) * this._columns) {\n                    neighbors.push(tile + this._columns - 1);\n                }\n            }\n        }\n        // y > 0\n        if (tile >= this._columns) {\n            neighbors.push(tile - this._columns);\n        }\n        // y < height\n        if (tile < (this._rows - 1) * this._columns) {\n            neighbors.push(tile + this._columns);\n        }\n        // x < width\n        if (x < this._columns - 1) {\n            neighbors.push(tile + 1);\n            if (this._diagonals) {\n                if (tile >= this._columns) {\n                    neighbors.push(tile - this._columns + 1);\n                }\n                if (tile < (this._rows - 1) * this._columns) {\n                    neighbors.push(tile + this._columns + 1);\n                }\n            }\n        }\n\n        return neighbors.filter(other => this._isConnected(tile, other));\n    }\n\n    getCost(a: number, b: number) {\n        // Manhattan distance\n        const x = Math.abs(this._getTileX(a) - this._getTileX(b));\n        const y = Math.abs(this._getTileY(a) - this._getTileY(b));\n        return Math.max(x, y);\n    }\n\n    getHeuristic(a: number, b: number) {\n        // Euclidean distance\n        const x = this._getTileX(a) - this._getTileX(b);\n        const y = this._getTileY(a) - this._getTileY(b);\n        return Math.sqrt(x * x + y * y);\n    }\n\n    getPath(start: number, goal: number): number[] {\n        // Tiles are not within the grid\n        const maxNode = this._columns * this._rows;\n        if (\n            start === null || goal === null || start < 0 || start >= maxNode\n            || goal < 0 || goal >= maxNode\n        ) {\n            return [];\n        }\n\n        // Tiles are not within the same section\n        if (this._connMap[start] !== this._connMap[goal]) {\n            return [];\n        }\n\n        // Same grid square\n        if (start === goal) {\n            return [start, goal];\n        }\n\n        return [start, ...aStarSearch(this, start, goal), goal];\n    }\n\n    getWaypointPath(\n        start: Vec2,\n        goal: Vec2,\n    ): Vec2[] {\n        const path = this.getPath(\n            this._getTile(start.x, start.y),\n            this._getTile(goal.x, goal.y),\n        );\n\n        if (!path) {\n            return [];\n        }\n\n        // Center of tile\n        const dx = Math.floor(this._tileWidth / 2);\n        const dy = Math.floor(this._tileHeight / 2);\n        return [\n            start,\n            ...path.slice(1, -1).map(tile => (vec2(\n                this._getTileX(tile) * this._tileWidth + dx,\n                this._getTileY(tile) * this._tileWidth + dy,\n            ))),\n            goal,\n        ];\n    }\n}\n", "import { vec2 } from \"./math\";\nimport { aStarSearch, type Graph } from \"./navigation\";\nimport { Vec2 } from \"./Vec2\";\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    get nodes(): number[] {\n        return [...this._polygons.keys()];\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    getNeighbors(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 { deg2rad, vec2 } from \"./math\";\nimport type { Vec2 } from \"./Vec2\";\n\nexport function createRegularPolygon(\n    radius: number,\n    sides: number,\n    startAngle: number = 0,\n): Vec2[] {\n    startAngle = deg2rad(startAngle);\n    let x = radius * Math.cos(startAngle);\n    let y = radius * Math.sin(startAngle);\n    const angle = 2 * Math.PI / sides;\n    const c = Math.cos(angle);\n    const s = Math.sin(angle);\n    const poly: Vec2[] = [];\n    for (let i = 0; i < sides; i++) {\n        poly.push(vec2(x, y));\n        [x, y] = [x * c - y * s, x * s + y * c];\n    }\n    return poly;\n}\n\nexport function createStarPolygon(\n    radius1: number,\n    radius2: number,\n    sides: number,\n    startAngle: number = 0,\n): Vec2[] {\n    startAngle = deg2rad(startAngle);\n    let x = Math.cos(startAngle);\n    let y = Math.sin(startAngle);\n    const angle = 2 * Math.PI / sides;\n    const c = Math.cos(angle);\n    const s = Math.sin(angle);\n    const poly: Vec2[] = [vec2(0)];\n    for (let i = 0; i < sides + 1; i++) {\n        const radius = i & 1 ? radius2 : radius1;\n        poly.push(vec2(x * radius, y * radius));\n        [x, y] = [x * c - y * s, x * s + y * c];\n    }\n    return poly;\n}\n\nexport function createCogPolygon(\n    radius1: number,\n    radius2: number,\n    sides: number,\n    startAngle: number = 0,\n): Vec2[] {\n    const angle = 2 * Math.PI / sides;\n    // Align startAngle so the cog is horizontal when startAngle is 0\n    startAngle = deg2rad(startAngle) - angle / 3;\n    let x = Math.cos(startAngle);\n    let y = Math.sin(startAngle);\n    const c = Math.cos(angle);\n    const s = Math.sin(angle);\n    const poly: Vec2[] = [vec2(0)];\n    for (let i = 0; i < sides + 1; i++) {\n        const radius = i / 2 & 1 ? radius2 : radius1;\n        poly.push(vec2(x * radius, y * radius));\n        [x, y] = [x * c - y * s, x * s + y * c];\n    }\n    return poly;\n}\n", "export function insertionSort<T>(a: T[], cmp: (a: T, b: T) => boolean) {\n    for (let i = 1; i < a.length; i++) {\n        for (let j = i - 1; j >= 0; j--) {\n            if (cmp(a[j], a[j + 1])) break;\n            swap(a, j, j + 1);\n        }\n    }\n}\n\nfunction swap<T>(a: T[], i: number, j: number) {\n    const temp = a[i];\n    a[i] = a[j];\n    a[j] = temp;\n}\n", "import {\n    type AreaComp,\n    getLocalAreaVersion,\n    getRenderAreaVersion,\n} from \"../../ecs/components/physics/area\";\n\nimport {\n    getTransformVersion,\n    objectTransformNeedsUpdate,\n} from \"../../ecs/entity/GameObjRaw\";\nimport { exists, isPaused } from \"../../ecs/entity/utils\";\nimport type { GameObj } from \"../../types\";\nimport { Rect, vec2 } from \"../math\";\nimport { calcTransform } from \"../various\";\nimport type { Vec2 } from \"../Vec2\";\nimport type { BroadPhaseAlgorithm } from \".\";\n\n/**\n * A quadtree structure\n */\nexport class Quadtree implements BroadPhaseAlgorithm {\n    bounds: Rect;\n    maxObjects: number;\n    maxLevels: number;\n    level: number;\n    nodes: Quadtree[];\n    objects: GameObj<AreaComp>[];\n    static versionsForObject: Map<GameObj<AreaComp>, [number, number, number]> =\n        new Map<GameObj<AreaComp>, [number, number, number]>();\n\n    /**\n     * Creates a new quadtree\n     * @param bounds - The bounds of this node.\n     * @param maxObjects - The maximum amount of objects before triggering a split.\n     * @param maxLevels - The maximum amount of levels before no more splits are made.\n     * @param level - The current level.\n     */\n    constructor(\n        bounds: Rect,\n        maxObjects: number = 8,\n        maxLevels: number = 4,\n        level: number = 0,\n    ) {\n        this.bounds = bounds;\n        this.maxObjects = maxObjects;\n        this.maxLevels = maxLevels;\n        this.level = level;\n        this.nodes = []; // lt, rt, rb, lb\n        this.objects = [];\n    }\n\n    /**\n     * True if this node is a leaf node.\n     */\n    get isLeaf() {\n        return this.nodes.length === 0;\n    }\n\n    /**\n     * Splits the node, but doesn't redistribute objects\n     */\n    subdivide() {\n        const level = this.level + 1;\n        const width = this.bounds.width / 2;\n        const height = this.bounds.height / 2;\n        const x = this.bounds.pos.x;\n        const y = this.bounds.pos.y;\n\n        const pos = [\n            vec2(x, y),\n            vec2(x + width, y),\n            vec2(x + width, y + height),\n            vec2(x, y + height),\n        ];\n\n        for (let i = 0; i < 4; i++) {\n            this.nodes[i] = new Quadtree(\n                new Rect(pos[i], width, height),\n                this.maxObjects,\n                this.maxLevels,\n                level,\n            );\n        }\n    }\n\n    /**\n     * Tries to merge and collapse nodes which are no longer overpopulated.\n     */\n    merge() {\n        if (this.nodes.length > 0) {\n            let count = this.objects.length;\n            let allLeaves = true;\n            for (let i = 0; i < 4; i++) {\n                this.nodes[i].merge();\n                allLeaves &&= this.nodes[i].isLeaf;\n                count += this.nodes[i].objects.length;\n            }\n\n            if (allLeaves && count <= this.maxObjects) {\n                for (let i = 0; i < 4; i++) {\n                    this.objects.push(...this.nodes[i].objects);\n                }\n                this.nodes = [];\n            }\n        }\n    }\n\n    /**\n     * Returns the quadrant this rect fits in or -1 if it doesn't fit any quadrant\n     * @param rect - The rect to test with.\n     *\n     * @returns The index of the quadrant fitting the rect completely, or -1 if none.\n     */\n    getQuadrant(rect: Rect) {\n        const boundsCenterX = this.bounds.pos.x + (this.bounds.width / 2);\n        const boundsCenterY = this.bounds.pos.y + (this.bounds.height / 2);\n        // Left - If the right side is left of the center\n        if (rect.pos.x + rect.width < boundsCenterX) {\n            // Top Left - If the bottom side is above the center\n            if (rect.pos.y + rect.height < boundsCenterY) {\n                return 0;\n            }\n            // Bottom Left - If the top side is below the center\n            else if (rect.pos.y >= boundsCenterY) {\n                return 3;\n            }\n        }\n        // Right - If the left side is right of the center\n        else if (rect.pos.x >= boundsCenterX) {\n            // Top Right - If the bottom side is above the center\n            if (rect.pos.y + rect.height < boundsCenterY) {\n                return 1;\n            }\n            // Bottom Right - If the top side is below the center\n            else if (rect.pos.y >= boundsCenterY) {\n                return 2;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Returns the quadrants this rect intersects\n     * @param rect - The rect to test with. Note that this rect is assumed to be within the node.\n     *\n     * @returns the list of quadrant indices\n     */\n    getQuadrants(rect: Rect): number[] {\n        const boundsCenterX = this.bounds.pos.x + (this.bounds.width / 2);\n        const boundsCenterY = this.bounds.pos.y + (this.bounds.height / 2);\n        const quadrants: number[] = [];\n\n        // Left - The left side is left of the center\n        if (rect.pos.x < boundsCenterX) {\n            // Top Left - If the top side is above the center\n            if (rect.pos.y < boundsCenterY) {\n                quadrants.push(0);\n            }\n            // Bottom Left - If the bottom side is below the center\n            if (rect.pos.y + rect.height > boundsCenterY) {\n                quadrants.push(3);\n            }\n        }\n        // Right - If the right side is right of the center\n        if (rect.pos.x + rect.width > boundsCenterX) {\n            // Top Right - If the top side is above the center\n            if (rect.pos.y < boundsCenterY) {\n                quadrants.push(1);\n            }\n            // Bottom Right - If the bottom side is below the center\n            if (rect.pos.y + rect.height > boundsCenterY) {\n                quadrants.push(2);\n            }\n        }\n        return quadrants;\n    }\n\n    /**\n     * Inserts the object with the given rectangle\n     * @param obj - The object to add\n     * @param bbox - The bounding box of the object\n     */\n    insert(obj: GameObj<AreaComp>, bbox: Rect): void {\n        // If we reached max objects, subdivide and redistribute\n        if (this.objects.length >= this.maxObjects) {\n            if (this.nodes.length === 0 && this.level < this.maxLevels) {\n                this.subdivide();\n                // Redistribute objects\n                let j = 0;\n                for (let i = 0; i < this.objects.length; i++) {\n                    const obj = this.objects[i];\n                    const bbox = obj.worldBbox();\n                    const index = this.getQuadrant(bbox);\n                    if (index !== -1) {\n                        this.nodes[index].insert(obj, bbox);\n                    }\n                    else {\n                        this.objects[j++] = obj;\n                        Quadtree.versionsForObject.set(obj, [\n                            getTransformVersion(obj),\n                            getRenderAreaVersion(obj),\n                            getLocalAreaVersion(obj),\n                        ]);\n                    }\n                }\n                this.objects.length = j;\n            }\n        }\n\n        // Check if the object fits in a smaller quadrant\n        if (this.nodes.length) {\n            const index = this.getQuadrant(bbox);\n\n            if (index !== -1) {\n                this.nodes[index].insert(obj, bbox);\n                return;\n            }\n        }\n\n        this.objects.push(obj);\n        Quadtree.versionsForObject.set(obj, [\n            getTransformVersion(obj),\n            getRenderAreaVersion(obj),\n            getLocalAreaVersion(obj),\n        ]);\n    }\n\n    /**\n     * Add the object\n     * @param obj - The object to add\n     */\n    add(obj: GameObj<AreaComp>) {\n        const bbox = obj.worldBbox();\n        this.insert(obj, bbox);\n    }\n\n    /**\n     * Retrieves all objects potentially intersecting the rectangle\n     * @param rect - The rect to test with\n     *\n     * @returns A set of objects potentially intersecting the rectangle\n     */\n    retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void {\n        for (let i = 0; i < this.objects.length; i++) {\n            retrieveCb(this.objects[i]);\n        }\n\n        if (this.nodes.length) {\n            const indices = this.getQuadrants(rect);\n            for (let i = 0; i < indices.length; i++) {\n                this.nodes[indices[i]].retrieve(rect, retrieveCb);\n            }\n        }\n    }\n\n    /**\n     * Removes the object\n     * @param obj - The object to remove\n     * @param fast - No node collapse if true\n     */\n    remove(obj: GameObj<AreaComp>, fast = false): boolean {\n        let index = this.objects.indexOf(obj);\n        if (index != -1) {\n            this.objects.splice(index, 1);\n            Quadtree.versionsForObject.delete(obj);\n            if (!fast) {\n                this.merge();\n            }\n            return true;\n        }\n\n        for (let i = 0; i < this.nodes.length; i++) {\n            if (this.nodes[i].remove(obj, fast)) {\n                if (!fast) {\n                    this.merge();\n                }\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Updates a single object\n     * Note that no testing is done here. Make sure the object needs to be actually updated.\n     * @param root - The tree root, since insertion happens from the root\n     * @param obj - The object to update\n     * @param bbox - The new bounding box\n     */\n    updateObject(root: Quadtree, obj: GameObj<AreaComp>, bbox: Rect): void {\n        this.remove(obj);\n        root.insert(obj, bbox);\n    }\n\n    /**\n     * True if the rectangle is completely outside this node's bounds\n     * @param bbox - The bounding box to test\n     */\n    isOutside(bbox: Rect) {\n        return bbox.pos.x + bbox.width < this.bounds.pos.x\n            || bbox.pos.y + bbox.height < this.bounds.pos.y\n            || bbox.pos.x > this.bounds.pos.x + this.bounds.width\n            || bbox.pos.y > this.bounds.pos.y + this.bounds.height;\n    }\n\n    /**\n     * True if the rectangle is completely outside this node's bounds\n     * @param bbox - The bounding box to test\n     */\n    isInside(bbox: Rect) {\n        return bbox.pos.x >= this.bounds.pos.x\n            && bbox.pos.y >= this.bounds.pos.y\n            && bbox.pos.x + bbox.width <= this.bounds.pos.x + this.bounds.width\n            && bbox.pos.y + bbox.height\n                <= this.bounds.pos.y + this.bounds.height;\n    }\n\n    /**\n     * Updates all objects in this node and the objects of its children\n     * @param root - The tree root, since insertion happens from the root\n     */\n    updateNode(orphans: [GameObj<AreaComp>, Rect][]) {\n        let i = 0;\n        while (i < this.objects.length) {\n            const obj = this.objects[i];\n            // Check if this world area changed since last frame\n            const versions = Quadtree.versionsForObject.get(obj);\n            if (\n                versions![0] === getTransformVersion(obj)\n                && versions![1] === getRenderAreaVersion(obj)\n                && versions![2] === getLocalAreaVersion(obj)\n            ) {\n                i++;\n                continue;\n            }\n\n            if (objectTransformNeedsUpdate(obj)) {\n                calcTransform(obj, obj.transform);\n            }\n            else {\n                versions![0] = getTransformVersion(obj);\n            }\n            versions![1] = getRenderAreaVersion(obj);\n            versions![2] = getLocalAreaVersion(obj);\n\n            const bbox = obj.worldBbox();\n            // If the object is outside the bounds, remove it and add it to the root later\n            if (!this.isInside(bbox)) {\n                orphans.push([obj, bbox]);\n                this.objects.splice(i, 1);\n                continue; // Don't increase i, the object at i was removed\n            }\n            else if (this.nodes.length > 0) {\n                // If the object fits in a quadrant, remove it and add it to the quadrant\n                const index = this.getQuadrant(bbox);\n                if (index !== -1) {\n                    // Use fast without merge, since it may remove the quadrant we are going to add it to\n                    this.nodes[index].insert(obj, bbox);\n                    this.objects.splice(i, 1);\n                    continue; // Don't increase i, the object at i was removed\n                }\n            }\n            i++;\n        }\n        // Update sub quadrants\n        for (let i = 0; i < this.nodes.length; i++) {\n            this.nodes[i].updateNode(orphans);\n        }\n    }\n\n    /**\n     * Update this tree\n     */\n    update() {\n        const orphans: [GameObj<AreaComp>, Rect][] = [];\n        this.updateNode(orphans);\n        // Reinsert all objects that were removed because they went outside the bounds of their quadrant\n        for (let i = 0; i < orphans.length; i++) {\n            this.insert(orphans[i][0], orphans[i][1]);\n        }\n    }\n\n    /**\n     * Clears this node and collapses it\n     */\n    clear() {\n        this.objects.length = 0;\n\n        // Do we need this? It only makes sense if someone is still holding a reference to a node\n        for (var i = 0; i < this.nodes.length; i++) {\n            this.nodes[i].clear();\n        }\n\n        this.nodes = [];\n    }\n\n    /**\n     * Gathers all collision pairs in this node and child nodes\n     * @param ancestorObjects - Objects in one of the node's ancestors\n     * @param pairs - The pairs being gathered\n     */\n    gatherPairs(\n        ancestorObjects: Array<GameObj<AreaComp>>,\n        pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void,\n    ) {\n        // The objects in this node potentially collide with each other\n        for (let i = 0; i < this.objects.length; i++) {\n            if (!isValidCollisionObject(this.objects[i])) continue;\n            // Note that we don't create doubles, since j = i + 1\n            for (let j = i + 1; j < this.objects.length; j++) {\n                if (isValidCollisionObject(this.objects[j])) {\n                    pairCb(this.objects[i], this.objects[j]);\n                }\n            }\n        }\n\n        // The objects in this node potentially collide with ancestor objects\n        for (let i = 0; i < this.objects.length; i++) {\n            if (!isValidCollisionObject(this.objects[i])) continue;\n            // Note that we don't create doubles, since the lists are disjoint\n            for (let j = 0; j < ancestorObjects.length; j++) {\n                if (isValidCollisionObject(ancestorObjects[j])) {\n                    pairCb(this.objects[i], ancestorObjects[j]);\n                }\n            }\n        }\n\n        // Check child nodes if any\n        if (this.nodes.length) {\n            // Add the local objects to the ancestors\n            ancestorObjects = ancestorObjects.concat(this.objects);\n            for (let i = 0; i < this.nodes.length; i++) {\n                this.nodes[i].gatherPairs(ancestorObjects, pairCb);\n            }\n        }\n    }\n\n    iterPairs(\n        pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void,\n    ): void {\n        this.gatherPairs([], pairCb);\n    }\n}\n\nexport class ResizingQuadtree implements BroadPhaseAlgorithm {\n    root: Quadtree;\n    constructor(\n        bounds: Rect,\n        maxObjects: number = 8,\n        maxLevels: number = 4,\n    ) {\n        this.root = new Quadtree(bounds, maxObjects, maxLevels, 0);\n    }\n\n    add(obj: GameObj<AreaComp>): void {\n        const increaseLevel = (node: Quadtree) => {\n            node.level++;\n            for (const n of node.nodes) {\n                increaseLevel(n);\n            }\n        };\n        const bbox = obj.worldBbox();\n        const isLeft = bbox.pos.x < this.root.bounds.pos.x;\n        // Note: Even though an object can be so large that it extends to the right as well, we prioritize left\n        const isRight = !isLeft\n            && bbox.pos.x + bbox.width\n                > this.root.bounds.pos.x + this.root.bounds.width;\n        const isCenter = !(isLeft || isRight);\n        const isTop = bbox.pos.y < this.root.bounds.pos.y;\n        // Note: Even though an object can be so large that it extends to the bottom as well, we prioritize top\n        const isBottom = !isTop\n            && bbox.pos.y + bbox.height\n                > this.root.bounds.pos.y + this.root.bounds.height;\n        const isMiddle = !(isTop || isBottom);\n        if (isTop && (isLeft || isCenter)) {\n            /**\n             * X X O => N N\n             * O O O    N O\n             * O O O\n             */\n            // New bounds\n            const bounds = new Rect(\n                this.root.bounds.pos.sub(\n                    this.root.bounds.width,\n                    this.root.bounds.height,\n                ),\n                this.root.bounds.width * 2,\n                this.root.bounds.height * 2,\n            );\n            // Create new root\n            const node = new Quadtree(\n                bounds,\n                this.root.maxObjects,\n                this.root.maxLevels,\n                0,\n            );\n            // Subdivide top level\n            node.subdivide();\n            // Replace bottom right node with old root\n            increaseLevel(this.root);\n            node.nodes[2] = this.root;\n            // Replace root with new node\n            this.root = node;\n\n            // Retry\n            return this.add(obj);\n        }\n        else if (isLeft && (isMiddle || isBottom)) {\n            /**\n             * O O O => N O\n             * X O O    N N\n             * X O O\n             */\n            // New bounds\n            const bounds = new Rect(\n                this.root.bounds.pos.sub(this.root.bounds.width, 0),\n                this.root.bounds.width * 2,\n                this.root.bounds.height * 2,\n            );\n            // Create new root\n            const node = new Quadtree(\n                bounds,\n                this.root.maxObjects,\n                this.root.maxLevels,\n                0,\n            );\n            // Subdivide top level\n            node.subdivide();\n            // Replace top right node with old root\n            increaseLevel(this.root);\n            node.nodes[1] = this.root;\n            // Replace root with new node\n            this.root = node;\n\n            // Retry\n            return this.add(obj);\n        }\n        else if (isRight && (isTop || isMiddle)) {\n            /**\n             * O O X => N N\n             * O O X    O N\n             * O O O\n             */\n            // New bounds\n            const bounds = new Rect(\n                this.root.bounds.pos.sub(0, this.root.bounds.height),\n                this.root.bounds.width * 2,\n                this.root.bounds.height * 2,\n            );\n            // Create new root\n            const node = new Quadtree(\n                bounds,\n                this.root.maxObjects,\n                this.root.maxLevels,\n                0,\n            );\n            // Subdivide top level\n            node.subdivide();\n            // Replace bottom left node with old root\n            increaseLevel(this.root);\n            node.nodes[3] = this.root;\n            // Replace root with new node\n            this.root = node;\n\n            // Retry\n            return this.add(obj);\n        }\n        else if (isBottom && (isCenter || isRight)) {\n            /**\n             * O O O => O N\n             * O O O    N N\n             * O X X\n             */\n            // New bounds\n            const bounds = new Rect(\n                this.root.bounds.pos,\n                this.root.bounds.width * 2,\n                this.root.bounds.height * 2,\n            );\n            // Create new root\n            const node = new Quadtree(\n                bounds,\n                this.root.maxObjects,\n                this.root.maxLevels,\n                0,\n            );\n            // Subdivide top level\n            node.subdivide();\n            // Replace bottom left node with old root\n            increaseLevel(this.root);\n            node.nodes[0] = this.root;\n            // Replace root with new node\n            this.root = node;\n\n            // Retry\n            return this.add(obj);\n        }\n        else {\n            this.root.insert(obj, bbox);\n        }\n    }\n\n    remove(obj: GameObj<AreaComp>): void {\n        this.root.remove(obj);\n        // TODO: If it can shrink, shrink. Not the best idea though, as this can oscillate\n    }\n\n    clear(): void {\n        this.root.clear();\n    }\n\n    update(): void {\n        const orphans: [GameObj<AreaComp>, Rect][] = [];\n        this.root.updateNode(orphans);\n        // Reinsert all objects that were removed because they went outside the bounds of their quadrant\n        for (let i = 0; i < orphans.length; i++) {\n            this.add(orphans[i][0]);\n        }\n    }\n\n    iterPairs(\n        pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void,\n    ): void {\n        this.root.iterPairs(pairCb);\n    }\n\n    get bounds() {\n        return this.root.bounds;\n    }\n\n    get nodes() {\n        return this.root.nodes;\n    }\n\n    retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void) {\n        return this.root.retrieve(rect, retrieveCb);\n    }\n}\n\nexport function makeQuadtree(\n    pos: Vec2,\n    width: number,\n    height: number,\n    maxObjects: number = 8,\n    maxLevels: number = 4,\n    resizing: boolean = false,\n) {\n    if (resizing) {\n        return new ResizingQuadtree(\n            new Rect(pos, width, height),\n            maxObjects,\n            maxLevels,\n        );\n    }\n    else {\n        return new Quadtree(\n            new Rect(pos, width, height),\n            maxObjects,\n            maxLevels,\n            0,\n        );\n    }\n}\n\nfunction isValidCollisionObject(obj: GameObj) {\n    return exists(obj) && (obj.isSensor || obj.has(\"body\")) && !isPaused(obj);\n}\n\nexport class BaseQuadtree<T> {\n    bounds: Rect;\n    maxObjects: number;\n    maxLevels: number;\n    level: number;\n    nodes: BaseQuadtree<T>[];\n    objects: T[];\n\n    /**\n     * Creates a new quadtree\n     * @param bounds - The bounds of this node.\n     * @param maxObjects - The maximum amount of objects before triggering a split.\n     * @param maxLevels - The maximum amount of levels before no more splits are made.\n     * @param level - The current level.\n     */\n    constructor(\n        bounds: Rect,\n        maxObjects: number = 8,\n        maxLevels: number = 4,\n        level: number = 0,\n    ) {\n        this.bounds = bounds;\n        this.maxObjects = maxObjects;\n        this.maxLevels = maxLevels;\n        this.level = level;\n        this.nodes = []; // lt, rt, rb, lb\n        this.objects = [];\n    }\n\n    /**\n     * True if this node is a leaf node.\n     */\n    get isLeaf() {\n        return this.nodes.length === 0;\n    }\n\n    /**\n     * Splits the node, but doesn't redistribute objects\n     */\n    subdivide() {\n        const level = this.level + 1;\n        const width = this.bounds.width / 2;\n        const height = this.bounds.height / 2;\n        const x = this.bounds.pos.x;\n        const y = this.bounds.pos.y;\n\n        const pos = [\n            vec2(x, y),\n            vec2(x + width, y),\n            vec2(x + width, y + height),\n            vec2(x, y + height),\n        ];\n\n        for (let i = 0; i < 4; i++) {\n            this.nodes[i] = new BaseQuadtree<T>(\n                new Rect(pos[i], width, height),\n                this.maxObjects,\n                this.maxLevels,\n                level,\n            );\n        }\n    }\n\n    /**\n     * Tries to merge and collapse nodes which are no longer overpopulated.\n     */\n    merge() {\n        if (this.nodes.length > 0) {\n            let count = this.objects.length;\n            let allLeaves = true;\n            for (let i = 0; i < 4; i++) {\n                this.nodes[i].merge();\n                allLeaves &&= this.nodes[i].isLeaf;\n                count += this.nodes[i].objects.length;\n            }\n\n            if (allLeaves && count <= this.maxObjects) {\n                for (let i = 0; i < 4; i++) {\n                    this.objects.push(...this.nodes[i].objects);\n                }\n                this.nodes = [];\n            }\n        }\n    }\n\n    /**\n     * Returns the quadrant this rect fits in or -1 if it doesn't fit any quadrant\n     * @param rect - The rect to test with.\n     *\n     * @returns The index of the quadrant fitting the rect completely, or -1 if none.\n     */\n    getQuadrant(rect: Rect) {\n        const boundsCenterX = this.bounds.pos.x + (this.bounds.width / 2);\n        const boundsCenterY = this.bounds.pos.y + (this.bounds.height / 2);\n        // Left - If the right side is left of the center\n        if (rect.pos.x + rect.width < boundsCenterX) {\n            // Top Left - If the bottom side is above the center\n            if (rect.pos.y + rect.height < boundsCenterY) {\n                return 0;\n            }\n            // Bottom Left - If the top side is below the center\n            else if (rect.pos.y >= boundsCenterY) {\n                return 3;\n            }\n        }\n        // Right - If the left side is right of the center\n        else if (rect.pos.x >= boundsCenterX) {\n            // Top Right - If the bottom side is above the center\n            if (rect.pos.y + rect.height < boundsCenterY) {\n                return 1;\n            }\n            // Bottom Right - If the top side is below the center\n            else if (rect.pos.y >= boundsCenterY) {\n                return 2;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Returns the quadrants this rect intersects\n     * @param rect - The rect to test with. Note that this rect is assumed to be within the node.\n     *\n     * @returns the list of quadrant indices\n     */\n    getQuadrants(rect: Rect): number[] {\n        const boundsCenterX = this.bounds.pos.x + (this.bounds.width / 2);\n        const boundsCenterY = this.bounds.pos.y + (this.bounds.height / 2);\n        const quadrants: number[] = [];\n\n        // Left - The left side is left of the center\n        if (rect.pos.x < boundsCenterX) {\n            // Top Left - If the top side is above the center\n            if (rect.pos.y < boundsCenterY) {\n                quadrants.push(0);\n            }\n            // Bottom Left - If the bottom side is below the center\n            if (rect.pos.y + rect.height > boundsCenterY) {\n                quadrants.push(3);\n            }\n        }\n        // Right - If the right side is right of the center\n        if (rect.pos.x + rect.width > boundsCenterX) {\n            // Top Right - If the top side is above the center\n            if (rect.pos.y < boundsCenterY) {\n                quadrants.push(1);\n            }\n            // Bottom Right - If the bottom side is below the center\n            if (rect.pos.y + rect.height > boundsCenterY) {\n                quadrants.push(2);\n            }\n        }\n        return quadrants;\n    }\n\n    /**\n     * Inserts the object with the given rectangle\n     * @param obj - The object to add\n     * @param bbox - The bounding box of the object\n     */\n    insert(obj: T, bbox: Rect): void {\n        // If we reached max objects, subdivide and redistribute\n        if (this.objects.length >= this.maxObjects) {\n            if (this.nodes.length === 0 && this.level < this.maxLevels) {\n                this.subdivide();\n                // Redistribute objects\n                let j = 0;\n                for (let i = 0; i < this.objects.length; i++) {\n                    const obj = this.objects[i];\n                    const index = this.getQuadrant(bbox);\n                    if (index !== -1) {\n                        this.nodes[index].insert(obj, bbox);\n                    }\n                    else {\n                        this.objects[j++] = obj;\n                    }\n                }\n                this.objects.length = j;\n            }\n        }\n\n        // Check if the object fits in a smaller quadrant\n        if (this.nodes.length) {\n            const index = this.getQuadrant(bbox);\n\n            if (index !== -1) {\n                this.nodes[index].insert(obj, bbox);\n                return;\n            }\n        }\n\n        this.objects.push(obj);\n    }\n\n    /**\n     * Retrieves all objects potentially intersecting the rectangle\n     * @param rect - The rect to test with\n     *\n     * @returns A set of objects potentially intersecting the rectangle\n     */\n    retrieve(rect: Rect, retrieveCb: (obj: T) => void): void {\n        for (let i = 0; i < this.objects.length; i++) {\n            retrieveCb(this.objects[i]);\n        }\n\n        if (this.nodes.length) {\n            const indices = this.getQuadrants(rect);\n            for (let i = 0; i < indices.length; i++) {\n                this.nodes[indices[i]].retrieve(rect, retrieveCb);\n            }\n        }\n    }\n\n    /**\n     * Removes the object\n     * @param obj - The object to remove\n     * @param fast - No node collapse if true\n     */\n    remove(obj: T, fast = false): boolean {\n        let index = this.objects.indexOf(obj);\n        if (index != -1) {\n            this.objects.splice(index, 1);\n            if (!fast) {\n                this.merge();\n            }\n            return true;\n        }\n\n        for (let i = 0; i < this.nodes.length; i++) {\n            if (this.nodes[i].remove(obj, fast)) {\n                if (!fast) {\n                    this.merge();\n                }\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Updates a single object\n     * Note that no testing is done here. Make sure the object needs to be actually updated.\n     * @param obj - The object to update\n     * @param bbox - The new bounding box\n     */\n    updateObject(obj: T, bbox: Rect, fast?: boolean): void {\n        this.remove(obj, fast);\n        this.insert(obj, bbox);\n    }\n\n    /**\n     * True if the rectangle is completely outside this node's bounds\n     * @param bbox - The bounding box to test\n     */\n    isOutside(bbox: Rect) {\n        return bbox.pos.x + bbox.width < this.bounds.pos.x\n            || bbox.pos.y + bbox.height < this.bounds.pos.y\n            || bbox.pos.x > this.bounds.pos.x + this.bounds.width\n            || bbox.pos.y > this.bounds.pos.y + this.bounds.height;\n    }\n\n    /**\n     * True if the rectangle is completely outside this node's bounds\n     * @param bbox - The bounding box to test\n     */\n    isInside(bbox: Rect) {\n        return bbox.pos.x >= this.bounds.pos.x\n            && bbox.pos.y >= this.bounds.pos.y\n            && bbox.pos.x + bbox.width <= this.bounds.pos.x + this.bounds.width\n            && bbox.pos.y + bbox.height\n                <= this.bounds.pos.y + this.bounds.height;\n    }\n\n    /**\n     * Clears this node and collapses it\n     */\n    clear() {\n        this.objects.length = 0;\n\n        // Do we need this? It only makes sense if someone is still holding a reference to a node\n        for (var i = 0; i < this.nodes.length; i++) {\n            this.nodes[i].clear();\n        }\n\n        this.nodes = [];\n    }\n\n    /**\n     * Gathers all collision pairs in this node and child nodes\n     * @param ancestorObjects - Objects in one of the node's ancestors\n     * @param pairs - The pairs being gathered\n     */\n    gatherPairs(\n        ancestorObjects: Array<T>,\n        pairCb: (obj1: T, obj2: T) => void,\n    ) {\n        // The objects in this node potentially collide with each other\n        for (let i = 0; i < this.objects.length; i++) {\n            // Note that we don't create doubles, since j = i + 1\n            for (let j = i + 1; j < this.objects.length; j++) {\n                pairCb(this.objects[i], this.objects[j]);\n            }\n        }\n\n        // The objects in this node potentially collide with ancestor objects\n        for (let i = 0; i < this.objects.length; i++) {\n            // Note that we don't create doubles, since the lists are disjoint\n            for (let j = 0; j < ancestorObjects.length; j++) {\n                pairCb(this.objects[i], ancestorObjects[j]);\n            }\n        }\n\n        // Check child nodes if any\n        if (this.nodes.length) {\n            // Add the local objects to the ancestors\n            ancestorObjects = ancestorObjects.concat(this.objects);\n            for (let i = 0; i < this.nodes.length; i++) {\n                this.nodes[i].gatherPairs(ancestorObjects, pairCb);\n            }\n        }\n    }\n\n    iterPairs(\n        pairCb: (obj1: T, obj2: T) => void,\n    ): void {\n        this.gatherPairs([], pairCb);\n    }\n}\n", "import { _k } from \"../shared\";\nimport type { KAPLAYPlugin } from \"../types\";\nimport type { KAPLAYCtx } from \"./contextType\";\n\nexport const plug = <T extends Record<string, any>>(\n    plugin: KAPLAYPlugin<T>,\n    ...args: any\n): KAPLAYCtx & T => {\n    const funcs = plugin(_k.k);\n    let funcsObj: T;\n    if (typeof funcs === \"function\") {\n        const plugWithOptions = funcs(...args);\n        funcsObj = plugWithOptions(_k.k);\n    }\n    else {\n        funcsObj = funcs;\n    }\n\n    for (const key in funcsObj) {\n        _k.k[key as keyof typeof _k.k] = funcsObj[key];\n\n        if (_k.globalOpt.global !== false) {\n            window[key as any] = funcsObj[key];\n        }\n    }\n\n    return _k.k as unknown as KAPLAYCtx & T;\n};\n", "import { _k } from \"../shared\";\n\nexport const quit = () => {\n    const { app, gfx, ggl, gc } = _k;\n\n    app.events.onOnce(\"frameEnd\", () => {\n        app.quit();\n\n        // clear canvas\n        gfx.gl.clear(\n            gfx.gl.COLOR_BUFFER_BIT | gfx.gl.DEPTH_BUFFER_BIT\n                | gfx.gl.STENCIL_BUFFER_BIT,\n        );\n\n        // unbind everything\n        const numTextureUnits = gfx.gl.getParameter(\n            gfx.gl.MAX_TEXTURE_IMAGE_UNITS,\n        );\n\n        for (let unit = 0; unit < numTextureUnits; unit++) {\n            gfx.gl.activeTexture(gfx.gl.TEXTURE0 + unit);\n            gfx.gl.bindTexture(gfx.gl.TEXTURE_2D, null);\n            gfx.gl.bindTexture(gfx.gl.TEXTURE_CUBE_MAP, null);\n        }\n\n        gfx.gl.bindBuffer(gfx.gl.ARRAY_BUFFER, null);\n        gfx.gl.bindBuffer(gfx.gl.ELEMENT_ARRAY_BUFFER, null);\n        gfx.gl.bindRenderbuffer(gfx.gl.RENDERBUFFER, null);\n        gfx.gl.bindFramebuffer(gfx.gl.FRAMEBUFFER, null);\n\n        // run all scattered gc events\n        ggl.destroy();\n        gc.forEach((f) => f());\n\n        // remove canvas\n        app.canvas.remove();\n    });\n};\n\nexport const onCleanup = (action: () => void) => {\n    _k.gc.push(action);\n};\n", "import { trigger } from \"../api/eventHandlers\";\nimport { getData, setData } from \"../app/data\";\nimport { loadAseprite } from \"../assets/aseprite\";\nimport {\n    Asset,\n    getAsset,\n    load,\n    loadJSON,\n    loadProgress,\n    loadRoot,\n} from \"../assets/asset\";\nimport {\n    getBitmapFont,\n    loadBitmapFont,\n    loadBitmapFontFromSprite,\n    loadHappy,\n} from \"../assets/bitmapFont\";\nimport { getFont, loadFont } from \"../assets/font\";\nimport { getShader, loadShader, loadShaderURL } from \"../assets/shader\";\nimport { getSound, loadMusic, loadSound, SoundData } from \"../assets/sound\";\nimport { getSprite, loadBean, loadSprite, SpriteData } from \"../assets/sprite\";\nimport { loadSpriteAtlas } from \"../assets/spriteAtlas\";\nimport { burp } from \"../audio/burp\";\nimport { play } from \"../audio/play\";\nimport { getVolume, setVolume, volume } from \"../audio/volume\";\nimport { ASCII_CHARS, EVENT_CANCEL_SYMBOL } from \"../constants/general\";\nimport { record } from \"../debug/record\";\nimport { blend } from \"../ecs/components/draw/blend\";\nimport { circle } from \"../ecs/components/draw/circle\";\nimport { color } from \"../ecs/components/draw/color\";\nimport { drawon } from \"../ecs/components/draw/drawon\";\nimport { ellipse } from \"../ecs/components/draw/ellipse\";\nimport { fadeIn } from \"../ecs/components/draw/fadeIn\";\nimport { fill } from \"../ecs/components/draw/fill\";\nimport { mask } from \"../ecs/components/draw/mask\";\nimport { opacity } from \"../ecs/components/draw/opacity\";\nimport { outline } from \"../ecs/components/draw/outline\";\nimport { particles } from \"../ecs/components/draw/particles\";\nimport { picture } from \"../ecs/components/draw/picture\";\nimport { polygon } from \"../ecs/components/draw/polygon\";\nimport { raycast } from \"../ecs/components/draw/raycast\";\nimport { rect } from \"../ecs/components/draw/rect\";\nimport { shader } from \"../ecs/components/draw/shader\";\nimport { sprite } from \"../ecs/components/draw/sprite\";\nimport { text } from \"../ecs/components/draw/text\";\nimport { uvquad } from \"../ecs/components/draw/uvquad\";\nimport { video } from \"../ecs/components/draw/video\";\nimport { agent } from \"../ecs/components/level/agent\";\nimport { level } from \"../ecs/components/level/level\";\nimport { pathfinder } from \"../ecs/components/level/pathfinder\";\nimport { patrol } from \"../ecs/components/level/patrol\";\nimport { sentry } from \"../ecs/components/level/sentry\";\nimport { tile } from \"../ecs/components/level/tile\";\nimport { animate, serializeAnimation } from \"../ecs/components/misc/animate\";\nimport { fakeMouse } from \"../ecs/components/misc/fakeMouse\";\nimport { health } from \"../ecs/components/misc/health\";\nimport { lifespan } from \"../ecs/components/misc/lifespan\";\nimport { named } from \"../ecs/components/misc/named\";\nimport { state } from \"../ecs/components/misc/state\";\nimport { stay } from \"../ecs/components/misc/stay\";\nimport { textInput } from \"../ecs/components/misc/textInput\";\nimport { timer } from \"../ecs/components/misc/timer\";\nimport { area } from \"../ecs/components/physics/area\";\nimport { body } from \"../ecs/components/physics/body\";\nimport { doubleJump } from \"../ecs/components/physics/doubleJump\";\nimport {\n    areaEffector,\n    buoyancyEffector,\n    constantForce,\n    platformEffector,\n    pointEffector,\n    surfaceEffector,\n} from \"../ecs/components/physics/effectors\";\nimport { anchor } from \"../ecs/components/transform/anchor\";\nimport { constraint } from \"../ecs/components/transform/constraint\";\nimport { fixed } from \"../ecs/components/transform/fixed\";\nimport { follow } from \"../ecs/components/transform/follow\";\nimport { layer } from \"../ecs/components/transform/layer\";\nimport { move } from \"../ecs/components/transform/move\";\nimport { offscreen } from \"../ecs/components/transform/offscreen\";\nimport { pos } from \"../ecs/components/transform/pos\";\nimport { rotate } from \"../ecs/components/transform/rotate\";\nimport { scale } from \"../ecs/components/transform/scale\";\nimport { skew } from \"../ecs/components/transform/skew\";\nimport { z } from \"../ecs/components/transform/z\";\nimport { KeepFlags } from \"../ecs/entity/GameObjRaw\";\nimport { createPrefab, loadPrefab } from \"../ecs/entity/prefab\";\nimport { addKaboom } from \"../ecs/entity/premade/addKaboom\";\nimport { addLevel } from \"../ecs/entity/premade/addLevel\";\nimport { destroy, exists, getTreeRoot } from \"../ecs/entity/utils\";\nimport { Collision } from \"../ecs/systems/Collision\";\nimport { system, SystemPhase } from \"../ecs/systems/systems\";\nimport { KEvent, KEventController, KEventHandler } from \"../events/events\";\nimport {\n    camFlash,\n    camPos,\n    camRot,\n    camScale,\n    camTransform,\n    flash,\n    getCamPos,\n    getCamRot,\n    getCamScale,\n    getCamTransform,\n    setCamPos,\n    setCamRot,\n    setCamScale,\n    shake,\n    toScreen,\n    toWorld,\n} from \"../game/camera\";\nimport {\n    getGravity,\n    getGravityDirection,\n    setGravity,\n    setGravityDirection,\n} from \"../game/gravity\";\nimport { getDefaultLayer, getLayers, layers, setLayers } from \"../game/layers\";\nimport { getSceneName, go, popScene, pushScene } from \"../game/scenes\";\nimport { anchorPt } from \"../gfx/anchor\";\nimport { getBackground, setBackground } from \"../gfx/bg\";\nimport { makeCanvas } from \"../gfx/canvasBuffer\";\nimport { drawBezier } from \"../gfx/draw/drawBezier\";\nimport { drawCanvas } from \"../gfx/draw/drawCanvas\";\nimport { drawCircle } from \"../gfx/draw/drawCircle\";\nimport { drawCurve } from \"../gfx/draw/drawCurve\";\nimport { drawEllipse } from \"../gfx/draw/drawEllipse\";\nimport { drawFormattedText } from \"../gfx/draw/drawFormattedText\";\nimport { drawLine, drawLines } from \"../gfx/draw/drawLine\";\nimport { drawMasked } from \"../gfx/draw/drawMasked\";\nimport {\n    appendToPicture,\n    beginPicture,\n    drawPicture,\n    endPicture,\n    Picture,\n} from \"../gfx/draw/drawPicture\";\nimport { drawPolygon } from \"../gfx/draw/drawPolygon\";\nimport { drawRect } from \"../gfx/draw/drawRect\";\nimport { drawSprite } from \"../gfx/draw/drawSprite\";\nimport { drawSubtracted } from \"../gfx/draw/drawSubtracted\";\nimport { drawText } from \"../gfx/draw/drawText\";\nimport { drawTriangle } from \"../gfx/draw/drawTriangle\";\nimport { drawUVQuad } from \"../gfx/draw/drawUVQuad\";\nimport { compileStyledText, formatText } from \"../gfx/formatText\";\nimport {\n    center,\n    height,\n    loadMatrix,\n    multRotate,\n    multScaleV,\n    multTranslateV,\n    popTransform,\n    pushTransform,\n    usePostEffect,\n    width,\n} from \"../gfx/stack\";\nimport { DecisionNode, DecisionTree } from \"../math/ai/decisiontree\";\nimport { Rule, RuleSystem } from \"../math/ai/rulesystem\";\nimport { StateMachine } from \"../math/ai/statemachine\";\nimport { clamp } from \"../math/clamp\";\nimport { Color, hsl2rgb, rgb } from \"../math/color\";\nimport { buildConvexHull } from \"../math/convexhull\";\nimport { easings } from \"../math/easings\";\nimport { gjkShapeIntersection, gjkShapeIntersects } from \"../math/gjk\";\nimport { lerp } from \"../math/lerp\";\nimport { lerpAngle } from \"../math/lerpAngle\";\nimport { Mat4 } from \"../math/Mat4\";\nimport {\n    bezier,\n    cardinal,\n    catmullRom,\n    chance,\n    choose,\n    chooseMultiple,\n    Circle,\n    clipLineToCircle,\n    clipLineToRect,\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    getSpriteOutline,\n    hermite,\n    isConvex,\n    kochanekBartels,\n    Line,\n    map,\n    mapc,\n    Mat2,\n    Mat23,\n    normalizedCurve,\n    piecewiseBezier,\n    piecewiseCatmullRom,\n    Point,\n    Polygon,\n    Quad,\n    quad,\n    rad2deg,\n    rand,\n    randi,\n    randSeed,\n    Rect,\n    RNG,\n    shuffle,\n    smoothstep,\n    step,\n    testCirclePolygon,\n    testLineCircle,\n    testLineLine,\n    testLinePoint,\n    testRectLine,\n    testRectPoint,\n    testRectRect,\n    triangulate,\n    vec2,\n    wave,\n} from \"../math/math\";\nimport { buildConnectivityMap, floodFill } from \"../math/navigation\";\nimport { NavGrid } from \"../math/navigationgrid\";\nimport { NavMesh } from \"../math/navigationmesh\";\nimport {\n    createCogPolygon,\n    createRegularPolygon,\n    createStarPolygon,\n} from \"../math/polygongeneration\";\nimport { insertionSort } from \"../math/sort\";\nimport { makeQuadtree, Quadtree } from \"../math/spatial/quadtree\";\nimport { Vec2 } from \"../math/Vec2\";\nimport { BlendMode, type KAPLAYPlugin } from \"../types\";\nimport {\n    download,\n    downloadBlob,\n    downloadJSON,\n    downloadText,\n} from \"../utils/dataURL\";\nimport type { KAPLAYCtx } from \"./contextType\";\nimport type { Engine } from \"./engine\";\nimport { throwError } from \"./errors\";\nimport { plug } from \"./plug\";\nimport { quit } from \"./quit\";\n\n// The context is the way the user interact with a KAPLAY game.\nexport const createContext = (\n    e: Engine,\n    plugins?: KAPLAYPlugin<Record<string, unknown>>[],\n    exportToGlobal?: boolean,\n): KAPLAYCtx => {\n    // aliases for root Game Obj operations\n    const { game, app, audio, debug, globalOpt } = e;\n    const add = game.root.add.bind(game.root);\n    const addPrefab = game.root.addPrefab.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 defaultScope = globalOpt.defaultLifetimeScope == \"app\"\n        ? e.appScope\n        : e.sceneScope;\n\n    const ctx: KAPLAYCtx = {\n        _k: e,\n        // @ts-ignore\n        VERSION: KAPLAY_VERSION,\n        // asset load\n        loadRoot,\n        loadProgress,\n        loadSprite,\n        loadSpriteAtlas,\n        loadSound,\n        loadMusic,\n        loadBitmapFont,\n        loadFont,\n        loadBitmapFontFromSprite,\n        loadShader,\n        loadShaderURL,\n        loadAseprite,\n        loadBean,\n        loadHappy,\n        loadJSON,\n        loadPrefab,\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: app.dt,\n        fixedDt: app.fixedDt,\n        restDt: app.restDt,\n        setFixedSpeed: app.setFixedSpeed,\n        time: app.time,\n        screenshot: app.screenshot,\n        screenshotToBlob: app.screenshotToBlob,\n        record,\n        isFocused: app.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: defaultScope.onLoad,\n        onLoadError: defaultScope.onLoadError,\n        onLoading: defaultScope.onLoading,\n        onResize: defaultScope.onResize,\n        onGamepadConnect: defaultScope.onGamepadConnect,\n        onGamepadDisconnect: defaultScope.onGamepadDisconnect,\n        onError: defaultScope.onError,\n        onCleanup: defaultScope.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        addPrefab,\n        createPrefab,\n        exists,\n        destroy,\n        destroyAll,\n        get,\n        query,\n        readd,\n        retrieve: (...args) => game.retrieve(...args),\n        // comps\n        pos,\n        rotate,\n        scale,\n        skew,\n        color,\n        blend,\n        opacity,\n        fill,\n        anchor,\n        area,\n        sprite,\n        text,\n        polygon,\n        rect,\n        circle,\n        ellipse,\n        uvquad,\n        video,\n        picture,\n        outline,\n        particles,\n        body,\n        surfaceEffector,\n        areaEffector,\n        pointEffector,\n        buoyancyEffector,\n        platformEffector,\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        constraint,\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        level,\n        fakeMouse,\n        // group events\n        trigger,\n        on: defaultScope.on,\n        onFixedUpdate: defaultScope.onFixedUpdate,\n        onUpdate: defaultScope.onUpdate,\n        onDraw: defaultScope.onDraw,\n        onAdd: defaultScope.onAdd,\n        onDestroy: defaultScope.onDestroy,\n        onUse: defaultScope.onUse,\n        onUnuse: defaultScope.onUnuse,\n        onTag: defaultScope.onTag,\n        onUntag: defaultScope.onUntag,\n        onClick: defaultScope.onClick,\n        onCollide: defaultScope.onCollide,\n        onCollideUpdate: defaultScope.onCollideUpdate,\n        onCollideEnd: defaultScope.onCollideEnd,\n        onHover: defaultScope.onHover,\n        onHoverUpdate: defaultScope.onHoverUpdate,\n        onHoverEnd: defaultScope.onHoverEnd,\n        onKeyDown: defaultScope.onKeyDown,\n        onKeyPress: defaultScope.onKeyPress,\n        onKeyPressRepeat: defaultScope.onKeyPressRepeat,\n        onKeyRelease: defaultScope.onKeyRelease,\n        onMouseDown: defaultScope.onMouseDown,\n        onMousePress: defaultScope.onMousePress,\n        onMouseRelease: defaultScope.onMouseRelease,\n        onMouseMove: defaultScope.onMouseMove,\n        onCharInput: defaultScope.onCharInput,\n        onTouchStart: defaultScope.onTouchStart,\n        onTouchMove: defaultScope.onTouchMove,\n        onTouchEnd: defaultScope.onTouchEnd,\n        onScroll: defaultScope.onScroll,\n        onHide: defaultScope.onHide,\n        onShow: defaultScope.onShow,\n        onTabShow: defaultScope.onTabShow,\n        onTabHide: defaultScope.onTabHide,\n        onGamepadButtonDown: defaultScope.onGamepadButtonDown,\n        onGamepadButtonPress: defaultScope.onGamepadButtonPress,\n        onGamepadButtonRelease: defaultScope.onGamepadButtonRelease,\n        onGamepadStick: defaultScope.onGamepadStick,\n        onButtonPress: defaultScope.onButtonPress,\n        onButtonDown: defaultScope.onButtonDown,\n        onButtonRelease: defaultScope.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        getGamepadAnalogButton: app.getGamepadAnalogButton,\n        isButtonPressed: app.isButtonPressed,\n        isButtonDown: app.isButtonDown,\n        isButtonReleased: app.isButtonReleased,\n        getButton: app.getButton,\n        getButtons: app.getButtons,\n        setButton: app.setButton,\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        Collision,\n        Vec2,\n        Color,\n        Mat2,\n        Mat4,\n        Mat23,\n        Quad,\n        Quadtree,\n        makeQuadtree,\n        RNG,\n        Rule,\n        RuleSystem,\n        DecisionNode,\n        DecisionTree,\n        StateMachine,\n        getSpriteOutline,\n        insertionSort,\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        lerpAngle,\n        step,\n        smoothstep,\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        piecewiseBezier,\n        piecewiseCatmullRom,\n        createRegularPolygon,\n        createStarPolygon,\n        createCogPolygon,\n        floodFill,\n        buildConnectivityMap,\n        easingSteps,\n        easingLinear,\n        easingCubicBezier,\n        testLineLine,\n        testRectRect,\n        testRectLine,\n        testRectPoint,\n        testCirclePolygon,\n        testLinePoint,\n        testLineCircle,\n        clipLineToRect,\n        clipLineToCircle,\n        anchorToVec2: anchorPt,\n        gjkShapeIntersects,\n        gjkShapeIntersection,\n        isConvex,\n        triangulate,\n        buildConvexHull,\n        NavMesh,\n        NavGrid,\n        // raw draw\n        drawSprite,\n        drawText,\n        formatText,\n        compileStyledText,\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        beginPicture,\n        appendToPicture,\n        endPicture,\n        drawPicture,\n        pushTransform,\n        popTransform,\n        pushTranslate: multTranslateV,\n        pushScale: multScaleV,\n        pushRotate: multRotate,\n        pushMatrix: loadMatrix,\n        usePostEffect,\n        makeCanvas,\n        drawCanvas,\n        Picture,\n        // debug\n        debug,\n        app: e.appScope,\n        // scene\n        scene: e.sceneScope,\n        getSceneName,\n        go,\n        onSceneLeave: defaultScope.onSceneLeave,\n        pushScene,\n        popScene,\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        system,\n        SystemPhase,\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        throwError,\n        // helpers\n        KEvent,\n        KEventHandler,\n        KEventController,\n        KeepFlags,\n        cancel: () => EVENT_CANCEL_SYMBOL,\n        BlendMode,\n    };\n\n    // Export context to Engine\n    e.k = ctx;\n\n    if (plugins) {\n        plugins.forEach(plug);\n    }\n\n    if (exportToGlobal) {\n        for (const key in ctx) {\n            ((window as any)[key]) = ctx[key as keyof KAPLAYCtx];\n        }\n    }\n\n    return ctx;\n};\n", "import { Vec2 } from \"../math/Vec2\";\nimport { _k } from \"../shared\";\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.gfx.pixelDensity;\n    const desiredWidth = _k.globalOpt.width;\n    const desiredHeight = _k.globalOpt.height;\n    const drawingBufferWidth = _k.gfx.gl.drawingBufferWidth;\n    const drawingBufferHeight = _k.gfx.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    _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    // console.log(\"[vwp] viewport is\", _k.gfx.viewport);\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", "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", "import { _k } from \"../shared\";\nimport type { ButtonBinding } from \"./inputBindings\";\n\n// Getting / Setting bindings\n\nexport const getButtons = () => {\n    return _k.app.state.buttons;\n};\n\nexport const getButton = (btn: string): ButtonBinding => {\n    return _k.app.state.buttons?.[btn];\n};\n\nexport const setButton = (btn: string, binding: ButtonBinding) => {\n    _k.app.state.buttons[btn] = {\n        ..._k.app.state.buttons[btn],\n        ...binding,\n    };\n    _k.app.state.buttonHandler.updateBinding(btn, binding);\n};\n\n// Virtually pressing / releasing\n\nexport const pressButton = (btn: string) => {\n    _k.app.state.buttonHandler.state.press(btn, _k.app.state);\n};\n\nexport const releaseButton = (btn: string) => {\n    _k.app.state.buttonHandler.state.release(btn, _k.app.state);\n};\n", "import type {\n    ChordedKey,\n    ChordedKGamepadButton,\n    ChordedMouseButton,\n    Key,\n    KGamepadButton,\n    MouseButton,\n} from \"../types\";\nimport { type AppState, ButtonState } from \"./app\";\n\n/**\n * A button binding.\n *\n * @group Input\n * @subgroup Buttons API\n */\nexport type ButtonBinding = {\n    keyboard?: ChordedKey | ChordedKey[];\n    keyboardCode?: string | string[];\n    gamepad?: ChordedKGamepadButton | ChordedKGamepadButton[];\n    mouse?: ChordedMouseButton | ChordedMouseButton[];\n};\n\n/**\n * A buttons definition for an action (jump, walk-left, run).\n *\n * @group Input\n * @subgroup Buttons API\n */\nexport type ButtonsDef = Record<string, ButtonBinding>;\n\n/**\n * A button binding device\n *\n * @group Input\n * @subgroup Buttons API\n */\nexport type ButtonBindingDevice = \"keyboard\" | \"gamepad\" | \"mouse\";\n\n// pass the user `buttons` definition to different keymaps\nexport const parseButtonBindings = (appState: AppState) => {\n    const btns = appState.buttons;\n\n    for (const b in btns) {\n        appState.buttonHandler.updateBinding(b, btns[b]);\n    }\n};\n\nfunction splitButtons<T extends string>(b: T): T[] {\n    // this is only to handle the special case of \"+\" being used as both the button and a splitter\n    // \"+\".split(\"+\") --> [\"\", \"\"]\n    // in all practicality \"+\" can only be a real key once so \"\", \"\" should only appear once\n    // we process it as many times as it appears to be consistent\n    const out = b.split(\"+\") as T[];\n    for (var i = 0; i < out.length; i++) {\n        if (out[i] === \"\" && out[i + 1] === \"\") {\n            out.splice(i, 2, \"+\" as T);\n            i--;\n        }\n    }\n    return out;\n}\n\nclass ChordedButtonDetector<T extends string = string> {\n    // map of mod key --> down state\n    mods = new Map<T, boolean>();\n    // map of commit key --> checkers for this commit key\n    committers = new Map<T, { check: Set<T>; btns: Map<string, T[]> }>();\n    buttonsUsed = new Set<string>();\n    updateBinding(button: string, bindings: T[]) {\n        // clear out old binding\n        const modsToClear = new Set<T>();\n        for (let { check, btns } of this.committers.values()) {\n            btns.get(button)?.forEach(b =>\n                check.delete(b) && modsToClear.add(b)\n            );\n            btns.delete(button);\n        }\n        // install new one\n        for (let b of bindings) {\n            const mods = splitButtons(b);\n            const committer = mods.pop()!;\n            // add checking on the old mod keys\n            for (let m of mods) {\n                modsToClear.delete(m);\n                if (!this.mods.has(m)) this.mods.set(m, false);\n            }\n\n            // install new buttons\n            if (!this.committers.has(committer)) {\n                this.committers.set(committer, {\n                    check: new Set(mods),\n                    btns: new Map([[button, mods]]),\n                });\n            }\n            else {\n                const e = this.committers.get(committer)!;\n                mods.forEach(m => e.check.add(m));\n                e.btns.set(button, mods);\n            }\n        }\n        // cleanup\n        modsToClear.forEach(m => this.mods.delete(m));\n    }\n    handleDown(key: T): string[] {\n        if (this.mods.has(key)) {\n            this.mods.set(key, true);\n        }\n        const commit = this.committers.get(key);\n        const pressedButtons: string[] = [];\n        if (commit) {\n            options: for (let [button, mods] of commit.btns.entries()) {\n                for (let mod of commit.check.values()) {\n                    if (this.mods.get(mod) !== mods.includes(mod)) {\n                        continue options;\n                    }\n                }\n                this.buttonsUsed.add(button);\n                pressedButtons.push(button);\n            }\n        }\n        return pressedButtons;\n    }\n    handleUp(key: T): string[] {\n        if (this.mods.has(key)) {\n            this.mods.set(key, false);\n        }\n        const commit = this.committers.get(key);\n        const canceledButtons: string[] = [];\n        if (commit) {\n            for (var button of commit.btns.keys()) {\n                this.buttonsUsed.delete(button) && canceledButtons.push(button);\n            }\n        }\n        return canceledButtons;\n    }\n}\n\nexport class ButtonProcessor {\n    byKey = new ChordedButtonDetector<ChordedKey>();\n    byKeyCode = new ChordedButtonDetector<string>();\n    byMouse = new ChordedButtonDetector<ChordedMouseButton>();\n    byGamepad = new ChordedButtonDetector<ChordedKGamepadButton>();\n    state = new ButtonState<string>(\n        \"buttonPress\",\n        null,\n        \"buttonDown\",\n        \"buttonRelease\",\n    );\n    updateBinding(name: string, b: ButtonBinding) {\n        const keyboardBtns = b.keyboard && [b.keyboard].flat();\n        const keyboardCodes = b.keyboardCode\n            && [b.keyboardCode].flat();\n        const gamepadBtns = b.gamepad && [b.gamepad].flat();\n        const mouseBtns = b.mouse && [b.mouse].flat();\n        if (keyboardBtns) {\n            this.byKey.updateBinding(name, keyboardBtns);\n        }\n        if (keyboardCodes) {\n            this.byKeyCode.updateBinding(name, keyboardCodes);\n        }\n        if (gamepadBtns) {\n            this.byGamepad.updateBinding(name, gamepadBtns);\n        }\n        if (mouseBtns) {\n            this.byMouse.updateBinding(name, mouseBtns);\n        }\n    }\n    private _maybePress(buttons: string[], state: AppState) {\n        for (let button of buttons) {\n            this.state.press(button, state);\n        }\n    }\n    private _maybeRelease(buttons: string[], state: AppState) {\n        for (let button of buttons) {\n            this.state.release(button, state);\n        }\n    }\n    processKeydown(key: Key, keyCode: string, state: AppState) {\n        this._maybePress(this.byKey.handleDown(key), state);\n        this._maybePress(this.byKeyCode.handleDown(keyCode), state);\n    }\n    processKeyup(key: Key, keyCode: string, state: AppState) {\n        this._maybeRelease(this.byKey.handleUp(key), state);\n        this._maybeRelease(this.byKeyCode.handleUp(keyCode), state);\n    }\n    processMousedown(mb: MouseButton, state: AppState) {\n        this._maybePress(this.byMouse.handleDown(mb), state);\n    }\n    processMouseup(mb: MouseButton, state: AppState) {\n        this._maybeRelease(this.byMouse.handleUp(mb), state);\n    }\n    processGamepadButtonDown(gb: KGamepadButton, state: AppState) {\n        this._maybePress(this.byGamepad.handleDown(gb), state);\n    }\n    processGamepadButtonUp(gb: KGamepadButton, state: AppState) {\n        this._maybeRelease(this.byGamepad.handleUp(gb), state);\n    }\n    update() {\n        this.state.update();\n    }\n    process(state: AppState) {\n        this.state.process(state);\n    }\n}\n", "// App is everything related to canvas, game loop and input\n\nimport type {\n    Cursor,\n    GameObj,\n    KAPLAYOpt,\n    Key,\n    KGamepad,\n    KGamepadButton,\n    KGamepadStick,\n    MouseButton,\n    Tag,\n} from \"../types\";\n\nimport { GP_MAP } from \"../constants/general\";\nimport type {\n    AppEventMap,\n    GameObjEventNames,\n    GameObjEvents,\n} from \"../events/eventMap\";\nimport { type KEventController, KEventHandler } from \"../events/events\";\nimport { canvasToViewport } from \"../gfx/viewport\";\nimport { map, vec2 } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport { _k } from \"../shared\";\nimport { deprecateMsg } from \"../utils/log\";\nimport { overload2 } from \"../utils/overload\";\nimport { isEqOrIncludes, setHasOrIncludes } from \"../utils/sets\";\nimport type { TupleWithoutFirst } from \"../utils/types\";\nimport {\n    getButton,\n    getButtons,\n    pressButton,\n    releaseButton,\n    setButton,\n} from \"./buttons\";\nimport {\n    ButtonProcessor,\n    type ButtonsDef,\n    parseButtonBindings,\n} from \"./inputBindings\";\n\nexport class ButtonState<T = string, A = never> {\n    pressed = new Set<T>();\n    pressedRepeat = new Set<T>();\n    released = new Set<T>();\n    down = new Set<T>();\n    constructor(\n        private _pressEv: keyof AppEventMap | null,\n        private _pressRepeatEv: keyof AppEventMap | null,\n        private _downEv: keyof AppEventMap | null,\n        private _releaseEv: keyof AppEventMap | null,\n        private _arg?: A,\n    ) {}\n    update() {\n        this.pressed.clear();\n        this.released.clear();\n        this.pressedRepeat.clear();\n    }\n    process(state: AppState) {\n        if (this._downEv !== null) {\n            this.down.forEach(b => {\n                state.events.trigger(this._downEv as any, b, this._arg);\n            });\n        }\n    }\n    press(btn: T, state: AppState) {\n        const had = this.pressed.has(btn);\n        this.pressed.add(btn);\n        this.down.add(btn);\n        if (!had && this._pressEv !== null) {\n            state.events.trigger(this._pressEv as any, btn, this._arg);\n        }\n        this.pressRepeat(btn, state);\n    }\n    pressRepeat(btn: T, state: AppState) {\n        const had = this.pressedRepeat.has(btn);\n        this.pressedRepeat.add(btn);\n        if (!had && this._pressRepeatEv !== null) {\n            state.events.trigger(this._pressRepeatEv as any, btn, this._arg);\n        }\n    }\n    release(btn: T, state: AppState) {\n        const had = this.released.has(btn);\n        this.down.delete(btn);\n        this.pressed.delete(btn);\n        this.released.add(btn);\n        if (!had && this._releaseEv !== null) {\n            state.events.trigger(this._releaseEv as any, btn, this._arg);\n        }\n    }\n}\n\nclass GamepadState {\n    // We allow null gamepad because one of these is used for the merged gamepad state which\n    // doesn't fire the events. since they have to include the gamepad as the arg we just let\n    // the individual gamepad states fire the events, and only collect the merged state here\n    // for the purposes of isGamepadButtonDown() etc.\n    constructor(gp: KGamepad | null) {\n        this.buttonState = new ButtonState(\n            gp && \"gamepadButtonPress\",\n            null,\n            gp && \"gamepadButtonDown\",\n            gp && \"gamepadButtonRelease\",\n            gp!,\n        );\n    }\n    buttonState: ButtonState<KGamepadButton, KGamepad>;\n    stickState: Map<KGamepadStick, Vec2> = new Map([\n        [\"left\", new Vec2(0)],\n        [\"right\", new Vec2(0)],\n    ]);\n    analogState = new Map<string, number>();\n}\n\nclass FPSCounter {\n    /** Window size */\n    maxSamples = 10;\n    history = new Float64Array(this.maxSamples);\n    accumulator = 0;\n    i = 0;\n    fps = 0;\n    curNSamples = 0;\n    timer = 0;\n    autoRecalculateInterval = 1;\n    tick(dt: number) {\n        this.timer += dt;\n        this.accumulator += dt - this.history[this.i];\n        this.history[this.i] = dt;\n        this.i = (this.i + 1) % this.maxSamples;\n        this.curNSamples = Math.min(this.curNSamples + 1, this.maxSamples);\n        if (this.timer >= this.autoRecalculateInterval) {\n            this.calculate();\n            this.timer = 0;\n        }\n    }\n    calculate() {\n        return this.fps = this.curNSamples / this.accumulator;\n    }\n    ago(ago: number) {\n        return this.history.at(this.i - ago - 1);\n    }\n    resize(samples: number) {\n        this.history = new Float64Array(this.maxSamples = samples);\n        this.i = this.curNSamples = 0;\n    }\n}\n\nexport type App = ReturnType<typeof initApp>;\nexport type AppState = ReturnType<typeof initAppState>;\n\n/**\n * The App method names that will have a helper in GameObjRaw\n */\nexport type AppEvents = keyof {\n    [K in keyof App as K extends `on${any}` ? K : never]: [never];\n};\n\nconst fixedSpeeds = {\n    friedPotato: 10,\n    potato: 20,\n    snail: 25,\n    normal: 50,\n    lightspeed: 80,\n    ridiculous: 125,\n    ludicrous: 160,\n};\n\nexport type FixedSpeedOption = keyof typeof fixedSpeeds;\n\n/**\n * Create the App state object.\n *\n * @ignore\n *\n * @param opt - Options.\n *\n * @returns The app state.\n */\nexport const initAppState = (opt: {\n    canvas: HTMLCanvasElement;\n    buttons?: ButtonsDef;\n    fixedUpdateMode?: FixedSpeedOption;\n    maxTimeStep?: number;\n}) => {\n    const buttons = opt.buttons ?? {};\n    return {\n        canvas: opt.canvas,\n        buttons: buttons,\n        buttonHandler: new ButtonProcessor(),\n        loopID: null as null | number,\n        stopped: false,\n        dt: 0,\n        fixedDt: 1 / 50,\n        maxStep: opt.maxTimeStep ?? 0.1,\n        restDt: 0,\n        time: 0,\n        realTime: 0,\n        rawFPSCounter: new FPSCounter(),\n        fpsCounter: new FPSCounter(),\n        timeScale: 1,\n        skipTime: false,\n        isHidden: false,\n        numFrames: 0,\n        capsOn: false,\n        mousePos: new Vec2(0),\n        mouseDeltaPos: new Vec2(0),\n        keyState: new ButtonState<Key>(\n            \"keyPress\",\n            \"keyPressRepeat\",\n            \"keyDown\",\n            \"keyRelease\",\n        ),\n        mouseState: new ButtonState<MouseButton>(\n            \"mousePress\",\n            null,\n            \"mouseDown\",\n            \"mouseRelease\",\n        ),\n        mergedGamepadState: new GamepadState(null),\n        gamepadStates: new Map<number, GamepadState>(),\n        lastInputDevice: null as \"mouse\" | \"keyboard\" | \"gamepad\" | null,\n        // unified input state\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\n/**\n * Create the App, the context, and handler for all things related to the game\n * canvas, input, and DOM interaction.\n *\n * @ignore\n *\n * @param opt - Options.\n *\n * @returns The app context.\n */\nexport const initApp = (\n    opt: {\n        canvas: HTMLCanvasElement;\n    } & KAPLAYOpt,\n) => {\n    if (!opt.canvas) {\n        throw new Error(\"Please provide a canvas\");\n    }\n\n    const state = initAppState(opt);\n    parseButtonBindings(state);\n    if (opt.fixedUpdateMode) setFixedSpeed(opt.fixedUpdateMode);\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 rawFPS() {\n        return state.rawFPSCounter.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 screenshotToBlob(): Promise<Blob> {\n        return new Promise<Blob>((resolve, reject) => {\n            state.canvas.toBlob(b => {\n                if (b !== null) resolve(b);\n                else reject(new Error(\"failed to make blob\"));\n            });\n        });\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    const isFocused = () => {\n        return document.activeElement === 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 setFixedSpeed(speed: FixedSpeedOption) {\n        const fps = fixedSpeeds[speed];\n        if (!fps) throw new Error(\"Unknown fixed speed \" + speed);\n        state.fixedDt = 1 / fps;\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 fixedUpdateAccumulator = 0;\n        let updateAccumulator = 0;\n\n        const frame = (t: number) => {\n            state.loopID = null;\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 currentTime = t / 1000;\n            const unclampedDt = currentTime - state.realTime;\n            const observedDt = Math.min(unclampedDt, state.maxStep);\n\n            state.rawFPSCounter.tick(unclampedDt);\n            state.realTime = currentTime;\n\n            if (state.skipTime) {\n                state.skipTime = false;\n            }\n            else {\n                updateAccumulator += observedDt;\n                fixedUpdateAccumulator += observedDt;\n\n                if (fixedUpdateAccumulator > state.fixedDt) {\n                    state.dt = state.fixedDt;\n                    state.restDt = 0;\n                    while (fixedUpdateAccumulator > state.fixedDt) {\n                        fixedUpdateAccumulator -= state.fixedDt;\n                        if (fixedUpdateAccumulator < state.fixedDt) {\n                            state.restDt = fixedUpdateAccumulator;\n                        }\n                        fixedUpdate();\n                    }\n                }\n                const desiredDt = opt.maxFPS ? 1 / opt.maxFPS : 0;\n                if (updateAccumulator > desiredDt) {\n                    state.time += state.dt = desiredDt > 0\n                        ? Math.max(desiredDt, observedDt)\n                        : observedDt;\n                    state.restDt = fixedUpdateAccumulator;\n                    state.fpsCounter.tick(state.dt);\n                    if (desiredDt > 0) {\n                        updateAccumulator -= desiredDt;\n                    }\n                    else {\n                        updateAccumulator = 0;\n                    }\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 getGamepadAnalogButton(\n        btn: KGamepadButton,\n    ): number {\n        return state.mergedGamepadState.analogState.get(btn) ?? 0;\n    }\n\n    function isButtonPressed(btn?: string | string[]): boolean {\n        return btn === undefined\n            ? state.buttonHandler.state.pressed.size > 0\n            : setHasOrIncludes(state.buttonHandler.state.pressed, btn);\n    }\n\n    function isButtonDown(btn?: string | string[]): boolean {\n        return btn === undefined\n            ? state.buttonHandler.state.down.size > 0\n            : setHasOrIncludes(state.buttonHandler.state.down, btn);\n    }\n\n    function isButtonReleased(btn?: string | string[]): boolean {\n        return btn === undefined\n            ? state.buttonHandler.state.released.size > 0\n            : setHasOrIncludes(state.buttonHandler.state.released, 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        deprecateMsg(\"onHide\", \"onTabHide\");\n        return onTabHide(action);\n    }\n\n    function onShow(action: () => void): KEventController {\n        deprecateMsg(\"onShow\", \"onTabShow\");\n        return onTabShow(action);\n    }\n\n    function onTabHide(action: () => void): KEventController {\n        return state.events.on(\"show\", action);\n    }\n\n    function onTabShow(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: KGamepadStick,\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        return state.events.on(\"gamepadConnect\", action);\n    }\n\n    function onGamepadDisconnect(action: (gamepad: KGamepad) => void) {\n        return state.events.on(\"gamepadDisconnect\", action);\n    }\n\n    function getGamepadStick(stick: KGamepadStick): 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    const getLastInputDeviceType = () => {\n        return state.lastInputDevice;\n    };\n\n    function processInput() {\n        state.events.trigger(\"input\");\n        processGamepad();\n        state.keyState.process(state);\n        state.mouseState.process(state);\n        state.buttonHandler.process(state);\n    }\n\n    function resetInput() {\n        state.keyState.update();\n        state.mouseState.update();\n        state.buttonHandler.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        state.mergedGamepadState.analogState.forEach((v, k) => {\n            state.mergedGamepadState.analogState.set(k, 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            s.analogState.forEach((v, k) => {\n                s.analogState.set(k, 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: KGamepadStick) => {\n                return state.gamepadStates.get(browserGamepad.index)?.stickState\n                    .get(stick) || vec2();\n            },\n            getAnalog: (button: KGamepadButton) => {\n                return state.gamepadStates.get(browserGamepad.index)\n                    ?.analogState.get(button) ?? 0;\n            },\n        };\n\n        state.gamepads.push(gamepad);\n\n        state.gamepadStates.set(\n            browserGamepad.index,\n            new GamepadState(gamepad),\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\n                gamepadState.analogState.set(\n                    gamepadBtn,\n                    browserGamepadBtn.value,\n                );\n                state.mergedGamepadState.analogState.set(\n                    gamepadBtn,\n                    browserGamepadBtn.value,\n                );\n\n                if (browserGamepadBtn.pressed) {\n                    if (gamepadState.buttonState.down.has(gamepadBtn)) {\n                        gamepadState.buttonState.process(state);\n                        continue;\n                    }\n\n                    state.lastInputDevice = \"gamepad\";\n                    state.buttonHandler.processGamepadButtonDown(\n                        gamepadBtn,\n                        state,\n                    );\n\n                    state.mergedGamepadState.buttonState.press(\n                        gamepadBtn,\n                        state,\n                    );\n                    gamepadState.buttonState.press(gamepadBtn, state);\n                }\n                else if (gamepadState.buttonState.down.has(gamepadBtn)) {\n                    state.buttonHandler.processGamepadButtonUp(\n                        gamepadBtn,\n                        state,\n                    );\n\n                    state.mergedGamepadState.buttonState.release(\n                        gamepadBtn,\n                        state,\n                    );\n                    gamepadState.buttonState.release(gamepadBtn, state);\n                }\n            }\n\n            for (const stickName in map.sticks) {\n                const stick = map.sticks[stickName as KGamepadStick];\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 KGamepadStick, value);\n                state.mergedGamepadState.stickState.set(\n                    stickName as KGamepadStick,\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        // \uD83C\uDF5D Here we depend of GFX Context even if initGfx needs initApp for being used\n        // Letterbox creates some black bars so we need to remove that for calculating\n        // mouse position\n\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 (!opt.letterbox && 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.lastInputDevice = \"mouse\";\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            state.buttonHandler.processMousedown(m, state);\n            state.mouseState.press(m, state);\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            state.buttonHandler.processMouseup(m, state);\n            state.mouseState.release(m, state);\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        state.capsOn = e.getModifierState(\"CapsLock\");\n\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, state);\n            }\n            else {\n                state.lastInputDevice = \"keyboard\";\n                state.buttonHandler.processKeydown(k, code, state);\n                state.keyState.press(k, state);\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            state.buttonHandler.processKeyup(k, code, state);\n            state.keyState.release(k, state);\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                state.lastInputDevice = \"mouse\";\n                state.buttonHandler.processMousedown(\"left\", state);\n                state.mouseState.press(\"left\", state);\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchStart\",\n                    canvasToViewport(\n                        new Vec2(\n                            t.clientX - box.x,\n                            t.clientY - box.y,\n                        ),\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(\n                            t.clientX - box.x,\n                            t.clientY - box.y,\n                        ),\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                state.mouseDeltaPos = new Vec2(0, 0);\n                state.buttonHandler.processMouseup(\"left\", state);\n                state.mouseState.release(\"left\", state);\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchEnd\",\n                    canvasToViewport(\n                        new Vec2(\n                            t.clientX - box.x,\n                            t.clientY - box.y,\n                        ),\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\", state);\n            }\n\n            touches.forEach((t) => {\n                state.events.trigger(\n                    \"touchEnd\",\n                    canvasToViewport(\n                        new Vec2(\n                            t.clientX - box.x,\n                            t.clientY - box.y,\n                        ),\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        rawFPS,\n        setFixedSpeed,\n        numFrames,\n        quit,\n        isHidden,\n        setFullscreen,\n        isFullscreen,\n        setCursor,\n        screenshot,\n        screenshotToBlob,\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        isFocused,\n        getGamepadStick,\n        getGamepadAnalogButton,\n        isButtonPressed,\n        isButtonDown,\n        isButtonReleased,\n        getButton,\n        getButtons,\n        setButton,\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        onTabHide,\n        onTabShow,\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 type { App } from \"../app/app\";\nimport type { InternalAudioCtx } from \"../audio/audio\";\nimport { LOG_MAX } from \"../constants/general\";\nimport type { FrameRenderer } from \"../core/frameRendering\";\nimport type { Game } from \"../game/game\";\nimport type { AppGfxCtx } from \"../gfx/gfxApp\";\nimport { _k } from \"../shared\";\nimport type { KAPLAYOpt } from \"../types\";\nimport type { Recording } from \"./record\";\n\n/**\n * Available debugging message styles.\n *\n * @group Debug\n */\ntype DebugLogStyle = \"info\" | \"warn\" | \"error\";\n\n/**\n * Acceptable values for debugging message.\n *\n * @group Debug\n */\ntype DebugMessage = string | { toString(): string } | Error;\n\n/**\n * @group Debug\n */\nexport type DebugLog = {\n    msg: DebugMessage;\n    time: number;\n    style: DebugLogStyle;\n};\n\n/**\n * An interface for debugging the game.\n *\n * @group Debug\n */\nexport interface Debug {\n    /**\n     * Pause the whole game.\n     */\n    paused: boolean;\n    /**\n     * Draw bounding boxes of all objects with `area()` component, hover to inspect their states.\n     */\n    inspect: boolean;\n    /**\n     * Global time scale.\n     */\n    timeScale: number;\n    /**\n     * Show the debug log or not.\n     */\n    showLog: boolean;\n    /**\n     * Current frames per second, that the game is running using\n     * (may be limited by the `maxFPS` or `maxTimeStep` options)\n     */\n    fps(): number;\n    /**\n     * Raw frames per second from the browser unaffected by\n     * the `maxFPS` or `maxTimeStep` options.\n     */\n    rawFPS(): number;\n    /**\n     * Total number of frames elapsed.\n     *\n     * @since v3000.0\n     */\n    numFrames(): number;\n    /**\n     * Number of draw calls made last frame.\n     */\n    drawCalls(): number;\n    /**\n     * Step to the next frame. Useful with pausing.\n     */\n    stepFrame(): void;\n    /**\n     * Clear the debug log.\n     */\n    clearLog(): void;\n    /**\n     * Log a message to the on-screen debug log, with optional\n     * style wrapping.\n     *\n     * @param message - The messages to log\n     * @param wrapStyle - Style to wrap all messages\n     *\n     * @example\n     * ```\n     * debug.logMessage([\"oh\", \"hi\"], \"warn\");\n     * ```\n     *\n     * @since v4000.0\n     */\n    logMessage(message: DebugMessage[], wrapStyle?: DebugLogStyle): void;\n    /**\n     * Log a message with the info style (white) to the on-screen debug log.\n     *\n     * @param message - The message to log\n     *\n     * @example\n     * ```\n     * debug.log(\"oh\", \"hi\")\n     * ```\n     */\n    log(...message: DebugMessage[]): void;\n    /**\n     * Log a message with the warn style (yellow) to the on-screen debug log.\n     *\n     * @param message - The message to log\n     *\n     * @example\n     * ```\n     * debug.warn(\"oh\", \"humm\")\n     * ```\n     *\n     * @since v4000.0\n     */\n    warn(...message: DebugMessage[]): void;\n    /**\n     * Log a message with the error style (pink since kaboom) to the on-screen debug log.\n     *\n     * @param message - The message to log\n     *\n     * @example\n     * ```\n     * debug.error(\"oh\", \"no\")\n     * ```\n     */\n    error(...message: DebugMessage[]): void;\n    /**\n     * The recording handle if currently in recording mode.\n     *\n     * @since v2000.1\n     */\n    curRecording: Recording | null;\n    /**\n     * Get total number of objects.\n     *\n     * @since v3001.0\n     */\n    numObjects(): number;\n}\n\nexport const createDebug = (\n    gopt: KAPLAYOpt,\n    app: App,\n    appGfx: AppGfxCtx,\n    audio: InternalAudioCtx,\n    game: Game,\n    fr: FrameRenderer,\n): Debug => {\n    let debugPaused = false;\n\n    const debug = {\n        inspect: false,\n        set timeScale(timeScale: number) {\n            app.state.timeScale = timeScale;\n        },\n        get timeScale() {\n            return app.state.timeScale;\n        },\n        showLog: true,\n        fps: () => app.fps(),\n        rawFPS: () => app.rawFPS(),\n        numFrames: () => app.numFrames(),\n        stepFrame: fr.updateFrame,\n        drawCalls: () => appGfx.lastDrawCalls,\n        clearLog: () => game.logs = [],\n        logMessage: (message, wrapStyle = \"info\") => {\n            const max = gopt.logMax ?? LOG_MAX;\n            const msg = message.length > 1\n                ? message.concat(\" \").join(\" \")\n                : message[0];\n\n            game.logs.unshift({\n                msg: msg,\n                time: app.time(),\n                style: wrapStyle,\n            });\n\n            if (game.logs.length > max) {\n                game.logs = game.logs.slice(0, max);\n            }\n        },\n        log: (...message) => {\n            debug.logMessage(message, \"info\");\n        },\n        warn: (...message) => {\n            debug.logMessage(message, \"warn\");\n        },\n        error: (...message) => {\n            debug.logMessage(message, \"error\");\n        },\n        curRecording: null,\n        numObjects: () => game.root.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    } satisfies Debug;\n\n    return debug;\n};\n", "import {\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    onSceneLeave,\n    onTag,\n    onUntag,\n    onUnuse,\n    onUpdate,\n    onUse,\n} from \"../api/eventHandlers\";\nimport type { App } from \"../app/app\";\nimport { onCleanup } from \"../core/quit\";\n\nexport type ScopeHandlers = ReturnType<typeof createScopeHandlers>;\n\nexport const createScopeHandlers = (app: App) => {\n    const handlers = {\n        onKeyDown: app.onKeyDown,\n        onKeyPress: app.onKeyPress,\n        onKeyPressRepeat: app.onKeyPressRepeat,\n        onKeyRelease: app.onKeyRelease,\n        onCharInput: app.onCharInput,\n        onMouseDown: app.onMouseDown,\n        onMousePress: app.onMousePress,\n        onMouseRelease: app.onMouseRelease,\n        onMouseMove: app.onMouseMove,\n        onTouchStart: app.onTouchStart,\n        onTouchEnd: app.onTouchEnd,\n        onTouchMove: app.onTouchMove,\n        onScroll: app.onScroll,\n        onGamepadConnect: app.onGamepadConnect,\n        onGamepadDisconnect: app.onGamepadDisconnect,\n        onGamepadButtonDown: app.onGamepadButtonDown,\n        onGamepadButtonPress: app.onGamepadButtonPress,\n        onGamepadButtonRelease: app.onGamepadButtonRelease,\n        onGamepadStick: app.onGamepadStick,\n        onButtonDown: app.onButtonDown,\n        onButtonPress: app.onButtonPress,\n        onButtonRelease: app.onButtonRelease,\n        onTabShow: app.onTabShow,\n        onTabHide: app.onTabHide,\n        onUpdate: onUpdate,\n        onFixedUpdate: onFixedUpdate,\n        onDraw: onDraw,\n        onAdd: onAdd,\n        onDestroy: onDestroy,\n        onUse: onUse,\n        onUnuse: onUnuse,\n        onTag: onTag,\n        onUntag: onUntag,\n        on: on,\n        onClick: onClick,\n        onCollide: onCollide,\n        onCollideEnd: onCollideEnd,\n        onCollideUpdate: onCollideUpdate,\n        onHover: onHover,\n        onHoverEnd: onHoverEnd,\n        onHoverUpdate: onHoverUpdate,\n        onResize: app.onResize,\n        onSceneLeave: onSceneLeave,\n        onLoad: onLoad,\n        onLoading: onLoading,\n        onError: onError,\n        onLoadError: onLoadError,\n        onCleanup: onCleanup,\n        // deprecated\n        onShow: app.onShow,\n        onHide: app.onHide,\n    };\n\n    return handlers;\n};\n", "import type { App } from \"../app/app\";\nimport {\n    GameObjRawPrototype,\n    type InternalGameObjRaw,\n} from \"../ecs/entity/GameObjRaw\";\nimport { scene, type SceneDef } from \"../game/scenes\";\nimport { _k } from \"../shared\";\nimport type { KEventController } from \"./events\";\nimport { type ScopeHandlers } from \"./scopeHandlers\";\n\nexport type SceneScope =\n    & ScopeHandlers\n    & {\n        (id: string, def: SceneDef): void;\n    };\n\nexport const createSceneScope = (\n    handlers: ScopeHandlers,\n): SceneScope => {\n    const sceneScope = scene;\n\n    for (const e of Object.keys(handlers)) {\n        // @ts-expect-error\n        sceneScope[e] = function(...args: [any]) {\n            // @ts-expect-error\n            const ev: KEventController = handlers[e]?.(...args);\n\n            _k.game.sceneEvents.push(ev);\n\n            return ev;\n        };\n    }\n\n    return sceneScope as SceneScope;\n};\n\nexport type AppScope = ScopeHandlers;\n\nexport const createAppScope = (handlers: ScopeHandlers): AppScope => {\n    const appScope = {} as Record<string, any>;\n\n    for (const e of Object.keys(handlers)) {\n        appScope[e] = handlers[e as keyof ScopeHandlers];\n    }\n\n    return appScope as AppScope;\n};\n\nconst ingnoredHandlersForObject = [\n    \"onUpdate\",\n    \"onFixedUpdate\",\n    \"onDraw\",\n    \"onAdd\",\n    \"onDestroy\",\n    \"onUse\",\n    \"onUnuse\",\n    \"onTag\",\n    \"onUntag\",\n    \"onCollide\",\n    \"onCollideEnd\",\n    \"onCollideUpdate\",\n    \"onClick\",\n    \"onHover\",\n    \"onHoverEnd\",\n    \"onHoverUpdate\",\n    \"on\",\n] as const;\n\nexport type EventHandlersInAppButNotAddedInGameObjRaw =\n    typeof ingnoredHandlersForObject[number];\n\nexport function attachScopeHandlersToGameObjRaw(handlers: ScopeHandlers) {\n    for (const e of Object.keys(handlers)) {\n        if (\n            ingnoredHandlersForObject.includes(\n                e as EventHandlersInAppButNotAddedInGameObjRaw,\n            )\n        ) {\n            continue;\n        }\n\n        const obj = GameObjRawPrototype as Record<string, any>;\n\n        obj[e] = function(this: InternalGameObjRaw, ...args: [any]) {\n            // @ts-ignore\n            const ev: KEventController = handlers[e]?.(...args);\n            ev.controller = this;\n\n            this._inputEvents.push(ev);\n\n            this.onDestroy(() => ev.cancel());\n\n            return ev;\n        };\n    }\n}\n", "// The Game is the interface that connects all related to a KAPLAY game state.\n// It contains the game object tree, game object events, scenes, etc.\n\n// All in /game folder is stuff that uses/modify the game state.\n\nimport type { Asset } from \"../assets/asset\";\nimport type { SoundData } from \"../assets/sound\";\nimport type { SpriteData } from \"../assets/sprite\";\nimport type { DebugLog } from \"../debug/debug\";\nimport type { FakeMouseComp } from \"../ecs/components/misc/fakeMouse\";\nimport { timer, type TimerComp } from \"../ecs/components/misc/timer\";\nimport type { AreaComp } from \"../ecs/components/physics/area\";\nimport type { PosComp } from \"../ecs/components/transform/pos\";\nimport { makeInternal } from \"../ecs/entity/make\";\nimport type { System } from \"../ecs/systems/systems\";\nimport type { GameEventMap, GameObjEventMap } from \"../events/eventMap\";\nimport { type KEventController, KEventHandler } from \"../events/events\";\nimport { Mat23, Rect, RNG } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport type { GameObj } from \"../types\";\nimport type { SceneDef, SceneState } from \"./scenes\";\n\n/**\n * The \"Game\" it's all the state related to the game running\n */\nexport type Game = {\n    /**\n     * The last game object id used.\n     */\n    gameObjLastId: number;\n    /**\n     * Game global events.\n     */\n    events: KEventHandler<GameEventMap>;\n    /**\n     * Where game object global events are stored.\n     */\n    gameObjEvents: KEventHandler<GameObjEventMap>;\n    /**\n     * Event Handlers that are cancelled on scene change.\n     */\n    sceneEvents: KEventController[];\n    /**\n     * The root game object, parent of all game objects.\n     */\n    root: GameObj<TimerComp>;\n    /**\n     * The gravity vector of the game.\n     */\n    gravity: Vec2 | null;\n    /**\n     * The scenes of the game.\n     */\n    scenes: Record<string, SceneDef>;\n    /**\n     * The scene stack that stores the scene states\n     */\n    sceneStack: Array<SceneState>;\n    /**\n     * The current active scene arguments\n     */\n    currentSceneArgs: unknown[];\n    /**\n     * The current scene of the game.\n     */\n    currentScene: string | null;\n    /**\n     * The layers of the game.\n     */\n    layers: string[] | null;\n    /**\n     * The default layer index of the game.\n     */\n    defaultLayerIndex: number;\n    /**\n     * All systems added to the game.\n     */\n    systems: System[];\n    /**\n     * The systems added to the game, sorted by event.\n     */\n    systemsByEvent: [\n        System[],\n        System[],\n        System[],\n        System[],\n        System[],\n        System[],\n    ];\n    defaultAssets: {\n        ka?: Asset<SpriteData>;\n        boom?: Asset<SpriteData>;\n        burp?: SoundData;\n        happy?: string;\n        bean?: string;\n    };\n    logs: DebugLog[];\n    cam: CamData;\n    /**\n     * The default RNG used by rng functions.\n     */\n    // TODO: let user pass seed\n    defRNG: RNG;\n    /**\n     * If game just crashed.\n     */\n    crashed: boolean;\n    /**\n     * How many areas are in the game.\n     */\n    areaCount: number;\n    /**\n     * Fake Mouse game obj.\n     */\n    fakeMouse: GameObj<FakeMouseComp | PosComp> | null;\n    /** */\n    retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;\n    /**\n     * All text inputs in the game.\n     */\n    allTextInputs: Set<GameObj>;\n    /**\n     * Deprecated functions we already warned about.\n     */\n    warned: Set<string>;\n};\n\n/**\n * @group Rendering\n * @subgroup Camera\n */\ntype CamData = {\n    pos: Vec2 | null;\n    scale: Vec2;\n    angle: number;\n    shake: number;\n    transform: Mat23;\n};\n\n/**\n * Creates the Game interface.\n *\n * This will create:\n *\n * - The root game object\n * - The game object events\n * - The camera data\n *\n * @returns A Game\n */\nexport const createGame = (): Game => {\n    const game: Game = {\n        gameObjLastId: 0,\n        root: makeInternal(0) as GameObj<TimerComp>,\n        events: new KEventHandler<GameEventMap>(),\n        gameObjEvents: new KEventHandler<GameObjEventMap>(),\n        sceneEvents: [],\n        cam: {\n            pos: null as Vec2 | null,\n            scale: new Vec2(1),\n            angle: 0,\n            shake: 0,\n            transform: new Mat23(),\n        },\n        currentSceneArgs: [], // stores the current scene arguments //\n        sceneStack: [], // stores the scene names //\n\n        // Systems\n        systems: [], // all systems added\n        // we allocate systems here\n        systemsByEvent: [\n            [], // beforeUpdate\n            [], // beforeFixedUpdate\n            [], // beforeDraw\n            [], // afterUpdate\n            [], // afterFixedUpdate\n            [], // afterDraw\n        ],\n\n        // Scenes\n        scenes: {} as Record<string, SceneDef>,\n        currentScene: null as string | null,\n\n        // Layers\n        layers: null as string[] | null,\n        defaultLayerIndex: 0,\n\n        // Gravity\n        gravity: null as Vec2 | null,\n\n        // Default assets\n        defaultAssets: {},\n\n        // Logs\n        logs: [] as DebugLog[],\n\n        // Fake mouse API\n        fakeMouse: null,\n\n        // Retrieve\n        retrieve: (\n            rect: Rect,\n            retrieveCb: (obj: GameObj<AreaComp>) => void,\n        ) => {},\n\n        // Some state\n        crashed: false,\n        areaCount: 0,\n        allTextInputs: new Set<GameObj>(),\n        defRNG: new RNG(Date.now()),\n        warned: new Set<string>(),\n    };\n\n    game.root.use(timer());\n    game.gameObjLastId++;\n\n    return game;\n};\n", "import type { KAPLAYOpt, MustKAPLAYOpt } from \"../types\";\n\nexport const createCanvas = (gopt: MustKAPLAYOpt) => {\n    const root = gopt.root ?? document.body;\n    const pixelDensity = gopt.pixelDensity || 1;\n\n    // If root is not defined (which falls back to <body>) we assume user is on a clean page,\n    // and modify <body> to better fit a full screen canvas\n\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\n    // canvas css styles\n    const styles = [\n        \"outline: none\",\n        \"cursor: default\",\n    ];\n\n    // Adjust canvas size according to user viewport settings\n    if (\n        // check if isFixed\n        gopt.width && gopt.height && !gopt.letterbox\n    ) {\n        canvas.width = gopt.width * gopt.scale;\n        canvas.height = gopt.height * gopt.scale;\n        styles.push(`width: ${canvas.width}px`);\n        styles.push(`height: ${canvas.height}px`);\n    }\n    else {\n        canvas.width = canvas.parentElement!.offsetWidth;\n        canvas.height = canvas.parentElement!.offsetHeight;\n        styles.push(\"width: 100%\");\n        styles.push(\"height: 100%\");\n    }\n\n    // Cripsing\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    canvas.width *= pixelDensity;\n    canvas.height *= pixelDensity;\n\n    // Makes canvas focusable\n    canvas.tabIndex = 0;\n\n    return canvas;\n};\n", "import { makeShader, type Shader, 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/general\";\nimport { type Color, rgb } from \"../math/color\";\nimport { Mat23 } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\nimport type { MustKAPLAYOpt } from \"../types\";\nimport type { FontAtlas } from \"./formatText\";\nimport { FrameBuffer } from \"./FrameBuffer\";\nimport { BatchRenderer, type GfxCtx, Texture } from \"./gfx\";\nimport type { Frame } from \"./TexPacker\";\n\nexport type AppGfxCtx = {\n    /** How many draw calls we're doing last frame */\n    lastDrawCalls: number;\n    /** Font atlases */\n    fontAtlases: Record<string, FontAtlas>;\n    /** The graphics context */\n    ggl: GfxCtx;\n    /** Default shader */\n    defShader: Shader;\n    whitePixel: Frame;\n    /** FrameBuffer */\n    frameBuffer: FrameBuffer;\n    /** Post Shader, used in postEffect() */\n    postShader: string | null;\n    postShaderUniform: Uniform | (() => Uniform) | null;\n    renderer: BatchRenderer;\n    pixelDensity: number;\n    transform: Mat23;\n    transformStack: Mat23[];\n    transformStackIndex: number;\n    /** The background texture */\n    bgTex: Texture;\n    bgColor: Color | null;\n    bgAlpha: number;\n    /**\n     * The\n     */\n    width: number;\n    height: number;\n    /**\n     * Where the game is rendered.\n     */\n    viewport: Viewport;\n    fixed: boolean;\n    gl: WebGLRenderingContext;\n    /**\n     * Scratch vec2\n     */\n    scratchPt: Vec2;\n};\n\n/**\n * @group Rendering\n * @subgroup Canvas\n */\nexport type Viewport = {\n    x: number;\n    y: number;\n    width: number;\n    height: number;\n    scale: number;\n};\n\nexport const initAppGfx = (gfx: GfxCtx, gopt: MustKAPLAYOpt): AppGfxCtx => {\n    const defShader = makeShader(gfx, DEF_VERT, DEF_FRAG);\n    const pixelDensity = gopt.pixelDensity ?? 1;\n    const { gl } = gfx;\n\n    const frameBuffer = (gopt.width && gopt.height)\n        ? new FrameBuffer(\n            gfx,\n            gopt.width * pixelDensity * gopt.scale,\n            gopt.height * pixelDensity * gopt.scale,\n        )\n        : new FrameBuffer(\n            gfx,\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        gfx,\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        gfx,\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    const transformStack = new Array(32).fill(0).map(_ => new Mat23());\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        fontAtlases: {} as Record<string, FontAtlas>,\n\n        ggl: gfx,\n\n        // gfx states\n        defShader: defShader,\n        whitePixel: null as any,\n        frameBuffer: frameBuffer,\n        postShader: null as string | null,\n        postShaderUniform: null as Uniform | (() => Uniform) | null,\n        renderer: renderer,\n        pixelDensity: pixelDensity,\n\n        transform: new Mat23(),\n        transformStack: transformStack,\n        transformStackIndex: -1,\n\n        bgTex: bgTex,\n        bgColor: bgColor,\n        bgAlpha: bgAlpha,\n\n        width: gopt.width\n            ?? gl.drawingBufferWidth / pixelDensity / gopt.scale,\n        height: gopt.height\n            ?? gl.drawingBufferHeight / pixelDensity / gopt.scale,\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        gl,\n\n        scratchPt: new Vec2(0, 0),\n    };\n};\n", "import { burp } from \"../audio/burp\";\nimport { FrameBuffer } from \"../gfx/FrameBuffer\";\nimport { updateViewport } from \"../gfx/viewport\";\nimport { clamp } from \"../math/clamp\";\nimport { _k } from \"../shared\";\nimport { toFixed } from \"../utils/numbers\";\n\nexport function initAppEvents() {\n    _k.appScope.onTabHide(() => {\n        if (!_k.globalOpt.backgroundAudio) {\n            _k.audio.ctx.suspend();\n        }\n    });\n\n    _k.appScope.onTabShow(() => {\n        if (!_k.globalOpt.backgroundAudio && !_k.debug.paused) {\n            _k.audio.ctx.resume();\n        }\n    });\n\n    _k.app.onResize(() => {\n        const fixedSize = _k.globalOpt.width && _k.globalOpt.height;\n        if (fixedSize && !_k.globalOpt.letterbox) {\n            return;\n        }\n\n        _k.canvas.width = _k.canvas.offsetWidth * _k.gfx.pixelDensity;\n        _k.canvas.height = _k.canvas.offsetHeight * _k.gfx.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\n                / _k.gfx.pixelDensity\n                / _k.globalOpt.scale;\n            _k.gfx.height = _k.gfx.ggl.gl.drawingBufferHeight\n                / _k.gfx.pixelDensity\n                / _k.globalOpt.scale;\n        }\n    });\n\n    if (_k.globalOpt.debug !== false) {\n        _k.appScope.onKeyPress(\n            _k.globalOpt.debugKey ?? \"f1\",\n            () => _k.debug.inspect = !_k.debug.inspect,\n        );\n        _k.appScope.onKeyPress(\"f2\", () => _k.debug.clearLog());\n        _k.appScope.onKeyPress(\"f8\", () => _k.debug.paused = !_k.debug.paused);\n        _k.appScope.onKeyPress(\"f7\", () => {\n            _k.debug.timeScale = toFixed(\n                clamp(_k.debug.timeScale - 0.2, 0, 2),\n                1,\n            );\n        });\n        _k.appScope.onKeyPress(\"f9\", () => {\n            _k.debug.timeScale = toFixed(\n                clamp(_k.debug.timeScale + 0.2, 0, 2),\n                1,\n            );\n        });\n        _k.appScope.onKeyPress(\"f10\", () => _k.debug.stepFrame());\n    }\n\n    // burp mode initialization\n    if (_k.globalOpt.burp) {\n        _k.appScope.onKeyPress(\"b\", () => burp());\n    }\n}\n", "import { DBG_FONT } from \"../../constants/general\";\nimport { rgb } from \"../../math/color\";\nimport { vec2 } from \"../../math/math\";\nimport { type Vec2 } from \"../../math/Vec2\";\nimport { formatText } from \"../formatText\";\nimport {\n    height,\n    multTranslateV,\n    popTransform,\n    pushTransform,\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        multTranslateV(pos);\n\n        // cSpell: ignore ftxt\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            multTranslateV(vec2(-bw, 0));\n        }\n\n        if (pos.y + bh >= height()) {\n            multTranslateV(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 { DBG_FONT, LOG_TIME } from \"../../constants/general\";\nimport { isPaused } from \"../../ecs/entity/utils\";\nimport { rgb } from \"../../math/color\";\nimport { vec2, wave } from \"../../math/math\";\nimport { _k } from \"../../shared\";\nimport { formatText } from \"../formatText\";\nimport {\n    height,\n    multTranslate,\n    popTransform,\n    pushTransform,\n    width,\n} from \"../stack\";\nimport { viewportToCanvas } from \"../viewport\";\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 (\n                obj.has(\"area\")\n                && (_k.globalOpt.inspectOnlyActive ? !isPaused(obj) : true)\n                && obj.isHovering()\n            ) {\n                inspecting = obj;\n                break;\n            }\n        }\n\n        // Get it before any debug drawing, to get the number of non-debug draws\n        const batches = _k.gfx.renderer.numDraws;\n\n        pushTransform();\n        _k.game.root.drawInspect();\n        popTransform();\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            lines.push(...inspecting.tags.map(t => `tag: ${t}`));\n\n            drawInspectText(\n                viewportToCanvas(_k.app.mousePos()),\n                lines.join(\"\\n\"),\n            );\n        }\n\n        drawInspectText(\n            vec2(8),\n            `FPS: ${Math.round(_k.debug.fps())}\nRaw: ${Math.round(_k.debug.rawFPS())}\nBatches: ${batches}`,\n        );\n    }\n\n    if (_k.debug.paused) {\n        drawUnscaled(() => {\n            // top right corner\n            pushTransform();\n            multTranslate(width(), 0);\n            multTranslate(-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            multTranslate(width(), height());\n            multTranslate(-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 !== null) {\n        drawUnscaled(() => {\n            pushTransform();\n            multTranslate(width() - 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            multTranslate(0, height());\n            multTranslate(8, -8);\n\n            const pad = 8;\n            const logs = [];\n\n            for (const log of _k.game.logs) {\n                const style = log.msg instanceof Error ? \"error\" : log.style;\n                let str = \"\";\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                    \"warn\": { color: rgb(255, 230, 8) },\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 {\n    resetTreeIndex,\n    updateLastTransformVersion,\n} from \"../../ecs/entity/GameObjRaw\";\nimport { lerp } from \"../../math/lerp\";\nimport { rand } from \"../../math/math\";\nimport { Vec2 } from \"../../math/Vec2\";\nimport { _k } from \"../../shared\";\nimport { center, flush } from \"../stack\";\n\nexport function transformFrame() {\n    resetTreeIndex();\n    _k.game.root.transformTree(false);\n    updateLastTransformVersion();\n}\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 * _k.app.dt());\n    cam.transform.setIdentity()\n        .translateSelfV(center())\n        .scaleSelfV(cam.scale)\n        .rotateSelf(cam.angle)\n        .translateSelfV((cam.pos ?? center()).scale(-1).add(shake));\n\n    _k.app.state.events.trigger(\"draw\");\n    _k.game.root.draw();\n    flush();\n}\n", "import { loadProgress } from \"../../assets/asset\";\nimport { rgb } from \"../../math/color\";\nimport { vec2 } from \"../../math/math\";\nimport { _k } from \"../../shared\";\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 type { App } from \"../app/app\";\nimport { initAppEvents } from \"../app/appEvents\";\nimport {\n    getFailedAssets,\n    type InternalAssetsCtx,\n    loadProgress,\n} from \"../assets/asset\";\nimport type { Debug } from \"../debug/debug\";\nimport { SystemPhase } from \"../ecs/systems/systems\";\nimport type { Game } from \"../game/game\";\nimport { drawDebug } from \"../gfx/draw/drawDebug\";\nimport { drawFrame, transformFrame } from \"../gfx/draw/drawFrame\";\nimport { drawLoadScreen } from \"../gfx/draw/drawLoadingScreen\";\nimport { updateViewport } from \"../gfx/viewport\";\nimport type { KAPLAYOpt } from \"../types\";\nimport { handleErr } from \"./errors\";\nimport type { FrameRenderer } from \"./frameRendering\";\n\nexport function startEngineLoop(\n    app: App,\n    game: Game,\n    assets: InternalAssetsCtx,\n    gopt: KAPLAYOpt,\n    frameRenderer: FrameRenderer,\n    debug: Debug,\n) {\n    let isFirstFrame = true;\n\n    app.run(() => {\n        try {\n            if (assets.loaded) {\n                if (!debug.paused) {\n                    for (\n                        const sys of game\n                            .systemsByEvent[SystemPhase.BeforeFixedUpdate]\n                    ) {\n                        sys.run();\n                    }\n\n                    frameRenderer.fixedUpdateFrame();\n\n                    for (\n                        const sys of game\n                            .systemsByEvent[SystemPhase.AfterFixedUpdate]\n                    ) {\n                        sys.run();\n                    }\n                }\n\n                // checkFrame();\n            }\n        } catch (e) {\n            handleErr(e as Error);\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                        if (game.events.numListeners(\"loadError\") > 0) {\n                            game.events.trigger(\"loadError\", ...details);\n                        }\n                        else {\n                            throw details[1].error;\n                        }\n                    });\n                    game.events.trigger(\"load\");\n                }\n            }\n\n            if (\n                !assets.loaded && gopt.loadingScreen !== false\n                || isFirstFrame\n            ) {\n                frameRenderer.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                frameRenderer.frameEnd();\n            }\n            else {\n                if (!debug.paused) {\n                    for (\n                        const sys of game\n                            .systemsByEvent[SystemPhase.BeforeUpdate]\n                    ) {\n                        sys.run();\n                    }\n\n                    frameRenderer.updateFrame();\n\n                    for (\n                        const sys of game\n                            .systemsByEvent[SystemPhase.AfterUpdate]\n                    ) {\n                        sys.run();\n                    }\n                }\n\n                // checkFrame();\n                frameRenderer.frameStart();\n\n                transformFrame();\n\n                for (\n                    const sys of game.systemsByEvent[SystemPhase.BeforeDraw]\n                ) {\n                    sys.run();\n                }\n\n                drawFrame();\n                if (gopt.debug !== false) drawDebug();\n\n                for (const sys of game.systemsByEvent[SystemPhase.AfterDraw]) {\n                    sys.run();\n                }\n\n                frameRenderer.frameEnd();\n            }\n\n            if (isFirstFrame) {\n                isFirstFrame = false;\n            }\n\n            app.events.trigger(\"frameEnd\");\n\n            resetInput();\n        } catch (e) {\n            handleErr(e as Error);\n        }\n    });\n\n    updateViewport();\n    initAppEvents();\n}\n", "import { MAX_TEXT_CACHE_SIZE } from \"../constants/general\";\n\nexport const createFontCache = () => {\n    const fontCacheCanvas = document.createElement(\"canvas\");\n    fontCacheCanvas.width = MAX_TEXT_CACHE_SIZE;\n    fontCacheCanvas.height = MAX_TEXT_CACHE_SIZE;\n    const fontCacheC2d = fontCacheCanvas.getContext(\"2d\", {\n        willReadFrequently: true,\n    });\n\n    return {\n        fontCacheCanvas,\n        fontCacheC2d,\n    };\n};\n", "import type { App } from \"../app/app\";\nimport { BG_GRID_SIZE } from \"../constants/general\";\nimport type { Game } from \"../game/game\";\nimport { drawTexture } from \"../gfx/draw/drawTexture\";\nimport { drawUnscaled } from \"../gfx/draw/drawUnscaled\";\nimport { drawUVQuad } from \"../gfx/draw/drawUVQuad\";\nimport type { AppGfxCtx } from \"../gfx/gfxApp\";\nimport { flush, height, width } from \"../gfx/stack\";\nimport { Quad } from \"../math/math\";\nimport { Vec2 } from \"../math/Vec2\";\n\n/**\n * A frame renderer.\n *\n * @ignore\n */\nexport interface FrameRenderer {\n    frameStart: () => void;\n    frameEnd: () => void;\n    fixedUpdateFrame: () => void;\n    updateFrame: () => void;\n}\n\n/**\n * @ignore\n */\nexport const createFrameRenderer = (\n    app: App,\n    gfx: AppGfxCtx,\n    game: Game,\n    pixelDensity: number,\n) => {\n    // start a rendering frame, reset some states\n    function frameStart() {\n        // clear backbuffer\n        gfx.gl.clear(gfx.gl.COLOR_BUFFER_BIT);\n        gfx.frameBuffer.bind();\n        // clear framebuffer\n        gfx.gl.clear(gfx.gl.COLOR_BUFFER_BIT);\n\n        // Iconic background\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.transformStackIndex = -1;\n        gfx.transform.setIdentity();\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        gfx.gl.viewport(\n            0,\n            0,\n            gfx.gl.drawingBufferWidth,\n            gfx.gl.drawingBufferHeight,\n        );\n\n        const ow = gfx.width;\n        const oh = gfx.height;\n        gfx.width = gfx.gl.drawingBufferWidth / pixelDensity;\n        gfx.height = gfx.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    function fixedUpdateFrame() {\n        app.state.events.trigger(\"fixedUpdate\");\n        game.root.fixedUpdate();\n    }\n\n    function updateFrame() {\n        app.state.events.trigger(\"update\");\n        game.root.update();\n    }\n\n    return { frameStart, frameEnd, fixedUpdateFrame, updateFrame };\n};\n", "// The engine is what KAPLAY needs for running and proccesing all it's stuff\n\nimport { initApp } from \"../app/app\";\nimport { initAssets } from \"../assets/asset\";\nimport { initAudio } from \"../audio/audio\";\nimport { createDebug } from \"../debug/debug\";\nimport { blendFactory } from \"../ecs/components/draw/blend\";\nimport { circleFactory } from \"../ecs/components/draw/circle\";\nimport { colorFactory } from \"../ecs/components/draw/color\";\nimport { ellipseFactory } from \"../ecs/components/draw/ellipse\";\nimport { maskFactory } from \"../ecs/components/draw/mask\";\nimport { opacityFactory } from \"../ecs/components/draw/opacity\";\nimport { outlineFactory } from \"../ecs/components/draw/outline\";\nimport { rectFactory } from \"../ecs/components/draw/rect\";\nimport { spriteFactory } from \"../ecs/components/draw/sprite\";\nimport { textFactory } from \"../ecs/components/draw/text\";\nimport { anchorFactory } from \"../ecs/components/transform/anchor\";\nimport { fixedFactory } from \"../ecs/components/transform/fixed\";\nimport { moveFactory } from \"../ecs/components/transform/move\";\nimport { posFactory } from \"../ecs/components/transform/pos\";\nimport { rotateFactory } from \"../ecs/components/transform/rotate\";\nimport { scaleFactory } from \"../ecs/components/transform/scale\";\nimport { zFactory } from \"../ecs/components/transform/z\";\nimport { registerPrefabFactory } from \"../ecs/entity/prefab\";\nimport { createScopeHandlers } from \"../events/scopeHandlers\";\nimport {\n    attachScopeHandlersToGameObjRaw,\n    createAppScope,\n    createSceneScope,\n} from \"../events/scopes\";\nimport { createGame } from \"../game/game\";\nimport { createCanvas } from \"../gfx/canvas\";\nimport { initGfx } from \"../gfx/gfx\";\nimport { initAppGfx } from \"../gfx/gfxApp\";\nimport type { KAPLAYOpt } from \"../types\";\nimport type { KAPLAYCtx } from \"./contextType\";\nimport { startEngineLoop } from \"./engineLoop\";\nimport { createFontCache } from \"./fontCache\";\nimport { createFrameRenderer } from \"./frameRendering\";\n\nexport type Engine = ReturnType<typeof createEngine>;\n\n// Create global variables\nwindow.kaplayjs_assetsAliases = {};\n\n/**\n * Creates all necessary contexts and variables for running a KAPLAY instance.\n *\n * @ignore\n *\n * @param gopt - Global options for create the engine.\n *\n * @returns Engine.\n */\nexport const createEngine = (gopt: KAPLAYOpt) => {\n    // Default options\n    const opt = Object.assign(\n        {\n            scale: 1,\n            spriteAtlasPadding: 2,\n            defaultLifetimeScope: \"scene\" as \"scene\" | \"app\",\n        } satisfies KAPLAYOpt,\n        gopt,\n    );\n\n    const canvas = createCanvas(opt);\n    const { fontCacheC2d, fontCacheCanvas } = createFontCache();\n    const app = initApp({ canvas, ...gopt });\n    const gameHandlers = createScopeHandlers(app);\n    const sceneScope = createSceneScope(gameHandlers);\n    const appScope = createAppScope(gameHandlers);\n    attachScopeHandlersToGameObjRaw(gameHandlers);\n\n    // TODO: Probably we should move this to initGfx\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    // TODO: Investigate correctly what's the different between GFX and AppGFX and reduce to 1 method\n    const gfx = initGfx(gl, opt);\n    const appGfx = initAppGfx(gfx, opt);\n    const assets = initAssets(gfx, opt, appGfx);\n    const audio = initAudio();\n    const game = createGame();\n\n    // Frame rendering\n    const frameRenderer = createFrameRenderer(\n        app,\n        appGfx,\n        game,\n        opt.pixelDensity ?? 1,\n    );\n\n    // Debug mode\n    const debug = createDebug(opt, app, appGfx, audio, game, frameRenderer);\n\n    // Register default factories\n\n    // Transform Serialization\n    registerPrefabFactory(\"anchor\", anchorFactory);\n    registerPrefabFactory(\"fixed\", fixedFactory);\n    // `follow()` missing, we should figure a way to serialize an object reference (probably use named())\n    // `layer()` missing, needs investigation\n    registerPrefabFactory(\"move\", moveFactory);\n    // `offscreen()` missing\n    registerPrefabFactory(\"pos\", posFactory);\n    registerPrefabFactory(\"rotate\", rotateFactory);\n    registerPrefabFactory(\"scale\", scaleFactory);\n    registerPrefabFactory(\"z\", zFactory);\n\n    // Draw Serialization\n    registerPrefabFactory(\"blend\", blendFactory);\n    registerPrefabFactory(\"circle\", circleFactory);\n    registerPrefabFactory(\"color\", colorFactory);\n    // `drawon()` missing\n    registerPrefabFactory(\"ellipse\", ellipseFactory);\n    // `fadeIn()` missing\n    registerPrefabFactory(\"mask\", maskFactory);\n    registerPrefabFactory(\"opacity\", opacityFactory);\n    registerPrefabFactory(\"outline\", outlineFactory);\n    // `particles()` missing\n    // `picture()` missing\n    // `raycast()` missing, anyway, is not a component\n    registerPrefabFactory(\"rect\", rectFactory);\n    registerPrefabFactory(\"sprite\", spriteFactory);\n    registerPrefabFactory(\"text\", textFactory);\n    // `uvquad()` missing\n    // `video()` missing\n\n    return {\n        globalOpt: opt,\n        canvas,\n        app,\n        ggl: gfx,\n        gfx: appGfx,\n        audio,\n        assets,\n        frameRenderer,\n        fontCacheC2d,\n        fontCacheCanvas,\n        game,\n        debug,\n        gc: [] as (() => void)[],\n        sceneScope,\n        appScope,\n        // Patch, k it's only avaible after running kaplay()\n        k: null as unknown as KAPLAYCtx,\n        startLoop() {\n            startEngineLoop(\n                app,\n                game,\n                assets,\n                opt,\n                frameRenderer,\n                debug,\n            );\n        },\n    };\n};\n", "import type { Shape } from \"../types\";\nimport { Rect, vec2 } from \"./math\";\nimport { Vec2 } from \"./Vec2\";\n\nfunction minkowskiRectDifference(r1: Rect, r2: Rect): Rect {\n    return new Rect(\n        vec2(\n            r1.pos.x - (r2.pos.x + r2.width),\n            r1.pos.y - (r2.pos.y + r2.height),\n        ),\n        r1.width + r2.width,\n        r1.height + r2.height,\n    );\n}\n\nexport function minkowskiRectShapeIntersection(shape1: Shape, shape2: Shape) {\n    const s1 = shape1 instanceof Rect\n        ? shape1\n        : shape1.bbox();\n    const s2 = shape2 instanceof Rect\n        ? shape2\n        : shape2.bbox();\n    const res = minkowskiRectDifference(s1, s2);\n\n    if (!res.contains(new Vec2())) {\n        return null;\n    }\n\n    const distance = Math.min(\n        Math.abs(res.pos.x),\n        Math.abs(res.pos.x + res.width),\n        Math.abs(res.pos.y),\n        Math.abs(res.pos.y + res.height),\n    );\n\n    let normal = vec2();\n\n    switch (distance) {\n        case Math.abs(res.pos.x):\n            normal = vec2(1, 0);\n            break;\n        case Math.abs(res.pos.x + res.width):\n            normal = vec2(-1, 0);\n            break;\n        case Math.abs(res.pos.y):\n            normal = vec2(0, 1);\n            break;\n        case Math.abs(res.pos.y + res.height):\n            normal = vec2(0, -1);\n            break;\n    }\n\n    return {\n        normal,\n        distance,\n    };\n}\n", "import type { Shape } from \"../types\";\nimport { Polygon, vec2 } from \"./math\";\nimport { Vec2 } from \"./Vec2\";\n\nexport type SatResult = {\n    normal: Vec2;\n    distance: number;\n};\n\nexport function satShapeIntersection(shape1: Shape, shape2: Shape) {\n    const s1 = shape1 instanceof Polygon\n        ? shape1\n        : new Polygon(shape1.bbox().points());\n    const s2 = shape2 instanceof Polygon\n        ? shape2\n        : new Polygon(shape2.bbox().points());\n    return sat(s1, s2);\n}\n\nexport function sat(p1: Polygon, p2: Polygon): SatResult | null {\n    let overlap = Number.MAX_VALUE;\n    let result: SatResult | null = null;\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) { // This should be <= 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                if (!result) {\n                    result = {\n                        normal: overlap !== 0\n                            ? axisProj.scale(Math.sign(overlap))\n                            : axisProj.scale(Math.sign(min1 - max2)),\n                        distance: Math.abs(overlap),\n                    };\n                }\n                else {\n                    const s = overlap !== 0\n                        ? Math.sign(overlap)\n                        : Math.sign(min1 - max2);\n                    result.normal.x = s * axisProj.x;\n                    result.normal.y = s * axisProj.y;\n                    result.distance = Math.abs(overlap);\n                }\n            }\n        }\n    }\n    return result;\n}\n", "import { DEF_HASH_GRID_SIZE } from \"../../constants/general\";\nimport {\n    type AreaComp,\n    getLocalAreaVersion,\n    getRenderAreaVersion,\n} from \"../../ecs/components/physics/area\";\nimport {\n    getTransformVersion,\n    objectTransformNeedsUpdate,\n} from \"../../ecs/entity/GameObjRaw\";\nimport { exists, isPaused } from \"../../ecs/entity/utils\";\nimport { drawRect } from \"../../gfx/draw/drawRect\";\nimport { loadIdentity, pushMatrix } from \"../../gfx/stack\";\nimport type { GameObj } from \"../../types\";\nimport { type Rect, vec2 } from \"../math\";\nimport { calcTransform } from \"../various\";\nimport type { Vec2 } from \"../Vec2\";\n\nexport type HashGridOpt = {\n    hashGridSize?: number;\n};\n\nexport class HashGrid {\n    bounds: Rect;\n    cellSize: number;\n    columns: number;\n    grid: Array<Array<GameObj<AreaComp>>> = [];\n    hashesForObject: Map<GameObj<AreaComp>, Array<number>> = new Map<\n        GameObj<AreaComp>,\n        Array<number>\n    >();\n    versionsForObject: Map<GameObj<AreaComp>, [number, number, number]> =\n        new Map<\n            GameObj<AreaComp>,\n            [number, number, number]\n        >();\n\n    constructor(bounds: Rect, opt: HashGridOpt) {\n        this.bounds = bounds.clone();\n        this.cellSize = opt.hashGridSize || DEF_HASH_GRID_SIZE;\n        this._clampBoundsToCellSize();\n        this.columns = Math.floor(this.bounds.width / this.cellSize);\n    }\n\n    add(obj: GameObj<AreaComp>) {\n        const bbox = obj.worldBbox();\n        if (!this._isInside(bbox)) {\n            this._resizeToFit(bbox);\n        }\n        // Add the object to all cells covered by its bbox\n        const hashes = this._hashRect(bbox);\n        for (let i = 0; i < hashes.length; i++) {\n            const hash = hashes[i];\n            this._addObjectToGridByHash(obj, hash);\n        }\n        this.hashesForObject.set(obj, hashes);\n        this.versionsForObject.set(obj, [\n            getTransformVersion(obj),\n            getRenderAreaVersion(obj),\n            getLocalAreaVersion(obj),\n        ]);\n    }\n\n    remove(obj: GameObj<AreaComp>) {\n        // Remove the object from all cells it is contained in\n        const hashes = this.hashesForObject.get(obj);\n        if (hashes) {\n            for (let i = 0; i < hashes.length; i++) {\n                const hash = hashes[i];\n                this._removeObjectFromGridByHash(obj, hash);\n            }\n        }\n        this.hashesForObject.delete(obj);\n        this.versionsForObject.delete(obj);\n    }\n\n    clear() {\n        this.grid = [];\n        this.hashesForObject.clear();\n        this.versionsForObject.clear();\n    }\n\n    update() {\n        const oldSet = new Set<number>();\n        const newSet = new Set<number>();\n        for (const [obj, oldHashes] of this.hashesForObject) {\n            // Check if this world area changed since last frame\n            const versions = this.versionsForObject.get(obj);\n            if (\n                versions![0] === getTransformVersion(obj)\n                && versions![1] === getRenderAreaVersion(obj)\n                && versions![2] === getLocalAreaVersion(obj)\n            ) {\n                // No change\n                continue;\n            }\n\n            if (objectTransformNeedsUpdate(obj)) {\n                calcTransform(obj, obj.transform);\n            }\n            else {\n                versions![0] = getTransformVersion(obj);\n            }\n            versions![1] = getRenderAreaVersion(obj);\n            versions![2] = getLocalAreaVersion(obj);\n\n            // Retrieve the old hashes\n            for (let i = 0; i < oldHashes.length; i++) {\n                const hash = oldHashes[i];\n                oldSet.add(hash);\n            }\n            // Get the hashes of the updated world bbox\n            const newHashes = this._hashRect(obj.worldBbox());\n            for (let i = 0; i < newHashes.length; i++) {\n                const hash = newHashes[i];\n                newSet.add(hash);\n            }\n            // Check if there is a difference between old and new hashes\n            if (oldSet.symmetricDifference(newSet).size == 0) {\n                oldSet.clear();\n                newSet.clear();\n                // No change\n                continue;\n            }\n            // Remove the object from cells it no longer occupies\n            for (const hash of oldSet.difference(newSet)) {\n                this._removeObjectFromGridByHash(obj, hash);\n            }\n            // Add the object to newly occupied cells\n            for (const hash of newSet.difference(oldSet)) {\n                this._addObjectToGridByHash(obj, hash);\n            }\n            // Replace the hashes\n            oldHashes.length = 0;\n            for (let i = 0; i < newHashes.length; i++) {\n                const hash = newHashes[i];\n                oldHashes.push(hash);\n            }\n            oldSet.clear();\n            newSet.clear();\n        }\n\n        /*for (const i in this.grid) {\n            loadIdentity();\n            if (this.grid[i].length) {\n                drawRect({\n                    pos: vec2(i % this.columns, Math.floor(i / this.columns))\n                        .scale(this.cellSize),\n                    width: this.cellSize,\n                    height: this.cellSize,\n                });\n            }\n        }*/\n    }\n\n    /**\n     * Iterates all object pairs which potentially collide\n     */\n    iterPairs(\n        pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void,\n    ) {\n        const checked = new Set<GameObj<AreaComp>>();\n        for (const [obj1, hashes] of this.hashesForObject) {\n            if (!isValidCollisionObject(obj1)) continue;\n            checked.add(obj1);\n            const collisions = new Set<GameObj<AreaComp>>();\n            for (let i = 0; i < hashes.length; i++) {\n                const hash = hashes[i];\n                for (const obj2 of this.grid[hash]) {\n                    if (isValidCollisionObject(obj2) && !checked.has(obj2)) {\n                        collisions.add(obj2);\n                    }\n                }\n            }\n            for (const obj2 of collisions) {\n                pairCb(obj1, obj2);\n            }\n        }\n    }\n\n    /**\n     * Retrieves all object which potentially collide with the rectangle\n     */\n    retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void) {\n        // Get the hashes of the covered cells\n        const hashes = this._hashRect(rect);\n        // Collect the objects inside the cells\n        const hits = new Set<GameObj<AreaComp>>();\n        for (let i = 0; i < hashes.length; i++) {\n            const hash = hashes[i];\n            const cell = this.grid[hash];\n            if (cell) {\n                for (let i = 0; i < cell.length; i++) {\n                    hits.add(cell[i]);\n                }\n            }\n        }\n        hits.forEach(retrieveCb);\n    }\n\n    private _hashPoint(point: Vec2) {\n        const x = Math.floor((point.x - this.bounds.pos.x) / this.cellSize);\n        const y = Math.floor((point.y - this.bounds.pos.y) / this.cellSize);\n        return x + y * this.columns;\n    }\n\n    private _hashRect(rect: Rect) {\n        rect = rect.clone();\n\n        // Clamp rect\n        // TODO: remove this once update resizes too\n        if (rect.pos.x < this.bounds.pos.x) {\n            const diff = this.bounds.pos.x - rect.pos.x;\n            rect.pos.x = this.bounds.pos.x;\n            rect.width -= diff;\n        }\n        if (rect.pos.y < this.bounds.pos.y) {\n            const diff = this.bounds.pos.y - rect.pos.y;\n            rect.pos.y = this.bounds.pos.y;\n            rect.height -= diff;\n        }\n        if (rect.pos.x + rect.width > this.bounds.pos.x + this.bounds.width) {\n            rect.width = this.bounds.pos.x + this.bounds.width - rect.pos.x;\n        }\n        if (rect.pos.y + rect.height > this.bounds.pos.y + this.bounds.height) {\n            rect.height = this.bounds.pos.y + this.bounds.height - rect.pos.y;\n        }\n\n        // Calculate hashes\n        const w = Math.floor(this.bounds.width / this.cellSize);\n        let hash = this._hashPoint(rect.pos);\n        const hashes = [];\n        const rw = Math.ceil(rect.width / this.cellSize);\n        const rh = Math.ceil(rect.height / this.cellSize);\n        for (let y = 0; y <= rh; y++) {\n            for (let x = 0; x <= rw; x++) {\n                hashes.push(hash);\n                hash++;\n            }\n            hash += w - rw - 1;\n        }\n        return hashes;\n    }\n\n    private _addObjectToGridByHash(obj: GameObj<AreaComp>, hash: number) {\n        if (!this.grid[hash]) {\n            this.grid[hash] = [];\n        }\n        this.grid[hash].push(obj);\n    }\n\n    private _removeObjectFromGridByHash(obj: GameObj<AreaComp>, hash: number) {\n        const objects = this.grid[hash];\n        const index = objects.indexOf(obj);\n        if (index >= 0) {\n            objects.splice(index, 1);\n        }\n    }\n\n    private _isInside(bbox: Rect) {\n        return bbox.pos.x >= this.bounds.pos.x\n            && bbox.pos.y >= this.bounds.pos.y\n            && bbox.pos.x + bbox.width <= this.bounds.pos.x + this.bounds.width\n            && bbox.pos.y + bbox.height\n                <= this.bounds.pos.y + this.bounds.height;\n    }\n\n    private _resizeToFit(bbox: Rect) {\n        // Rectangle union\n        this.bounds.pos.x = Math.min(this.bounds.pos.x, bbox.pos.x);\n        this.bounds.pos.y = Math.min(this.bounds.pos.y, bbox.pos.y);\n        this.bounds.width = Math.max(\n            this.bounds.pos.x + this.bounds.width,\n            bbox.pos.x + bbox.width,\n        ) - this.bounds.pos.x;\n        this.bounds.height = Math.max(\n            this.bounds.pos.y + this.bounds.height,\n            bbox.pos.y + bbox.height,\n        ) - this.bounds.pos.y;\n\n        this._clampBoundsToCellSize();\n        this.columns = Math.floor(this.bounds.width / this.cellSize);\n\n        // TODO: Recalculate hashes instead of restarting from scratch\n        const objects = [...this.hashesForObject.keys()];\n\n        this.clear();\n\n        for (const obj of objects) {\n            this.add(obj);\n        }\n    }\n\n    private _clampBoundsToCellSize() {\n        this.bounds.pos.x = Math.floor(this.bounds.pos.x / this.cellSize)\n            * this.cellSize;\n        this.bounds.pos.y = Math.floor(this.bounds.pos.y / this.cellSize)\n            * this.cellSize;\n        this.bounds.width = Math.ceil(this.bounds.width / this.cellSize)\n            * this.cellSize;\n        this.bounds.height = Math.ceil(this.bounds.height / this.cellSize)\n            * this.cellSize;\n    }\n}\n\nfunction isValidCollisionObject(obj: GameObj) {\n    return exists(obj) && (obj.isSensor || obj.has(\"body\")) && !isPaused(obj);\n}\n", "import {\n    type AreaComp,\n    getLocalAreaVersion,\n    getRenderAreaVersion,\n} from \"../../ecs/components/physics/area\";\nimport {\n    getTransformVersion,\n    objectTransformNeedsUpdate,\n} from \"../../ecs/entity/GameObjRaw\";\nimport { exists, isPaused } from \"../../ecs/entity/utils\";\nimport type { GameObj } from \"../../types\";\nimport type { Rect } from \"../math\";\nimport { calcTransform } from \"../various\";\nimport type { BroadPhaseAlgorithm } from \".\";\n\n/**\n * Left or right edge of an object's bbox\n */\nclass SapEdgeHorizontal {\n    obj: GameObj<AreaComp>;\n    x: number;\n    isLeft: boolean;\n\n    constructor(obj: GameObj<AreaComp>, isLeft: boolean) {\n        this.obj = obj;\n        this.x = 0;\n        this.isLeft = isLeft;\n    }\n}\n\n/**\n * One dimensional horizontal sweep and prune\n *\n * @ignore\n */\nexport class SweepAndPruneHorizontal implements BroadPhaseAlgorithm {\n    edges: Array<SapEdgeHorizontal>;\n    objects: Map<GameObj<AreaComp>, [SapEdgeHorizontal, SapEdgeHorizontal]>;\n    versionsForObject: Map<GameObj<AreaComp>, [number, number, number]> =\n        new Map<\n            GameObj<AreaComp>,\n            [number, number, number]\n        >();\n\n    constructor() {\n        this.edges = [];\n        this.objects = new Map<\n            GameObj<AreaComp>,\n            [SapEdgeHorizontal, SapEdgeHorizontal]\n        >();\n    }\n\n    /**\n     * Add the object and its edges to the list\n     * @param obj - The object to add\n     */\n    add(obj: GameObj<AreaComp>) {\n        const left = new SapEdgeHorizontal(obj, true);\n        const right = new SapEdgeHorizontal(obj, false);\n        this.edges.push(left);\n        this.edges.push(right);\n        this.objects.set(obj, [left, right]);\n        this.versionsForObject.set(obj, [\n            -1,\n            -1,\n            -1,\n        ]);\n    }\n\n    /**\n     * Remove the object and its edges from the list\n     * @param obj - The object to remove\n     */\n    remove(obj: GameObj<AreaComp>) {\n        const pair = this.objects.get(obj);\n        if (pair) {\n            this.edges.splice(this.edges.indexOf(pair[0]), 1);\n            this.edges.splice(this.edges.indexOf(pair[1]), 1);\n            this.objects.delete(obj);\n            this.versionsForObject.delete(obj);\n        }\n    }\n\n    clear() {\n        this.edges = [];\n        this.objects.clear();\n    }\n\n    /**\n     * Update edges and sort\n     */\n    update() {\n        // Update edge data\n        for (const [obj, edges] of this.objects.entries()) {\n            if (!exists(obj)) continue;\n\n            // Check if this world area changed since last frame\n            const versions = this.versionsForObject.get(obj);\n            if (\n                versions![0] === getTransformVersion(obj)\n                && versions![1] === getRenderAreaVersion(obj)\n                && versions![2] === getLocalAreaVersion(obj)\n            ) {\n                // No change\n                continue;\n            }\n\n            if (objectTransformNeedsUpdate(obj)) {\n                calcTransform(obj, obj.transform);\n            }\n            else {\n                versions![0] = getTransformVersion(obj);\n            }\n            versions![1] = getRenderAreaVersion(obj);\n            versions![2] = getLocalAreaVersion(obj);\n\n            const bbox = obj.worldBbox();\n            edges[0].x = bbox.pos.x;\n            edges[1].x = bbox.pos.x + bbox.width;\n        }\n        // Insertion sort is ~O(n) for nearly-sorted lists - which this will be\n        // on all but the first iteration. The builtin Array.sort() can't make\n        // this guarantee of speed -- JS engines typically use various other sorting\n        // algorithms (introsort, mergesort, selection sort, treesort, etc.) that don't\n        // have this nice property.\n        //\n        // There's an insertionSort() function elsewhere, but inlining it here\n        // offers some speed benefits especially with dumber JS optimizers that\n        // won't or can't automatically inline \"hot\" functions.\n        for (let i = 1; i < this.edges.length; i++) {\n            for (let j = i - 1; j >= 0; j--) {\n                if (this.edges[j].x < this.edges[j + 1].x) break;\n                const temp = this.edges[j];\n                this.edges[j] = this.edges[j + 1];\n                this.edges[j + 1] = temp;\n            }\n        }\n    }\n\n    /**\n     * Iterates all object pairs which potentially collide\n     */\n    iterPairs(\n        pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void,\n    ) {\n        const touching = new Set<GameObj<AreaComp>>();\n\n        for (const edge of this.edges) {\n            if (edge.isLeft) {\n                if (isValidCollisionObject(edge.obj)) {\n                    for (const obj of touching) {\n                        if (isValidCollisionObject(obj)) {\n                            pairCb(obj, edge.obj);\n                        }\n                    }\n                }\n                touching.add(edge.obj);\n            }\n            else {\n                touching.delete(edge.obj);\n            }\n        }\n    }\n\n    retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void) {\n        const left = rect.pos.x;\n        const right = left + rect.width;\n        const hits = new Set<GameObj<AreaComp>>();\n        for (const edge of this.edges) {\n            if (edge.isLeft) {\n                if (edge.x < right) {\n                    hits.add(edge.obj);\n                }\n            }\n            else {\n                if (edge.x < left) {\n                    hits.delete(edge.obj);\n                }\n            }\n        }\n        hits.forEach(retrieveCb);\n    }\n}\n\n/**\n * Left or right edge of an object's bbox\n */\nclass SapEdgeVertical {\n    obj: GameObj<AreaComp>;\n    y: number;\n    isTop: boolean;\n\n    constructor(obj: GameObj<AreaComp>, isTop: boolean) {\n        this.obj = obj;\n        this.y = 0;\n        this.isTop = isTop;\n    }\n}\n\n/**\n * One dimensional vertical sweep and prune\n *\n * @ignore\n */\nexport class SweepAndPruneVertical implements BroadPhaseAlgorithm {\n    edges: Array<SapEdgeVertical>;\n    objects: Map<GameObj<AreaComp>, [SapEdgeVertical, SapEdgeVertical]>;\n    versionsForObject: Map<GameObj<AreaComp>, [number, number, number]> =\n        new Map<\n            GameObj<AreaComp>,\n            [number, number, number]\n        >();\n\n    constructor() {\n        this.edges = [];\n        this.objects = new Map<\n            GameObj<AreaComp>,\n            [SapEdgeVertical, SapEdgeVertical]\n        >();\n    }\n\n    /**\n     * Add the object and its edges to the list\n     * @param obj - The object to add\n     */\n    add(obj: GameObj<AreaComp>) {\n        const top = new SapEdgeVertical(obj, true);\n        const bottom = new SapEdgeVertical(obj, false);\n        this.edges.push(top);\n        this.edges.push(bottom);\n        this.objects.set(obj, [top, bottom]);\n        this.versionsForObject.set(obj, [-1, -1, -1]);\n    }\n\n    /**\n     * Remove the object and its edges from the list\n     * @param obj - The object to remove\n     */\n    remove(obj: GameObj<AreaComp>) {\n        const pair = this.objects.get(obj);\n        if (pair) {\n            this.edges.splice(this.edges.indexOf(pair[0]), 1);\n            this.edges.splice(this.edges.indexOf(pair[1]), 1);\n            this.objects.delete(obj);\n            this.versionsForObject.delete(obj);\n        }\n    }\n\n    clear() {\n        this.edges = [];\n        this.objects.clear();\n    }\n\n    /**\n     * Update edges and sort\n     */\n    update() {\n        // Update edge data\n        for (const [obj, edges] of this.objects.entries()) {\n            if (!exists(obj)) continue;\n\n            // Check if this world area changed since last frame\n            const versions = this.versionsForObject.get(obj);\n            if (\n                versions![0] === getTransformVersion(obj)\n                && versions![1] === getRenderAreaVersion(obj)\n                && versions![2] === getLocalAreaVersion(obj)\n            ) {\n                // No change\n                continue;\n            }\n\n            if (objectTransformNeedsUpdate(obj)) {\n                calcTransform(obj, obj.transform);\n            }\n            else {\n                versions![0] = getTransformVersion(obj);\n            }\n            versions![1] = getRenderAreaVersion(obj);\n            versions![2] = getLocalAreaVersion(obj);\n\n            const bbox = obj.worldBbox();\n            edges[0].y = bbox.pos.y;\n            edges[1].y = bbox.pos.y + bbox.height;\n        }\n        // Insertion sort is ~O(n) for nearly-sorted lists - which this will be\n        // on all but the first iteration. The builtin Array.sort() can't make\n        // this guarantee of speed -- JS engines typically use various other sorting\n        // algorithms (introsort, mergesort, selection sort, treesort, etc.) that don't\n        // have this nice property.\n        //\n        // There's an insertionSort() function elsewhere, but inlining it here\n        // offers some speed benefits especially with dumber JS optimizers that\n        // won't or can't automatically inline \"hot\" functions.\n        for (let i = 1; i < this.edges.length; i++) {\n            for (let j = i - 1; j >= 0; j--) {\n                if (this.edges[j].y < this.edges[j + 1].y) break;\n                const temp = this.edges[j];\n                this.edges[j] = this.edges[j + 1];\n                this.edges[j + 1] = temp;\n            }\n        }\n    }\n\n    /**\n     * Iterates all object pairs which potentially collide\n     */\n    iterPairs(\n        pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void,\n    ): void {\n        const touching = new Set<GameObj<AreaComp>>();\n\n        for (const edge of this.edges) {\n            if (edge.isTop) {\n                if (isValidCollisionObject(edge.obj)) {\n                    for (const obj of touching) {\n                        if (isValidCollisionObject(obj)) {\n                            pairCb(obj, edge.obj);\n                        }\n                    }\n                }\n                touching.add(edge.obj);\n            }\n            else {\n                touching.delete(edge.obj);\n            }\n        }\n    }\n\n    retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void) {\n        const top = rect.pos.y;\n        const bottom = top + rect.height;\n        const hits = new Set<GameObj<AreaComp>>();\n        for (const edge of this.edges) {\n            if (edge.isTop) {\n                if (edge.y < bottom) {\n                    hits.add(edge.obj);\n                }\n            }\n            else {\n                if (edge.y < top) {\n                    hits.delete(edge.obj);\n                }\n            }\n        }\n        hits.forEach(retrieveCb);\n    }\n}\n\nfunction isValidCollisionObject(obj: GameObj) {\n    return obj.exists() && (obj.isSensor || obj.has(\"body\")) && !isPaused(obj);\n}\n", "import { DEF_HASH_GRID_SIZE } from \"../../constants/general\";\nimport { height, width } from \"../../gfx/stack\";\nimport { gjkShapeIntersection } from \"../../math/gjk\";\nimport { Rect, vec2 } from \"../../math/math\";\nimport { minkowskiRectShapeIntersection } from \"../../math/minkowski\";\nimport { satShapeIntersection } from \"../../math/sat\";\nimport type { BroadPhaseAlgorithm } from \"../../math/spatial\";\nimport { HashGrid } from \"../../math/spatial/hashgrid\";\nimport { Quadtree } from \"../../math/spatial/quadtree\";\nimport {\n    SweepAndPruneHorizontal,\n    SweepAndPruneVertical,\n} from \"../../math/spatial/sweepandprune\";\nimport { _k } from \"../../shared\";\nimport type { GameObj } from \"../../types\";\nimport { type AreaComp, usesArea } from \"../components/physics/area\";\nimport { Collision } from \"./Collision\";\nexport type BroadPhaseType = \"sap\" | \"sapv\" | \"quadtree\" | \"grid\";\nexport type NarrowPhaseType = \"gjk\" | \"sat\" | \"box\";\n\nexport const createCollisionSystem = (\n    { broad = \"sap\", narrow = \"gjk\", opt = {} }: {\n        broad?: BroadPhaseType;\n        narrow?: NarrowPhaseType;\n        opt?: any;\n    } = {},\n) => {\n    const broadPhaseIntersection: BroadPhaseAlgorithm = broad === \"sap\"\n        ? new SweepAndPruneHorizontal()\n        : broad === \"sapv\"\n        ? new SweepAndPruneVertical()\n        : broad === \"quadtree\"\n        ? new Quadtree(new Rect(vec2(0, 0), width(), height()), 8, 8)\n        : broad == \"grid\"\n        ? new HashGrid(\n            new Rect(\n                vec2(-DEF_HASH_GRID_SIZE, -DEF_HASH_GRID_SIZE),\n                width() + DEF_HASH_GRID_SIZE * 2,\n                height() + DEF_HASH_GRID_SIZE * 2,\n            ),\n            opt,\n        )\n        : new SweepAndPruneHorizontal();\n    const narrowPhaseIntersection = narrow === \"gjk\"\n        ? gjkShapeIntersection\n        : narrow === \"sat\"\n        ? satShapeIntersection\n        : narrow === \"box\"\n        ? minkowskiRectShapeIntersection\n        : gjkShapeIntersection;\n\n    function narrowPhase(\n        obj: GameObj<AreaComp>,\n        other: GameObj<AreaComp>,\n    ): boolean {\n        for (const tag of obj.collisionIgnore) {\n            if (other.is(tag)) {\n                return false;\n            }\n        }\n        for (const tag of other.collisionIgnore) {\n            if (obj.is(tag)) {\n                return false;\n            }\n        }\n        const res = narrowPhaseIntersection(obj.worldArea(), other.worldArea());\n        if (res) {\n            const col1 = new Collision(\n                obj,\n                other,\n                res.normal,\n                res.distance,\n            );\n            obj.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\", obj, col2);\n        }\n        return true;\n    }\n\n    let broadInit = false;\n\n    function broadPhase() {\n        if (!broadInit) {\n            broadInit = true;\n            _k.appScope.onAdd(obj => {\n                if (obj.has(\"area\")) {\n                    broadPhaseIntersection.add(obj as GameObj<AreaComp>);\n                }\n            });\n            _k.appScope.onDestroy(obj => {\n                broadPhaseIntersection.remove(obj as GameObj<AreaComp>);\n            });\n            _k.appScope.onUse((obj, id) => {\n                if (id === \"area\") {\n                    broadPhaseIntersection.add(obj as GameObj<AreaComp>);\n                }\n            });\n            _k.appScope.onUnuse((obj, id) => {\n                if (id === \"area\") {\n                    broadPhaseIntersection.remove(obj as GameObj<AreaComp>);\n                }\n            });\n\n            for (const obj of _k.game.root.get(\"*\", { recursive: true })) {\n                if (obj.has(\"area\")) {\n                    broadPhaseIntersection.add(obj as GameObj<AreaComp>);\n                }\n            }\n        }\n\n        broadPhaseIntersection.update();\n        broadPhaseIntersection.iterPairs(narrowPhase);\n    }\n\n    function checkFrame() {\n        if (!usesArea()) {\n            return;\n        }\n\n        return broadPhase();\n    }\n\n    function retrieve(\n        rect: Rect,\n        retrieveCb: (obj: GameObj<AreaComp>) => void,\n    ) {\n        broadPhaseIntersection.retrieve(rect, retrieveCb);\n    }\n\n    return {\n        checkFrame,\n        retrieve,\n    };\n};\n", "// The definitive version!\nimport { SoundData } from \"./assets/sound\";\nimport { loadSprite } from \"./assets/sprite\";\nimport { createEmptyAudioBuffer } from \"./audio/audio\";\nimport { createContext } from \"./core/context\";\nimport type { KAPLAYCtx } from \"./core/contextType\";\nimport { createEngine } from \"./core/engine\";\nimport type {\n    KAPLAYCtxT,\n    KAPLAYOptTypeOptions,\n    KAPLAYTypeOptWithoutPlugins,\n    TypesOpt,\n} from \"./core/taf\";\nimport beanSrc from \"./data/assets/bean.png\";\nimport boomSpriteSrc from \"./data/assets/boom.png\";\nimport burpSoundSrc from \"./data/assets/burp.mp3\";\nimport happyFontSrc from \"./data/assets/happy.png\";\nimport kaSpriteSrc from \"./data/assets/ka.png\";\nimport { _setTopMostOnlyActivate } from \"./ecs/components/physics/area\";\nimport { createCollisionSystem } from \"./ecs/systems/createCollisionSystem\";\nimport { system, SystemPhase } from \"./ecs/systems/systems\";\nimport { _k, updateEngine } from \"./shared\";\nimport {\n    type KAPLAYOpt,\n    type KAPLAYPlugin,\n    type MergePlugins,\n    type PluginList,\n} from \"./types\";\n\n// If kaplay() was already called\nlet ran = false;\n\ntype HasDefinedKeys<TObj, TCheck> = {\n    [K in keyof TCheck & keyof TObj]: TObj[K] extends undefined ? never : K;\n}[keyof TCheck & keyof TObj] extends never ? never : TObj;\n\ntype ChooseKAPLAYCtx<O extends KAPLAYOptTypeOptions> =\n    HasDefinedKeys<O, KAPLAYTypeOptWithoutPlugins> extends never ? KAPLAYCtx\n        : KAPLAYCtxT<O>;\n\ntype KAPLAYGame<O extends KAPLAYOptTypeOptions | undefined> = O extends\n    KAPLAYOptTypeOptions ? O[\"plugins\"] extends PluginList<any> ?\n            & ChooseKAPLAYCtx<O>\n            & MergePlugins<O[\"plugins\"]>\n    : ChooseKAPLAYCtx<O>\n    : KAPLAYCtx;\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 */\nexport const kaplay = <\n    O extends KAPLAYOpt,\n>(\n    opt?: O,\n): KAPLAYGame<O> => {\n    if (ran) {\n        console.warn(\n            \"kaplay() was called a second time, cleaning up previous state...\",\n        );\n\n        // cleanup\n        // @ts-ignore\n        updateEngine(null);\n    }\n\n    const gopt = opt ?? {} as KAPLAYOpt;\n\n    ran = true;\n\n    updateEngine(createEngine(gopt));\n\n    const {\n        app,\n        game,\n        audio,\n    } = _k;\n\n    const { checkFrame, retrieve } = createCollisionSystem({\n        broad: gopt.broadPhaseCollisionAlgorithm || \"sap\",\n        narrow: gopt.narrowPhaseCollisionAlgorithm || \"gjk\",\n        opt: gopt,\n    });\n\n    game.retrieve = retrieve;\n\n    _setTopMostOnlyActivate(gopt.topMostOnlyActivate ?? false);\n\n    system(\"collision\", checkFrame, [\n        SystemPhase.AfterFixedUpdate,\n        SystemPhase.AfterUpdate,\n    ]);\n\n    // #region Loading default assets\n    game.defaultAssets.ka = loadSprite(null, kaSpriteSrc);\n    game.defaultAssets.boom = loadSprite(null, boomSpriteSrc);\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(audio.ctx));\n\n    // load that burp sound\n    audio.ctx.decodeAudioData(burpSoundSrc.buffer.slice(0) as ArrayBuffer).then(\n        (buf) => {\n            burpSnd.buf = buf;\n            game.defaultAssets.burp = burpSnd;\n        },\n    ).catch((err) => {\n        console.error(\"Failed to load burp: \", err);\n    });\n\n    game.defaultAssets.bean = beanSrc;\n    game.defaultAssets.happy = happyFontSrc;\n    // #endregion\n\n    _k.startLoop();\n\n    // the exported ctx handle\n    const ctx: KAPLAYCtx = createContext(\n        _k,\n        gopt.plugins as KAPLAYPlugin<Record<string, unknown>>[],\n        gopt.global !== false,\n    );\n\n    if (gopt.focus !== false) {\n        app.canvas.focus();\n    }\n\n    return ctx as KAPLAYGame<O>;\n};\n\nexport const kaplayTypes = <T extends TypesOpt = TypesOpt>(): T => {\n    return null as unknown as T;\n};\n\nexport default kaplay;\n"],
  "mappings": "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EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EACpDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EACnDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EACnDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EACnDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,EAAE,EAAI,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EACnDC,EAAM,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EAAI,KAAK,EAAE,CAAC,EAExDzB,EAAI,CAAC,EAAI,KAAK,EAAE,CAAC,EAAIO,EAAM,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",
  "names": ["_k", "updateEngine", "e", "base64ToArrayBuffer", "base64", "binstr", "len", "bytes", "i", "dataURLToArrayBuffer", "url", "download", "filename", "a", "downloadText", "text", "downloadJSON", "data", "downloadBlob", "blob", "isDataURL", "str", "getFileName", "p", "gamepad_default", "ASCII_CHARS", "DEF_ANCHOR", "BG_GRID_SIZE", "DEF_FONT", "DBG_FONT", "DEF_TEXT_SIZE", "DEF_TEXT_CACHE_SIZE", "MAX_TEXT_CACHE_SIZE", "SPRITE_ATLAS_WIDTH", "SPRITE_ATLAS_HEIGHT", "DEF_HASH_GRID_SIZE", "LOG_MAX", "LOG_TIME", "VERTEX_FORMAT", "STRIDE", "sum", "f", "MAX_BATCHED_QUAD", "MAX_BATCHED_VERTS", "MAX_BATCHED_INDICES", "VERT_TEMPLATE", "FRAG_TEMPLATE", "DEF_VERT", "DEF_FRAG", "DEF_OFFSCREEN_DIS", "DEF_JUMP_FORCE", "MAX_VEL", "EVENT_CANCEL_SYMBOL", "GP_MAP", "gamepad_default", "MAX_TRIES", "exists", "obj", "destroy", "getTreeRoot", "_k", "isFixed", "isPaused", "Registry", "v", "id", "KEventController", "_KEventController", "cancel", "events", "ev", "e", "p", "oldEv", "newEv", "KEvent", "action", "handler", "args", "isPaused", "res", "result", "EVENT_CANCEL_SYMBOL", "KEventHandler", "name", "BlendMode", "SpriteData", "_SpriteData", "frames", "anims", "slice9", "src", "opt", "spriteSrcToImage", "img", "data", "filter", "_k", "fixFramesPixelsToFractionOfImage", "slice", "tex", "quad", "id", "f", "frame", "resolveSprite", "spr", "getSprite", "loadProgress", "Asset", "name", "loadSprite", "fixURL", "s", "loadImg", "images", "loadBean", "width", "height", "q", "clamp", "val", "min", "max", "CSS_COLOR_MAP", "lerpNumber", "a", "b", "t", "Color", "_Color", "r", "g", "b", "clamp", "arr", "hex", "result", "h", "s", "l", "hue2rgb", "p", "q", "t", "cssColor", "color", "CSS_COLOR_MAP", "a", "other", "dest", "lerpNumber", "max", "min", "d", "data", "rgb", "args", "cl", "hsl2rgb", "Vec2", "_Vec2", "x", "y", "deg", "angle", "deg2rad", "arr", "v", "out", "args", "p2", "vec2", "other", "s", "len", "normal", "on", "vecOrAngle", "c", "dir", "tmp", "rad2deg", "dest", "t", "lerpNumber", "src", "dst", "cos", "sin", "t1", "t2", "invSin", "n", "m", "Rect", "data", "traceRegion", "width", "height", "isInRegion", "RDP", "epsilon", "directions", "Vec2", "start", "y", "x", "outline", "current", "prevDir", "dir", "i", "d", "nx", "ny", "simplifyClosed", "points", "open", "simplified", "getDistance", "c", "a", "b", "A", "B", "C", "start_indx", "end_indx", "max_dist", "max_indx", "l", "r", "lerp", "a", "b", "t", "Vec2", "Color", "deg2rad", "deg", "rad2deg", "rad", "map", "v", "l1", "h1", "l2", "h2", "mapc", "clamp", "step", "edge", "x", "smoothstep", "edge0", "edge1", "vec2", "args", "Vec2", "Quad", "_Quad", "y", "w", "h", "other", "quad", "Mat2", "_Mat2", "a", "b", "c", "d", "point", "det", "m", "e1", "e2", "radians", "s", "Mat23", "_Mat23", "e", "f", "t", "angle", "sx", "sy", "degrees", "oldA", "oldB", "p", "o", "tmp", "r", "Mat3", "_Mat3", "m11", "m12", "m13", "m21", "m22", "m23", "m31", "m32", "m33", "wave", "lo", "hi", "lerp", "A", "C", "M", "RNG", "seed", "Color", "rgb", "randSeed", "_k", "rand", "randi", "chance", "shuffle", "list", "i", "j", "chooseMultiple", "count", "choose", "testRectRect", "r1", "r2", "testLineLineT", "l1", "l2", "denom", "ua", "ub", "testLineLine", "t", "vec2", "clipLineToRect", "r", "l", "result", "dir", "tmin", "tmax", "tx1", "tx2", "ty1", "ty2", "Vec2", "testRectLine", "testRectPoint", "r", "pt", "testRectCircle", "c", "nx", "ny", "vec2", "testRectPolygon", "p", "testPolygonPolygon", "Polygon", "testLinePoint", "l", "v1", "v2", "t", "clipLineToCircle", "circle", "result", "v", "a", "centerToOrigin", "b", "dis", "testCirclePoint", "Vec2", "t1", "t2", "b1", "b2", "testLineCircle", "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", "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", "p", "fraction", "raycastGrid", "gridPosHit", "maxDistance", "pos", "len", "dir", "gridPos", "step", "tDelta", "dist", "tMax", "steppedIndex", "Point", "_Point", "pt", "m", "r", "Rect", "shape", "testPointShape", "_Line", "p1", "p2", "testLineShape", "rand", "Vec2", "v1", "v2", "_Rect", "width", "height", "Polygon", "min", "max", "dx", "dy", "testRectShape", "pts", "maxPoint", "vertex", "distance", "_Circle", "center", "radius", "tr", "Ellipse", "testCircleShape", "_Ellipse", "rx", "ry", "degrees", "inv", "M", "e1", "e2", "b", "rad2deg", "angle", "scale", "Mat3", "ux", "uy", "vx", "vy", "halfwidth", "halfheight", "testEllipseShape", "axis", "segmentLineIntersection", "getSpriteOutline", "asset", "frame", "RDP", "epsilon", "spr", "resolveSprite", "frameData", "px", "py", "pw", "ph", "canvas", "ctx", "image_data", "isInRegion", "x", "idx", "trace", "traceRegion", "_Polygon", "i", "total", "l", "testPolygonShape", "srcUv", "dstUv", "surfaceLine", "left", "right", "ap", "wasLeft", "index", "isLeft", "intersection", "uv1", "uv2", "alpha", "uv", "lerp", "pp", "evaluateQuadratic", "pt1", "pt2", "pt3", "t", "t2", "mt", "mt2", "evaluateQuadraticFirstDerivative", "evaluateQuadraticSecondDerivative", "evaluateBezier", "pt4", "t3", "mt3", "evaluateBezierFirstDerivative", "evaluateBezierSecondDerivative", "evaluateCatmullRom", "A", "B", "C", "D", "evaluateCatmullRomFirstDerivative", "normalizedCurve", "curve", "curveLength", "curveLengthApproximation", "length", "s", "l", "entries", "detail", "llut", "tlut", "ddt", "pp", "e", "d", "inverse", "index", "t1", "l1", "l2", "a", "hermite", "m1", "m2", "cardinal", "tension", "h", "hx", "hy", "Vec2", "catmullRom", "bezier", "kochanekBartels", "continuity", "bias", "hermiteFirstDerivative", "piecewiseBezier", "pts", "beziers", "totalLength", "i", "bezierCurve", "fromLength", "toLength", "b", "map", "reflect", "piecewiseCatmullRom", "curves", "addCurve", "firstPt", "lastPt", "inZeroOneDomain", "approximately", "cubeRoot", "v", "getCubicRoots", "pa", "pb", "pc", "pd", "c", "q", "a2", "p", "p3", "q2", "discriminant", "mp3", "mp33", "r", "cosphi", "phi", "root1", "root2", "root3", "u1", "sd", "v1", "cubicBezierYforX", "x", "easingLinear", "keys", "len", "easingCubicBezier", "p1", "p2", "vec2", "easingSteps", "steps", "position", "xdist", "jumpStart", "jumpEnd", "ydist", "startY", "step", "isOrientedCcw", "isOrientedCcwPolygon", "polygon", "total", "prev", "onSameSide", "px", "py", "m", "pointInTriangle", "someInTriangle", "vertices", "isEar", "triangulate", "nextIdx", "prevIdx", "idx", "lm", "pt", "concaveVertices", "triangles", "nVertices", "current", "skipped", "next", "isConvex", "j", "k", "winding", "fixURL", "url", "isDataURL", "_k", "drawImageSourceAt", "c2d", "src", "atX", "atY", "cutX", "cutY", "cutWidth", "cutHeight", "slice", "x", "y", "dx", "dy", "w", "h", "frames", "qw", "qh", "j", "i", "Quad", "Mat4", "_Mat4", "m", "p", "s", "a", "deg2rad", "c", "m0", "m1", "m4", "m5", "other", "out", "i", "j", "Vec2", "det", "r", "rad2deg", "f00", "f01", "f02", "f03", "f04", "f05", "f06", "f07", "f08", "f09", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "IDENTITY_MATRIX", "Mat4", "TOP_LEFT", "Vec2", "TOP", "TOP_RIGHT", "LEFT", "CENTER", "RIGHT", "BOTTOM_LEFT", "BOTTOM", "BOTTOM_RIGHT", "color", "args", "rgb", "colorFactory", "data", "Color", "c2", "c3", "c4", "c5", "easings", "x", "toFixed", "n", "f", "opacity", "a", "time", "easeFunc", "easings", "toValue", "_k", "toFixed", "opacityFactory", "data", "getRenderProps", "obj", "calcTransform", "obj", "tr", "updateTransformRecursive", "i", "updateChildrenTransformRecursive", "clampAngle", "angle", "getArcPts", "pos", "radiusX", "radiusY", "start", "end", "res", "deg2rad", "isLoop", "pts", "nverts", "step", "v", "vec2", "r", "i", "anchorPt", "orig", "TOP_LEFT", "TOP", "TOP_RIGHT", "LEFT", "CENTER", "RIGHT", "BOTTOM_LEFT", "BOTTOM", "BOTTOM_RIGHT", "alignPt", "align", "pushTransform", "_k", "popTransform", "multTranslateV", "_k", "multTranslate", "x", "y", "multRotate", "angle", "multScaleV", "s", "multSkewV", "s", "_k", "loadMatrix", "m", "_k", "storeMatrix", "flush", "width", "height", "center", "vec2", "usePostEffect", "name", "uniform", "arrayIsColor", "arr", "Color", "arrayIsVec2", "Vec2", "arrayIsNumber", "getErrorMessage", "error", "warn", "msg", "_k", "deprecateMsg", "oldName", "newName", "TextureUnitManager", "_TextureUnitManager", "texture", "unit", "gl", "_k", "Shader", "ctx", "vert", "frag", "attribs", "vertShader", "fragShader", "prog", "attrib", "i", "vertError", "fragError", "linkError", "uniform", "name", "val", "loc", "Mat4", "Mat23", "Color", "Vec2", "Texture", "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", "lineContents", "resolveShader", "src", "shader", "getShader", "loadProgress", "Asset", "loadShader", "loadShaderURL", "fixURL", "resolveUrl", "url", "fetchText", "load", "drawRaw", "attributes", "indices", "fixed", "tex", "shaderSrc", "uniform", "blend", "parsedTex", "_k", "parsedShader", "shader", "resolveShader", "Asset", "transform", "vertLength", "vv", "index", "i", "width", "height", "drawLine", "opt", "p1", "p2", "w", "dis", "color", "Color", "opacity", "attributes", "drawRaw", "_k", "_drawLinesBevel", "pts", "vertices", "halfWidth", "centerOffset", "lerp", "isLoop", "offset", "vec2", "segment", "length", "normal", "pt1", "pt2", "dir", "n", "angle", "vector", "cs", "sn", "p", "j", "i", "nextSegment", "nextLength", "nextNormal", "det", "lambda", "d", "indices", "index", "_drawLinesRound", "deg2rad", "fixedPoint", "_drawLinesMiter", "drawLines", "width", "drawPolygon", "opt", "npts", "pushTransform", "multTranslateV", "multRotate", "multScaleV", "multSkewV", "color", "Color", "attributes", "i", "indices", "triangulate", "t", "p", "n", "drawRaw", "_k", "drawLines", "popTransform", "drawRect", "opt", "w", "h", "offset", "anchorPt", "DEF_ANCHOR", "Vec2", "pts", "maxRadius", "r", "getArcPts", "vec2", "drawPolygon", "drawEllipse", "opt", "start", "end", "offset", "anchorPt", "Vec2", "pts", "getArcPts", "polyOpt", "drawPolygon", "drawCircle", "opt", "drawEllipse", "drawUVQuad", "opt", "w", "h", "anchor", "anchorPt", "DEF_ANCHOR", "offsetX", "offsetY", "q", "Quad", "color", "Color", "opacity", "pushTransform", "multTranslateV", "multRotate", "multScaleV", "multSkewV", "multTranslate", "drawRaw", "popTransform", "drawFormattedText", "ftext", "pushTransform", "multTranslateV", "multRotate", "anchorPt", "charsByTexture", "ch", "chars", "drawUVQuad", "popTransform", "getBitmapFont", "name", "_k", "loadBitmapFont", "src", "gw", "gh", "opt", "fontSrc", "fixURL", "loadImg", "img", "makeFont", "ASCII_CHARS", "loadBitmapFontFromSprite", "spriteID", "chars", "splittedChars", "spr", "frames", "h", "c", "i", "loadHappy", "fontName", "FontData", "fontface", "opt", "_k", "DEF_TEXT_CACHE_SIZE", "MAX_TEXT_CACHE_SIZE", "rgb", "resolveFont", "src", "DEF_FONT", "bfont", "getBitmapFont", "font", "getFont", "loadProgress", "Asset", "name", "loadFont", "err", "face", "makeFont", "tex", "gw", "gh", "chars", "filter", "w", "h", "cols", "map", "charMap", "i", "ch", "Quad", "GRAPHEMES", "segmenterCache", "getSegmenter", "locale", "key", "segmenter", "runes", "string", "normalized", "segment", "runesLegacy", "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", "applyCharTransform", "fchar", "tr", "vec2", "compileStyledText", "txt", "charStyleMap", "renderText", "styleStack", "text", "emit", "ch", "execResult", "m", "endSlash", "theTagName", "tagParam", "expectedTagName", "arg", "getFontName", "font", "FontData", "getFontAtlasForFont", "fontName", "atlas", "_k", "f", "DEF_TEXT_CACHE_SIZE", "allChars", "renderableChars", "i", "updateFontAtlas", "c2d", "ascent", "descent", "safeOffset", "w", "h", "p", "x", "y", "rgb", "img", "formatText", "opt", "resolveFont", "Asset", "chars", "runes", "fontAtlas", "defGfxFont", "size", "sizeScale", "scale", "lineSpacing", "letterSpacing", "baselineCenterOffset", "curX", "tw", "lines", "curLine", "cursor", "lastSpace", "lastSpaceWidth", "paraIndentX", "defaultFontValue", "theFChar", "Color", "styles", "name", "param", "style", "requestedFont", "resolvedFont", "requestedFontData", "requestedFontScale", "charWidth", "formattedChars", "th", "ox", "alignPt", "thisLineHeight", "drawText", "opt", "drawFormattedText", "formatText", "drawUnscaled", "content", "flush", "ow", "_k", "oh", "throwError", "err", "handleErr", "_k", "error", "showErrorScreen", "drawUnscaled", "gw", "width", "gh", "height", "textStyle", "DBG_FONT", "drawRect", "rgb", "title", "formatText", "vec2", "drawFormattedText", "drawText", "esc", "popTransform", "drawStenciled", "content", "mask", "test", "gl", "_k", "flush", "drawMasked", "content", "mask", "gl", "_k", "drawStenciled", "Picture", "data", "command", "drawPicture", "picture", "opt", "w", "width", "h", "height", "_k", "transform", "ctx", "gl", "a_pos", "a_uv", "a_color", "lastShader", "lastTexture", "texture", "shader", "IDENTITY_MATRIX", "getCamTransform", "beginPicture", "appendToPicture", "endPicture", "Mesh", "drawSubtracted", "content", "mask", "gl", "_k", "drawStenciled", "FrameBuffer", "ctx", "w", "h", "opt", "gl", "Texture", "frameBuffer", "renderBuffer", "data", "bytesPerRow", "temp", "y", "topOffset", "bottomOffset", "canvas", "action", "makeInternal", "id", "compsAndTags", "addCompIdsToTags", "_k", "obj", "GameObjRawPrototype", "currentMaking", "KEventHandler", "KEvent", "Mat23", "comps", "tagList", "compOrTag", "compId", "comp", "tag", "make", "internalIsMaking", "factoryMethods", "registerPrefabFactory", "id", "factoryMethod", "deserializePrefabAsset", "serializedPrefab", "list", "tag", "loadPrefab", "name", "url", "_k", "fetchJSON", "fixURL", "createPrefab", "nameOrObject", "object", "data", "Asset", "KeepFlags", "_nextTreeIndex", "resetTreeIndex", "_lastTransformVersion", "_nextTransformVersion", "nextTransformVersion", "updateLastTransformVersion", "transformNeedsUpdate", "version", "objectTransformNeedsUpdate", "obj", "getTransformVersion", "COMP_DESC", "COMP_EVENTS", "GameObjRawPrototype", "p", "index", "opt", "oldTransform", "newTransform", "a", "make", "calcTransform", "_k", "name", "comps", "data", "prefabAsset", "deserializedCompList", "deserializePrefabAsset", "child", "id", "c", "children", "idx", "trigger", "o", "tag", "opts", "compIdAreTags", "checkTagsOrComps", "t", "list", "recurse", "isChild", "events", "ev", "hierarchy", "include", "exclude", "parent", "distanceOp", "sdist", "i", "objects", "o1", "o2", "l1", "l2", "maskFunc", "drawMasked", "drawSubtracted", "f", "pushTransform", "isFixed", "loadMatrix", "popTransform", "flush", "FrameBuffer", "Picture", "beginPicture", "endPicture", "info", "comp", "key", "value", "force", "localUpdateNeeded", "updateNeeded", "multTranslateV", "multRotate", "multScaleV", "multSkewV", "Mat23", "storeMatrix", "addCompIdAsTag", "gc", "prop", "func", "val", "originalCompId", "internalIsMaking", "e", "dep", "throwError", "compId", "compList", "op", "action", "ctrl", "args", "cb", "SystemPhase", "system", "name", "action", "when", "systems", "_k", "replacingSystemIdx", "s", "loc", "idx", "usesArea", "_k", "_nextRenderAreaVersion", "nextRenderAreaVersion", "_nextLocalAreaVersion", "nextLocalAreaVersion", "_nextWorldAreaVersion", "nextWorldAreaVersion", "getRenderAreaVersion", "obj", "getLocalAreaVersion", "_topMostOnlyActivate", "_setTopMostOnlyActivate", "value", "clickHandler", "button", "screenPos", "worldPos", "toWorld", "objects", "Rect", "o1", "o2", "l1", "l2", "to1", "to2", "clickHandlerRunning", "startClickHandler", "hoverHandler", "oldObjects", "newObjects", "systemInstalled", "startHoverSystem", "mouseHover", "fakeMouseHover", "system", "area", "opt", "colliding", "collidingThisFrame", "events", "_worldShape", "_worldBBox", "_screenShape", "_shape", "_scale", "vec2", "_offset", "_cursor", "_localAreaVersion", "_worldAreaVersion", "_worldBBoxVersion", "_cachedTransformVersion", "_cachedRenderAreaVersion", "_cachedLocalAreaVersion", "col", "exists", "event", "id", "a", "pushTransform", "multTranslate", "opts", "rgb", "isFixed", "drawRect", "Polygon", "drawPolygon", "Circle", "drawCircle", "popTransform", "mpos", "other", "otherOrTag", "c", "action", "btn", "tag", "cb", "pt", "localArea", "Vec2", "offset", "anchorPt", "DEF_ANCHOR", "renderAreaVersion", "transform", "data", "rect", "w", "h", "opt", "_shape", "_width", "_height", "value", "nextRenderAreaVersion", "drawRect", "getRenderProps", "Rect", "vec2", "data", "rectFactory", "fixed", "fixedFactory", "data", "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", "shake", "intensity", "toScreen", "p", "Vec2", "toWorld", "camPos", "deprecateMsg", "camScale", "camRot", "camFlash", "camTransform", "deepEq", "o1", "o2", "t1", "t2", "k1", "k2", "k", "v1", "v2", "Texture", "_Texture", "ctx", "w", "h", "opt", "gl", "glText", "filter", "wrap", "img", "tex", "x", "y", "BatchRenderer", "format", "maxVertices", "maxIndices", "sum", "f", "glVBuf", "primitive", "vertices", "indices", "shader", "uniform", "blend", "width", "height", "fixed", "index", "count", "indexOffset", "l", "i", "material", "lastCommand", "lastMaterial", "command", "deepEq", "IDENTITY_MATRIX", "getCamTransform", "Mesh", "genStack", "setFunc", "stack", "push", "item", "pop", "cur", "initGfx", "opts", "gc", "onDestroy", "action", "destroy", "extension", "curVertexFormat", "setVertexFormat", "fmt", "stride", "offset", "pushTexture2D", "popTexture2D", "t", "pushArrayBuffer", "popArrayBuffer", "b", "pushElementArrayBuffer", "popElementArrayBuffer", "pushFramebuffer", "popFramebuffer", "pushRenderbuffer", "popRenderbuffer", "pushViewport", "popViewport", "pushProgram", "popProgram", "p", "FilterTexPacker", "_p", "_f", "_gfx", "_w", "_h", "_pad", "el", "tex", "Texture", "ctx", "img", "f", "Quad", "x", "y", "chopX", "chopY", "imgWidth", "imgHeight", "curCtx", "drawImageSourceAt", "chopQuad", "pad", "paddedWidth", "paddedHeight", "curEl", "curTex", "maxX", "maxY", "rectToAdd", "Rect", "Vec2", "p", "found", "doesitfit", "rect", "testRectRect", "entry", "pos", "width", "height", "used", "frames", "main", "frame", "packerId", "big", "TexPacker", "filter", "name", "packer", "quad", "id", "whitePixel", "Asset", "_Asset", "KEvent", "loader", "data", "err", "asset", "action", "AssetBucket", "onGet", "KEventHandler", "name", "id", "d", "handle", "loaded", "a", "timeout", "res", "rej", "_", "x", "fetchURL", "url", "fetchJSON", "path", "fetchText", "fetchArrayBuffer", "loadRoot", "_k", "loadJSON", "fixURL", "loadImg", "src", "img", "resolve", "reject", "spriteSrcToImage", "loadProgress", "buckets", "n", "bucket", "getFailedAssets", "fails", "getAsset", "load", "prom", "initAssets", "ggl", "opt", "appGfx", "packer", "TexPacker", "SPRITE_ATLAS_WIDTH", "SPRITE_ATLAS_HEIGHT", "assets", "SoundData", "_SoundData", "buf", "resolve", "reject", "_k", "url", "isDataURL", "dataURLToArrayBuffer", "fetchArrayBuffer", "resolveSound", "src", "snd", "getSound", "loadProgress", "Asset", "name", "loadSound", "fixedSrc", "fixURL", "sound", "loadMusic", "musicUrl", "a", "createEmptyAudioBuffer", "ctx", "initAudio", "masterNode", "overload2", "fn1", "fn2", "args", "al", "trigger", "event", "tag", "args", "obj", "_k", "on", "cb", "paused", "obj2Handler", "handleNew", "ec", "h", "ecOnTag", "newTag", "ecOnAdd", "ecOnUntag", "oldTag", "ecOnDestroy", "p", "onAdd", "overload2", "action", "onDestroy", "onUse", "onUnuse", "onTag", "onUntag", "onCollide", "t1", "t2", "f", "a", "b", "col", "onCollideUpdate", "onCollideEnd", "onFixedUpdate", "onUpdate", "onDraw", "onClick", "startClickHandler", "onHover", "startHoverSystem", "onHoverEnd", "onHoverUpdate", "onError", "onLoading", "onLoad", "onLoadError", "getFailedAssets", "asset", "onSceneLeave", "getData", "key", "def", "setData", "data", "loadAseprite", "name", "imgSrc", "jsonSrc", "fixURL", "getFileName", "resolveJSON", "fetchJSON", "_k", "data", "size", "frames", "f", "Quad", "anims", "anim", "SpriteData", "loadSpriteAtlas", "src", "data", "repack", "fixURL", "load", "res", "rej", "fetchJSON", "json", "spriteSrcToImage", "img", "packer", "_k", "map", "wholeImageWidth", "wholeImageHeight", "mainFramesByFilter", "name", "spriteSectionX", "spriteSectionY", "spriteSectionWidth", "spriteSectionHeight", "frames", "sliceX", "sliceY", "anims", "slice9", "filter", "mainQuad", "Quad", "fixFramesPixelsToFractionOfImage", "slice", "spr", "SpriteData", "q", "ourFrame", "playMusic", "url", "opt", "onEndEvents", "KEvent", "el", "src", "_k", "resumeAudioCtx", "play", "time", "l", "p", "val", "clamp", "s", "d", "action", "node", "play", "src", "opt", "_k", "playMusic", "ctx", "paused", "srcNode", "onEndEvents", "KEvent", "gainNode", "panNode", "pos", "startTime", "stopTime", "started", "getTime", "start", "data", "snd", "resolveSound", "Asset", "t", "cloneNode", "oldNode", "newNode", "p", "time", "val", "pan", "l", "action", "node", "burp", "opt", "_k", "play", "setVolume", "v", "_k", "getVolume", "volume", "deprecateMsg", "a", "dummy", "SoundData", "record", "frameRate", "mimeTypes", "_k", "options", "mimeType", "mime", "audioDest", "audioStream", "firstAudioTrack", "canvasStream", "firstCanvasTrack", "recorder", "play", "chunks", "defaultExt", "e", "t", "finalized", "checkFinalized", "rec", "resolve", "filename", "blob", "downloadBlob", "blend", "blendFactory", "data", "circle", "radius", "opt", "_shape", "_radius", "value", "nextRenderAreaVersion", "drawCircle", "getRenderProps", "Circle", "Vec2", "data", "circleFactory", "drawon", "c", "opt", "ellipse", "radiusX", "radiusY", "opt", "_shape", "_radiusX", "_radiusY", "value", "nextRenderAreaVersion", "drawEllipse", "getRenderProps", "Ellipse", "Vec2", "ellipseFactory", "data", "fadeIn", "time", "finalOpacity", "t", "done", "_k", "map", "fill", "mask", "m", "maskFactory", "data", "outline", "width", "color", "rgb", "opacity", "join", "miterLimit", "cap", "outlineFactory", "data", "Color", "Particle", "vec2", "particles", "popt", "eopt", "emitterLifetime", "colors", "Color", "opacities", "quads", "Quad", "scales", "s", "lifetime", "spread", "speed", "angleRange", "angularVelocityRange", "accelerationRange", "dampingRange", "indices", "attributes", "count", "time", "i", "onEndEvents", "KEvent", "nextFree", "index", "n", "velocityAngle", "rand", "vel", "Vec2", "angle", "angularVelocity", "acceleration", "damping", "lt", "pos", "p", "DT", "_k", "progress", "colorIndex", "color", "lerp", "map", "opacityIndex", "opacity", "quadIndex", "quad", "scaleIndex", "scale", "deg2rad", "c", "hw", "hh", "j", "drawRaw", "action", "picture", "drawPicture", "getRenderProps", "polygon", "pts", "opt", "drawPolygon", "getRenderProps", "nextRenderAreaVersion", "Polygon", "p", "raycast", "origin", "direction", "exclude", "minHit", "_k", "tag", "hit", "shader", "id", "uniform", "drawTexture", "opt", "q", "Quad", "w", "h", "offset", "anchorPt", "DEF_ANCHOR", "offsetX", "offsetY", "fcols", "frows", "cols", "rows", "fracX", "fracY", "n", "indices", "attributes", "index", "color", "Color", "opacity", "addQuad", "x", "y", "s", "j", "i", "drawRaw", "drawUVQuad", "Vec2", "sprite", "src", "opt", "spriteData", "curAnim", "curAnimDir", "spriteLoadedEvent", "KEvent", "calcTexScale", "tex", "q", "w", "scale", "vec2", "setSpriteData", "obj", "spr", "frame", "animName", "anim", "createAnimFrames", "frames", "frameSeqLength", "i", "_shape", "_width", "_height", "value", "nextRenderAreaVersion", "Quad", "resolveSprite", "left", "right", "top", "bottom", "tileMode", "warn", "tw", "th", "iw", "ih", "w1", "w3", "w2", "h1", "h3", "h2", "quads", "quad", "props", "getRenderProps", "offset", "anchorPt", "DEF_ANCHOR", "offsetX", "offsetY", "uv", "transform", "isCenter", "isEdge", "shouldTile", "drawTexture", "_k", "name", "prevAnim", "action", "Rect", "data", "spriteFactory", "text", "opt", "theFormattedText", "update", "obj", "formatText", "getRenderProps", "_shape", "_width", "_height", "nt", "DEF_TEXT_SIZE", "value", "nextRenderAreaVersion", "_k", "drawFormattedText", "Rect", "vec2", "textFactory", "data", "uvquad", "w", "h", "_shape", "_width", "_height", "value", "nextRenderAreaVersion", "drawUVQuad", "getRenderProps", "Rect", "vec2", "video", "url", "opt", "_video", "_playing", "_timeupdate", "_canCopyVideo", "_texture", "Texture", "_k", "_shape", "_width", "_height", "value", "nextRenderAreaVersion", "updateCopyFlag", "response", "gl", "drawUVQuad", "getRenderProps", "drawRect", "Rect", "vec2", "agent", "opts", "target", "path", "index", "navMapChangedEvent", "p", "cb", "BinaryHeap", "compareFn", "a", "b", "item", "lastItem", "pos", "parent", "child", "index1", "index2", "pos", "args", "_pos", "vec2", "_posReadOnly", "nextTransformVersion", "value", "_k", "dest", "speed", "diff", "obj", "p", "isFixed", "toWorld", "toScreen", "other", "drawCircle", "rgb", "posFactory", "data", "tile", "opts", "tilePos", "vec2", "isObstacle", "cost", "edges", "getEdgeMask", "loopup", "s", "mask", "dir", "edgeMask", "p", "level", "is", "n", "e", "level", "map", "opt", "numRows", "numColumns", "spatialMap", "costMap", "edgeMap", "connectivityMap", "tile2Hash", "tilePos", "hash2Tile", "hash", "vec2", "createSpatialMap", "child", "insertIntoSpatialMap", "obj", "i", "removeFromSpatialMap", "index", "updateSpatialMap", "spatialMapChanged", "createCostMap", "size", "objects", "cost", "createEdgeMap", "len", "mask", "createConnectivityMap", "traverse", "frontier", "getNeighbours", "getCost", "node", "neighbour", "getHeuristic", "goal", "p1", "p2", "diagonals", "n", "x", "left", "top", "right", "bottom", "row", "keys", "key", "j", "args", "p", "comps", "hasPos", "hasTile", "comp", "pos", "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", "data", "compsAndTags", "tags", "compOrTag", "buildPath", "start", "goal", "cameFrom", "path", "node", "aStarSearch", "graph", "start", "goal", "frontier", "BinaryHeap", "a", "b", "cameFrom", "costSoFar", "current", "neighbors", "next", "newCost", "buildPath", "floodFill", "predicate", "stack", "fill", "node", "neighbor", "buildConnectivityMap", "map", "index", "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", "objects", "o", "cb", "AnimateChannel", "name", "opts", "relative", "easings", "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", "Anim", "acc", "channel", "Vec2", "Color", "c", "o", "allFinished", "localFinished", "animate", "gopts", "anims", "currentAnim", "vec2", "time", "clamp", "anim", "_k", "cb", "options", "serializeAnimation", "fakeMouse", "opt", "isPressed", "lastPos", "_k", "action", "health", "hp", "maxHP", "val", "origHP", "clamp", "action", "lifespan", "time", "opt", "fade", "_k", "a", "easings", "named", "name", "state", "initState", "stateList", "transitions", "events", "initStateEvents", "KEvent", "on", "event", "action", "trigger", "args", "didFirstEnter", "oldState", "available", "s", "from", "to", "data", "stay", "scenesToStay", "textInput", "hasFocus", "maxInputLength", "charEv", "backEv", "origText", "newValue", "_k", "flip", "character", "cb", "timer", "maxLoopsPerFrame", "time", "action", "count", "waitFirst", "t", "onEndEvents", "KEvent", "ev", "_k", "i", "val", "p", "f", "from", "to", "duration", "setValue", "easeFunc", "easings", "curTime", "lerp", "setGravity", "g", "_k", "vec2", "getGravity", "setGravityDirection", "d", "getGravityDirection", "body", "opt", "curPlatform", "lastPlatformPos", "willFall", "acc", "vec2", "prevPhysicsPos", "nextPhysicsPos", "prevDrawPos", "DEF_JUMP_FORCE", "other", "col", "rcol", "tmass", "calcTransform", "col2", "_k", "pastPlatform", "restitution", "friction", "projection", "rejection", "exists", "dt", "lerpAmount", "p", "lerp", "prevVel", "maxVel", "MAX_VEL", "nextVel", "action", "getGravityDirection", "impulse", "force", "data", "doubleJump", "numJumps", "jumpsLeft", "force", "action", "surfaceEffector", "opts", "obj", "col", "dir", "currentVel", "force", "areaEffector", "pointEffector", "length", "distance", "forceScale", "constantForce", "platformEffector", "opt", "Vec2", "_", "normal", "s", "collision", "buoyancyEffector", "o", "shape", "polygon", "Polygon", "submergedArea", "vec2", "body", "displacedMass", "buoyancyForce", "velocity", "dragMagnitude", "dragForce", "anchor", "o", "Vec2", "anchorPt", "anchorFactory", "data", "systemInstalled", "installSystem", "constraints", "_k", "obj", "id", "system", "constraint", "target", "opt", "d", "vec2", "dd", "l", "lerp", "transform", "p", "Vec2", "srcAngle", "dstAngle", "newAngle", "scale", "newTransform", "Mat23", "updateTransformRecursive", "srcScale", "dstScale", "newScale", "angle", "newX", "newY", "minAngle", "maxAngle", "minLength", "maxLength", "_minAngle", "_maxAngle", "_minLength", "_maxLength", "pushTransform", "multRotate", "drawCircle", "Color", "popTransform", "algorithm", "depth", "iterations", "chain", "length", "endEffector", "i", "dx", "dy", "it", "effector", "effectorTransform", "calcTransform", "angleToTarget", "rad2deg", "angleToEndEffector", "angleCorrection", "rotation", "clampAngle", "ax", "ay", "bx", "by", "s", "px", "py", "len", "nlen", "clamp", "olen", "updateChildrenTransformRecursive", "p1", "bone", "childBone", "loadMatrix", "drawPolygon", "root", "rootPosX", "rootPosY", "parent", "parentTransform", "follow", "obj", "offset", "vec2", "exists", "layer", "_layerIndex", "_k", "value", "move", "dir", "speed", "d", "Vec2", "moveFactory", "data", "offscreen", "opt", "isOut", "screenRect", "Rect", "vec2", "width", "height", "selfRect", "check", "self", "DEF_OFFSCREEN_DIS", "pos", "dist", "testRectPoint", "action", "_k", "rotate", "a", "_angle", "value", "nextTransformVersion", "angle", "rotateFactory", "data", "scale", "args", "_scale", "vec2", "_scaleReadOnly", "value", "Vec2", "nextTransformVersion", "scaleFactory", "data", "skew", "args", "_skew", "vec2", "_skewReadOnly", "value", "Vec2", "nextTransformVersion", "z", "zFactory", "data", "boom", "speed", "size", "time", "s", "vec2", "_k", "addKaboom", "p", "opt", "_k", "kaboom", "pos", "stay", "speed", "s", "sprite", "scale", "anchor", "boom", "ka", "timer", "addLevel", "map", "opt", "parent", "_k", "pos", "vec2", "level", "Collision", "_Collision", "source", "target", "normal", "distance", "resolved", "_k", "vec2", "setLayers", "layerNames", "defaultLayer", "_k", "defaultLayerIndex", "getLayers", "getDefaultLayer", "layers", "deprecateMsg", "scene", "id", "def", "_k", "go", "name", "args", "e", "obj", "vec2", "Mat23", "pushScene", "popScene", "sceneData", "getSceneName", "setBackground", "args", "color", "rgb", "alpha", "_k", "getBackground", "makeCanvas", "w", "h", "fb", "FrameBuffer", "_k", "action", "flush", "drawCurve", "curve", "opt", "segments", "p", "i", "drawLines", "drawBezier", "opt", "drawCurve", "t", "evaluateBezier", "drawCanvas", "opt", "fb", "drawUVQuad", "vec2", "height", "drawSprite", "opt", "spr", "resolveSprite", "calcTexScale", "tex", "q", "w", "h", "scale", "vec2", "frame", "Quad", "width", "height", "drawTexture", "drawTriangle", "opt", "drawPolygon", "DecisionNode", "attribute", "value", "node", "ValueDecisionNode", "predicate", "PredicateDecisionNode", "weight", "WeightDecisionNode", "answers", "dice", "rand", "sum", "values", "v", "distinct", "entropy", "outcomes", "positive", "outcome", "negative", "gain", "splitByAttribute", "i", "o", "DecisionTree", "_DecisionTree", "data", "attributes", "indexOfAttributeToSplitOn", "gains", "_", "index", "maxGain", "createBranches", "attributeColumn", "a", "d", "column", "n", "tree", "Rule", "predicate", "salience", "system", "ActionRule", "action", "AssertRule", "fact", "grade", "RetractRule", "RuleSystem", "rule", "a", "b", "facts", "State", "name", "callbacks", "StateMachine", "states", "oldStateName", "cb", "state", "from", "to", "orient", "a", "b", "c", "v", "buildConvexHull", "points", "first", "i", "sorted", "o", "stack", "calculateSupport", "shapeA", "shapeB", "direction", "oppositeDirection", "Vec2", "supportA", "supportB", "addSupport", "vertices", "support", "tripleProduct", "a", "b", "c", "Vec2", "evolveSimplex", "simplex", "colliderA", "colliderB", "direction", "ab", "a0", "tp", "c0", "bc", "ca", "bcNorm", "caNorm", "addSupport", "gjkIntersects", "vertices", "result", "findClosestEdge", "simplex", "winding", "minDistance", "minNormal", "Vec2", "minIndex", "line", "norm", "i", "j", "dist", "getIntersection", "colliderA", "colliderB", "e0", "e1", "e2", "intersection", "MAX_TRIES", "edge", "support", "calculateSupport", "distance", "len", "gjkIntersection", "vertices", "direction", "result", "evolveSimplex", "gjkShapeIntersects", "shapeA", "shapeB", "gjkIntersects", "gjkShapeIntersection", "lerpAngle", "a", "b", "t", "clampAngle", "Vec2", "NavGrid", "width", "height", "isConnected", "diagonals", "tileWidth", "tileHeight", "buildConnectivityMap", "index", "node", "x", "y", "column", "tile", "neighbors", "other", "a", "b", "start", "goal", "maxNode", "aStarSearch", "path", "dx", "dy", "vec2", "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", "createRegularPolygon", "radius", "sides", "startAngle", "deg2rad", "x", "y", "angle", "c", "s", "poly", "i", "vec2", "createStarPolygon", "radius1", "radius2", "createCogPolygon", "insertionSort", "a", "cmp", "i", "j", "swap", "temp", "Quadtree", "_Quadtree", "bounds", "maxObjects", "maxLevels", "level", "width", "height", "x", "y", "pos", "vec2", "i", "Rect", "count", "allLeaves", "rect", "boundsCenterX", "boundsCenterY", "quadrants", "obj", "bbox", "j", "index", "getTransformVersion", "getRenderAreaVersion", "getLocalAreaVersion", "retrieveCb", "indices", "fast", "root", "orphans", "versions", "objectTransformNeedsUpdate", "calcTransform", "ancestorObjects", "pairCb", "isValidCollisionObject", "ResizingQuadtree", "increaseLevel", "node", "n", "isLeft", "isRight", "isCenter", "isTop", "isBottom", "isMiddle", "makeQuadtree", "resizing", "exists", "isPaused", "plug", "plugin", "args", "funcs", "_k", "funcsObj", "key", "quit", "app", "gfx", "ggl", "gc", "_k", "numTextureUnits", "unit", "f", "onCleanup", "action", "createContext", "e", "plugins", "exportToGlobal", "game", "app", "audio", "debug", "globalOpt", "add", "addPrefab", "readd", "destroyAll", "get", "wait", "loop", "query", "tween", "defaultScope", "ctx", "loadRoot", "loadProgress", "loadSprite", "loadSpriteAtlas", "loadSound", "loadMusic", "loadBitmapFont", "loadFont", "loadBitmapFontFromSprite", "loadShader", "loadShaderURL", "loadAseprite", "loadBean", "loadHappy", "loadJSON", "loadPrefab", "load", "getSound", "getFont", "getBitmapFont", "getSprite", "getShader", "getAsset", "Asset", "SpriteData", "SoundData", "width", "height", "center", "record", "flash", "setCamPos", "getCamPos", "setCamRot", "getCamRot", "setCamScale", "getCamScale", "getCamTransform", "camPos", "camScale", "camFlash", "camRot", "camTransform", "shake", "toScreen", "toWorld", "setGravity", "getGravity", "setGravityDirection", "getGravityDirection", "setBackground", "getBackground", "getTreeRoot", "createPrefab", "exists", "destroy", "args", "pos", "rotate", "scale", "skew", "color", "blend", "opacity", "fill", "anchor", "area", "sprite", "text", "polygon", "rect", "circle", "ellipse", "uvquad", "video", "picture", "outline", "particles", "body", "surfaceEffector", "areaEffector", "pointEffector", "buoyancyEffector", "platformEffector", "constantForce", "doubleJump", "shader", "textInput", "timer", "fixed", "stay", "health", "lifespan", "named", "state", "z", "layer", "move", "constraint", "offscreen", "follow", "fadeIn", "mask", "drawon", "raycast", "tile", "animate", "serializeAnimation", "agent", "sentry", "patrol", "pathfinder", "level", "fakeMouse", "trigger", "play", "setVolume", "getVolume", "volume", "burp", "Line", "Rect", "Circle", "Ellipse", "Point", "Polygon", "Collision", "Vec2", "Color", "Mat2", "Mat4", "Mat23", "Quad", "Quadtree", "makeQuadtree", "RNG", "Rule", "RuleSystem", "DecisionNode", "DecisionTree", "StateMachine", "getSpriteOutline", "insertionSort", "rand", "randi", "randSeed", "vec2", "rgb", "hsl2rgb", "quad", "choose", "chooseMultiple", "shuffle", "chance", "lerp", "lerpAngle", "step", "smoothstep", "easings", "map", "mapc", "wave", "deg2rad", "rad2deg", "clamp", "evaluateQuadratic", "evaluateQuadraticFirstDerivative", "evaluateQuadraticSecondDerivative", "evaluateBezier", "evaluateBezierFirstDerivative", "evaluateBezierSecondDerivative", "evaluateCatmullRom", "evaluateCatmullRomFirstDerivative", "curveLengthApproximation", "normalizedCurve", "hermite", "cardinal", "catmullRom", "bezier", "kochanekBartels", "piecewiseBezier", "piecewiseCatmullRom", "createRegularPolygon", "createStarPolygon", "createCogPolygon", "floodFill", "buildConnectivityMap", "easingSteps", "easingLinear", "easingCubicBezier", "testLineLine", "testRectRect", "testRectLine", "testRectPoint", "testCirclePolygon", "testLinePoint", "testLineCircle", "clipLineToRect", "clipLineToCircle", "anchorPt", "gjkShapeIntersects", "gjkShapeIntersection", "isConvex", "triangulate", "buildConvexHull", "NavMesh", "NavGrid", "drawSprite", "drawText", "formatText", "compileStyledText", "drawRect", "drawLine", "drawLines", "drawTriangle", "drawCircle", "drawEllipse", "drawUVQuad", "drawPolygon", "drawCurve", "drawBezier", "drawFormattedText", "drawMasked", "drawSubtracted", "beginPicture", "appendToPicture", "endPicture", "drawPicture", "pushTransform", "popTransform", "multTranslateV", "multScaleV", "multRotate", "loadMatrix", "usePostEffect", "makeCanvas", "drawCanvas", "Picture", "getSceneName", "go", "pushScene", "popScene", "layers", "getLayers", "setLayers", "getDefaultLayer", "addLevel", "getData", "setData", "download", "downloadJSON", "downloadText", "downloadBlob", "plug", "system", "SystemPhase", "ASCII_CHARS", "addKaboom", "quit", "throwError", "KEvent", "KEventHandler", "KEventController", "KeepFlags", "EVENT_CANCEL_SYMBOL", "BlendMode", "key", "updateViewport", "pixelDensity", "_k", "desiredWidth", "desiredHeight", "drawingBufferWidth", "drawingBufferHeight", "canvasWidth", "canvasHeight", "x", "y", "viewportWidth", "viewportHeight", "canvasAspectRatio", "disairedAspectRatio", "scaledWidth", "scaledHeight", "viewportToCanvas", "pt", "Vec2", "canvasToViewport", "isEqOrIncludes", "listOrSmt", "el", "setHasOrIncludes", "set", "key", "k", "getButtons", "_k", "getButton", "btn", "setButton", "binding", "pressButton", "releaseButton", "parseButtonBindings", "appState", "btns", "b", "splitButtons", "out", "i", "ChordedButtonDetector", "button", "bindings", "modsToClear", "check", "mods", "committer", "m", "e", "key", "commit", "pressedButtons", "options", "mod", "canceledButtons", "ButtonProcessor", "ButtonState", "name", "keyboardBtns", "keyboardCodes", "gamepadBtns", "mouseBtns", "buttons", "state", "keyCode", "mb", "gb", "ButtonState", "_pressEv", "_pressRepeatEv", "_downEv", "_releaseEv", "_arg", "state", "b", "btn", "had", "GamepadState", "gp", "Vec2", "FPSCounter", "dt", "ago", "samples", "fixedSpeeds", "initAppState", "opt", "buttons", "ButtonProcessor", "KEventHandler", "initApp", "parseButtonBindings", "setFixedSpeed", "fixedDt", "restDt", "isHidden", "time", "fps", "rawFPS", "numFrames", "screenshot", "screenshotToBlob", "resolve", "reject", "setCursor", "c", "getCursor", "setCursorLocked", "res", "e", "isCursorLocked", "enterFullscreen", "el", "exitFullscreen", "setFullscreen", "f", "isFullscreen", "isFocused", "quit", "ce", "canvasEvents", "de", "docEvents", "we", "winEvents", "name", "val", "resizeObserver", "speed", "run", "fixedUpdate", "update", "fixedUpdateAccumulator", "updateAccumulator", "frame", "t", "currentTime", "unclampedDt", "observedDt", "desiredDt", "processInput", "resetInput", "isTouchscreen", "mousePos", "mouseDeltaPos", "isMousePressed", "m", "isMouseDown", "isMouseReleased", "isMouseMoved", "isKeyPressed", "k", "setHasOrIncludes", "isKeyPressedRepeat", "isKeyDown", "isKeyReleased", "isGamepadButtonPressed", "isGamepadButtonDown", "isGamepadButtonReleased", "getGamepadAnalogButton", "isButtonPressed", "isButtonDown", "isButtonReleased", "onResize", "action", "onKeyDown", "overload2", "key", "isEqOrIncludes", "onKeyPress", "onKeyPressRepeat", "onKeyRelease", "onMouseDown", "mouse", "onMousePress", "onMouseRelease", "onMouseMove", "onCharInput", "onTouchStart", "onTouchMove", "onTouchEnd", "onScroll", "onHide", "deprecateMsg", "onTabHide", "onShow", "onTabShow", "onGamepadButtonPress", "onGamepadButtonDown", "onGamepadButtonRelease", "onGamepadStick", "stick", "a", "v", "onGamepadConnect", "onGamepadDisconnect", "getGamepadStick", "charInputted", "getGamepads", "onButtonPress", "onButtonDown", "onButtonRelease", "getLastInputDeviceType", "processGamepad", "s", "registerGamepad", "browserGamepad", "gamepad", "vec2", "button", "removeGamepad", "g", "map", "GP_MAP", "gamepadState", "i", "gamepadBtn", "browserGamepadBtn", "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", "getButton", "getButtons", "setButton", "pressButton", "releaseButton", "createDebug", "gopt", "app", "appGfx", "audio", "game", "fr", "debugPaused", "debug", "timeScale", "message", "wrapStyle", "max", "LOG_MAX", "msg", "v", "createScopeHandlers", "app", "onUpdate", "onFixedUpdate", "onDraw", "onAdd", "onDestroy", "onUse", "onUnuse", "onTag", "onUntag", "on", "onClick", "onCollide", "onCollideEnd", "onCollideUpdate", "onHover", "onHoverEnd", "onHoverUpdate", "onSceneLeave", "onLoad", "onLoading", "onError", "onLoadError", "onCleanup", "createSceneScope", "handlers", "sceneScope", "scene", "e", "args", "ev", "_k", "createAppScope", "appScope", "ingnoredHandlersForObject", "attachScopeHandlersToGameObjRaw", "obj", "GameObjRawPrototype", "createGame", "game", "makeInternal", "KEventHandler", "Vec2", "Mat23", "rect", "retrieveCb", "RNG", "timer", "createCanvas", "gopt", "root", "pixelDensity", "canvas", "styles", "initAppGfx", "gfx", "gopt", "defShader", "makeShader", "DEF_VERT", "DEF_FRAG", "pixelDensity", "gl", "frameBuffer", "FrameBuffer", "bgColor", "bgAlpha", "rgb", "renderer", "BatchRenderer", "VERTEX_FORMAT", "MAX_BATCHED_VERTS", "MAX_BATCHED_INDICES", "bgTex", "Texture", "transformStack", "_", "Mat23", "Vec2", "initAppEvents", "_k", "fixedSize", "updateViewport", "FrameBuffer", "toFixed", "clamp", "burp", "drawInspectText", "pos", "txt", "drawUnscaled", "pad", "vec2", "pushTransform", "multTranslateV", "ftxt", "formatText", "DBG_FONT", "rgb", "bw", "bh", "width", "height", "drawRect", "drawFormattedText", "popTransform", "drawDebug", "_k", "inspecting", "obj", "isPaused", "batches", "pushTransform", "popTransform", "lines", "data", "tag", "t", "drawInspectText", "viewportToCanvas", "vec2", "drawUnscaled", "multTranslate", "width", "size", "drawRect", "rgb", "i", "height", "pad", "ftxt", "formatText", "DBG_FONT", "flipped", "drawTriangle", "drawFormattedText", "drawCircle", "wave", "logs", "log", "style", "str", "prettyDebug", "LOG_TIME", "ftext", "object", "inside", "seen", "outStr", "tmp", "e", "p", "transformFrame", "resetTreeIndex", "_k", "updateLastTransformVersion", "drawFrame", "cam", "shake", "Vec2", "rand", "lerp", "center", "flush", "drawLoadScreen", "progress", "loadProgress", "_k", "drawUnscaled", "w", "width", "h", "pos", "vec2", "height", "drawRect", "rgb", "startEngineLoop", "app", "game", "assets", "gopt", "frameRenderer", "debug", "isFirstFrame", "sys", "e", "handleErr", "processInput", "resetInput", "loadProgress", "getFailedAssets", "details", "drawLoadScreen", "transformFrame", "drawFrame", "drawDebug", "updateViewport", "initAppEvents", "createFontCache", "fontCacheCanvas", "MAX_TEXT_CACHE_SIZE", "fontCacheC2d", "createFrameRenderer", "app", "gfx", "game", "pixelDensity", "frameStart", "drawUnscaled", "drawUVQuad", "width", "height", "Quad", "BG_GRID_SIZE", "frameEnd", "flush", "ow", "oh", "drawTexture", "Vec2", "fixedUpdateFrame", "updateFrame", "createEngine", "gopt", "opt", "canvas", "createCanvas", "fontCacheC2d", "fontCacheCanvas", "createFontCache", "app", "initApp", "gameHandlers", "createScopeHandlers", "sceneScope", "createSceneScope", "appScope", "createAppScope", "attachScopeHandlersToGameObjRaw", "canvasContext", "gfx", "initGfx", "appGfx", "initAppGfx", "assets", "initAssets", "audio", "initAudio", "game", "createGame", "frameRenderer", "createFrameRenderer", "debug", "createDebug", "registerPrefabFactory", "anchorFactory", "fixedFactory", "moveFactory", "posFactory", "rotateFactory", "scaleFactory", "zFactory", "blendFactory", "circleFactory", "colorFactory", "ellipseFactory", "maskFactory", "opacityFactory", "outlineFactory", "rectFactory", "spriteFactory", "textFactory", "startEngineLoop", "minkowskiRectDifference", "r1", "r2", "Rect", "vec2", "minkowskiRectShapeIntersection", "shape1", "shape2", "s1", "s2", "res", "Vec2", "distance", "normal", "satShapeIntersection", "shape1", "shape2", "s1", "Polygon", "s2", "sat", "p1", "p2", "overlap", "result", "poly", "i", "a", "axisProj", "min1", "max1", "j", "q", "min2", "max2", "o", "o1", "o2", "s", "HashGrid", "bounds", "opt", "DEF_HASH_GRID_SIZE", "obj", "bbox", "hashes", "i", "hash", "getTransformVersion", "getRenderAreaVersion", "getLocalAreaVersion", "oldSet", "newSet", "oldHashes", "versions", "objectTransformNeedsUpdate", "calcTransform", "newHashes", "pairCb", "checked", "obj1", "isValidCollisionObject", "collisions", "obj2", "rect", "retrieveCb", "hits", "cell", "point", "x", "y", "diff", "w", "rw", "rh", "objects", "index", "exists", "isPaused", "SapEdgeHorizontal", "obj", "isLeft", "SweepAndPruneHorizontal", "left", "right", "pair", "edges", "exists", "versions", "getTransformVersion", "getRenderAreaVersion", "getLocalAreaVersion", "objectTransformNeedsUpdate", "calcTransform", "bbox", "i", "j", "temp", "pairCb", "touching", "edge", "isValidCollisionObject", "rect", "retrieveCb", "hits", "SapEdgeVertical", "isTop", "SweepAndPruneVertical", "top", "bottom", "isPaused", "createCollisionSystem", "broad", "narrow", "opt", "broadPhaseIntersection", "SweepAndPruneHorizontal", "SweepAndPruneVertical", "Quadtree", "Rect", "vec2", "width", "height", "HashGrid", "DEF_HASH_GRID_SIZE", "narrowPhaseIntersection", "gjkShapeIntersection", "satShapeIntersection", "minkowskiRectShapeIntersection", "narrowPhase", "obj", "other", "tag", "res", "col1", "Collision", "col2", "broadInit", "broadPhase", "_k", "id", "checkFrame", "usesArea", "retrieve", "rect", "retrieveCb", "ran", "kaplay", "opt", "updateEngine", "gopt", "createEngine", "app", "game", "audio", "_k", "checkFrame", "retrieve", "createCollisionSystem", "_setTopMostOnlyActivate", "system", "loadSprite", "ka_default", "boom_default", "burpSnd", "SoundData", "createEmptyAudioBuffer", "burp_default", "buf", "err", "bean_default", "happy_default", "ctx", "createContext", "kaplayTypes", "kaplay_default"]
}
