quake2ts 0.0.563 → 0.0.564

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/mocks.ts","../src/shared/bsp.ts","../src/game/factories.ts","../src/game/helpers.ts","../src/game/mocks.ts","../src/server/mocks/transport.ts","../src/server/mocks/state.ts","../src/setup/browser.ts","../src/e2e/input.ts","../src/setup/webgl.ts","../src/setup/canvas.ts","../src/setup/node.ts","../src/setup/storage.ts","../src/setup/audio.ts","../src/setup/timing.ts","../src/e2e/playwright.ts","../src/e2e/network.ts","../src/e2e/visual.ts"],"sourcesContent":["import { vi, type Mock } from 'vitest';\n\nexport interface BinaryWriterMock {\n writeByte: Mock<[number], void>;\n writeShort: Mock<[number], void>;\n writeLong: Mock<[number], void>;\n writeString: Mock<[string], void>;\n writeBytes: Mock<[Uint8Array], void>;\n getBuffer: Mock<[], Uint8Array>;\n reset: Mock<[], void>;\n writeInt8: Mock<[number], void>;\n writeUint8: Mock<[number], void>;\n writeInt16: Mock<[number], void>;\n writeUint16: Mock<[number], void>;\n writeInt32: Mock<[number], void>;\n writeUint32: Mock<[number], void>;\n writeFloat: Mock<[number], void>;\n getData: Mock<[], Uint8Array>;\n}\n\nexport const createBinaryWriterMock = (): BinaryWriterMock => ({\n writeByte: vi.fn(),\n writeShort: vi.fn(),\n writeLong: vi.fn(),\n writeString: vi.fn(),\n writeBytes: vi.fn(),\n getBuffer: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n reset: vi.fn(),\n // Legacy methods (if any)\n writeInt8: vi.fn(),\n writeUint8: vi.fn(),\n writeInt16: vi.fn(),\n writeUint16: vi.fn(),\n writeInt32: vi.fn(),\n writeUint32: vi.fn(),\n writeFloat: vi.fn(),\n getData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n});\n\nexport const createNetChanMock = () => ({\n qport: 1234,\n\n // Sequencing\n incomingSequence: 0,\n outgoingSequence: 0,\n incomingAcknowledged: 0,\n\n // Reliable messaging\n incomingReliableAcknowledged: false,\n incomingReliableSequence: 0,\n outgoingReliableSequence: 0,\n reliableMessage: createBinaryWriterMock(),\n reliableLength: 0,\n\n // Fragmentation\n fragmentSendOffset: 0,\n fragmentBuffer: null,\n fragmentLength: 0,\n fragmentReceived: 0,\n\n // Timing\n lastReceived: 0,\n lastSent: 0,\n\n remoteAddress: { type: 'IP', port: 1234 },\n\n // Methods\n setup: vi.fn(),\n reset: vi.fn(),\n transmit: vi.fn(),\n process: vi.fn(),\n canSendReliable: vi.fn(() => true),\n writeReliableByte: vi.fn(),\n writeReliableShort: vi.fn(),\n writeReliableLong: vi.fn(),\n writeReliableString: vi.fn(),\n getReliableData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n needsKeepalive: vi.fn(() => false),\n isTimedOut: vi.fn(() => false),\n});\n\nexport interface BinaryStreamMock {\n getPosition: Mock<[], number>;\n getReadPosition: Mock<[], number>;\n getLength: Mock<[], number>;\n getRemaining: Mock<[], number>;\n seek: Mock<[number], void>;\n setReadPosition: Mock<[number], void>;\n hasMore: Mock<[], boolean>;\n hasBytes: Mock<[number], boolean>;\n\n readChar: Mock<[], number>;\n readByte: Mock<[], number>;\n readShort: Mock<[], number>;\n readUShort: Mock<[], number>;\n readLong: Mock<[], number>;\n readULong: Mock<[], number>;\n readFloat: Mock<[], number>;\n\n readString: Mock<[], string>;\n readStringLine: Mock<[], string>;\n\n readCoord: Mock<[], number>;\n readAngle: Mock<[], number>;\n readAngle16: Mock<[], number>;\n\n readData: Mock<[number], Uint8Array>;\n\n readPos: Mock<[], any>; // Use proper type if available, e.g., Vec3\n readDir: Mock<[], any>;\n}\n\nexport const createBinaryStreamMock = (): BinaryStreamMock => ({\n getPosition: vi.fn(() => 0),\n getReadPosition: vi.fn(() => 0),\n getLength: vi.fn(() => 0),\n getRemaining: vi.fn(() => 0),\n seek: vi.fn(),\n setReadPosition: vi.fn(),\n hasMore: vi.fn(() => true),\n hasBytes: vi.fn((amount: number) => true),\n\n readChar: vi.fn(() => 0),\n readByte: vi.fn(() => 0),\n readShort: vi.fn(() => 0),\n readUShort: vi.fn(() => 0),\n readLong: vi.fn(() => 0),\n readULong: vi.fn(() => 0),\n readFloat: vi.fn(() => 0),\n\n readString: vi.fn(() => ''),\n readStringLine: vi.fn(() => ''),\n\n readCoord: vi.fn(() => 0),\n readAngle: vi.fn(() => 0),\n readAngle16: vi.fn(() => 0),\n\n readData: vi.fn<[number], Uint8Array>((length: number) => new Uint8Array(length)),\n\n readPos: vi.fn(),\n readDir: vi.fn(),\n});\n","import {\n computePlaneSignBits,\n type CollisionBrush,\n type CollisionModel,\n type CollisionPlane,\n type CollisionNode,\n type CollisionLeaf,\n CONTENTS_SOLID,\n type Vec3\n} from '@quake2ts/shared';\n\nexport function makePlane(normal: Vec3, dist: number): CollisionPlane {\n return {\n normal,\n dist,\n type: Math.abs(normal.x) === 1 ? 0 : Math.abs(normal.y) === 1 ? 1 : Math.abs(normal.z) === 1 ? 2 : 3,\n signbits: computePlaneSignBits(normal),\n };\n}\n\nexport function makeAxisBrush(size: number, contents = CONTENTS_SOLID): CollisionBrush {\n const half = size / 2;\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, half),\n makePlane({ x: -1, y: 0, z: 0 }, half),\n makePlane({ x: 0, y: 1, z: 0 }, half),\n makePlane({ x: 0, y: -1, z: 0 }, half),\n makePlane({ x: 0, y: 0, z: 1 }, half),\n makePlane({ x: 0, y: 0, z: -1 }, half),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n\nexport function makeNode(plane: CollisionPlane, children: [number, number]): CollisionNode {\n return { plane, children };\n}\n\nexport function makeBspModel(\n planes: CollisionPlane[],\n nodes: CollisionNode[],\n leaves: CollisionLeaf[],\n brushes: CollisionBrush[],\n leafBrushes: number[]\n): CollisionModel {\n return {\n planes,\n nodes,\n leaves,\n brushes,\n leafBrushes,\n bmodels: [],\n };\n}\n\nexport function makeLeaf(contents: number, firstLeafBrush: number, numLeafBrushes: number): CollisionLeaf {\n return { contents, cluster: 0, area: 0, firstLeafBrush, numLeafBrushes };\n}\n\nexport function makeLeafModel(brushes: CollisionBrush[]): CollisionModel {\n const planes = brushes.flatMap((brush) => brush.sides.map((side) => side.plane));\n\n return {\n planes,\n nodes: [],\n leaves: [makeLeaf(0, 0, brushes.length)],\n brushes,\n leafBrushes: brushes.map((_, i) => i),\n bmodels: [],\n };\n}\n\nexport function makeBrushFromMinsMaxs(mins: Vec3, maxs: Vec3, contents = CONTENTS_SOLID): CollisionBrush {\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, maxs.x),\n makePlane({ x: -1, y: 0, z: 0 }, -mins.x),\n makePlane({ x: 0, y: 1, z: 0 }, maxs.y),\n makePlane({ x: 0, y: -1, z: 0 }, -mins.y),\n makePlane({ x: 0, y: 0, z: 1 }, maxs.z),\n makePlane({ x: 0, y: 0, z: -1 }, -mins.z),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n","import type { PlayerState, EntityState } from '@quake2ts/shared';\nimport type { GameStateSnapshot } from '@quake2ts/game';\n\nexport const createPlayerStateFactory = (overrides?: Partial<PlayerState>): PlayerState => ({\n pm_type: 0,\n pm_time: 0,\n pm_flags: 0,\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewAngles: { x: 0, y: 0, z: 0 },\n onGround: false,\n waterLevel: 0,\n watertype: 0,\n mins: { x: 0, y: 0, z: 0 },\n maxs: { x: 0, y: 0, z: 0 },\n damageAlpha: 0,\n damageIndicators: [],\n blend: [0, 0, 0, 0],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n ...overrides,\n});\n\nexport const createEntityStateFactory = (overrides?: Partial<EntityState>): EntityState => ({\n number: 0,\n origin: { x: 0, y: 0, z: 0 },\n angles: { x: 0, y: 0, z: 0 },\n oldOrigin: { x: 0, y: 0, z: 0 },\n modelIndex: 0,\n modelIndex2: 0,\n modelIndex3: 0,\n modelIndex4: 0,\n frame: 0,\n skinNum: 0,\n effects: 0,\n renderfx: 0,\n solid: 0,\n sound: 0,\n event: 0,\n ...overrides,\n});\n\nexport const createGameStateSnapshotFactory = (overrides?: Partial<GameStateSnapshot>): GameStateSnapshot => ({\n gravity: { x: 0, y: 0, z: -800 },\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewangles: { x: 0, y: 0, z: 0 },\n level: { timeSeconds: 0, frameNumber: 0, previousTimeSeconds: 0, deltaSeconds: 0.1 },\n entities: {\n activeCount: 0,\n worldClassname: 'worldspawn',\n },\n packetEntities: [],\n pmFlags: 0,\n pmType: 0,\n waterlevel: 0,\n watertype: 0,\n deltaAngles: { x: 0, y: 0, z: 0 },\n health: 100,\n armor: 0,\n ammo: 0,\n blend: [0, 0, 0, 0],\n damageAlpha: 0,\n damageIndicators: [],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n pm_time: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n pm_flags: 0,\n pm_type: 0,\n ...overrides,\n});\n","import { vi, type Mock } from 'vitest';\nimport { Entity, SpawnRegistry, ScriptHookRegistry, type SpawnContext, type EntitySystem } from '@quake2ts/game';\nimport { createRandomGenerator, type Vec3 } from '@quake2ts/shared';\n\n// Re-export generic helpers from shared\nexport { intersects, stairTrace, ladderTrace } from '@quake2ts/shared';\n\n// -- Types --\n\nexport interface MockEngine {\n sound: Mock<[Entity, number, string, number, number, number], void>;\n soundIndex: Mock<[string], number>;\n modelIndex: Mock<[string], number>;\n centerprintf: Mock<[Entity, string], void>;\n}\n\nexport interface MockGame {\n random: ReturnType<typeof createRandomGenerator>;\n registerEntitySpawn: Mock<[string, (entity: Entity) => void], void>;\n unregisterEntitySpawn: Mock<[string], void>;\n getCustomEntities: Mock<[], string[]>;\n hooks: ScriptHookRegistry;\n registerHooks: Mock<[any], any>;\n spawnWorld: Mock<[], void>;\n clientBegin: Mock<[any], void>;\n damage: Mock<[number], void>;\n}\n\nexport interface TestContext extends SpawnContext {\n entities: EntitySystem;\n game: MockGame;\n engine: MockEngine;\n}\n\n// -- Factories --\n\nexport const createMockEngine = (): MockEngine => ({\n sound: vi.fn(),\n soundIndex: vi.fn((sound: string) => 0),\n modelIndex: vi.fn((model: string) => 0),\n centerprintf: vi.fn(),\n});\n\nexport const createMockGame = (seed: number = 12345): { game: MockGame, spawnRegistry: SpawnRegistry } => {\n const spawnRegistry = new SpawnRegistry();\n const hooks = new ScriptHookRegistry();\n\n const game: MockGame = {\n random: createRandomGenerator({ seed }),\n registerEntitySpawn: vi.fn((classname: string, spawnFunc: (entity: Entity) => void) => {\n spawnRegistry.register(classname, (entity) => spawnFunc(entity));\n }),\n unregisterEntitySpawn: vi.fn((classname: string) => {\n spawnRegistry.unregister(classname);\n }),\n getCustomEntities: vi.fn(() => Array.from(spawnRegistry.keys())),\n hooks,\n registerHooks: vi.fn((newHooks) => hooks.register(newHooks)),\n spawnWorld: vi.fn(() => {\n hooks.onMapLoad('q2dm1');\n }),\n clientBegin: vi.fn((client) => {\n hooks.onPlayerSpawn({} as any);\n }),\n damage: vi.fn((amount: number) => {\n hooks.onDamage({} as any, null, null, amount, 0, 0);\n })\n };\n\n return { game, spawnRegistry };\n};\n\nexport function createTestContext(options?: { seed?: number, initialEntities?: Entity[] }): TestContext {\n const engine = createMockEngine();\n const seed = options?.seed ?? 12345;\n const { game, spawnRegistry } = createMockGame(seed);\n\n const traceFn = vi.fn((start: Vec3, end: Vec3, mins?: Vec3, maxs?: Vec3) => ({\n fraction: 1.0,\n ent: null,\n allsolid: false,\n startsolid: false,\n endpos: end,\n plane: { normal: { x: 0, y: 0, z: 1 }, dist: 0 },\n surfaceFlags: 0,\n contents: 0\n }));\n\n const entityList: Entity[] = options?.initialEntities ? [...options.initialEntities] : [];\n\n // Create hooks helper that interacts with the entity list\n const hooks = game.hooks;\n\n const entities = {\n spawn: vi.fn(() => {\n const ent = new Entity(entityList.length + 1);\n entityList.push(ent);\n hooks.onEntitySpawn(ent);\n return ent;\n }),\n free: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n hooks.onEntityRemove(ent);\n }),\n finalizeSpawn: vi.fn(),\n freeImmediate: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n }),\n setSpawnRegistry: vi.fn(),\n timeSeconds: 10,\n deltaSeconds: 0.1,\n modelIndex: vi.fn(() => 0),\n scheduleThink: vi.fn((entity: Entity, time: number) => {\n entity.nextthink = time;\n }),\n linkentity: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n multicast: vi.fn(),\n unicast: vi.fn(),\n engine,\n game,\n sound: vi.fn((ent: Entity, chan: number, sound: string, vol: number, attn: number, timeofs: number) => {\n engine.sound(ent, chan, sound, vol, attn, timeofs);\n }),\n soundIndex: vi.fn((sound: string) => engine.soundIndex(sound)),\n useTargets: vi.fn((entity: Entity, activator: Entity | null) => {\n }),\n findByTargetName: vi.fn(() => []),\n pickTarget: vi.fn(() => null),\n killBox: vi.fn(),\n rng: createRandomGenerator({ seed }),\n imports: {\n configstring: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n },\n level: {\n intermission_angle: { x: 0, y: 0, z: 0 },\n intermission_origin: { x: 0, y: 0, z: 0 },\n next_auto_save: 0,\n health_bar_entities: null\n },\n targetNameIndex: new Map(),\n forEachEntity: vi.fn((callback: (ent: Entity) => void) => {\n entityList.forEach(callback);\n }),\n find: vi.fn((predicate: (ent: Entity) => boolean) => {\n return entityList.find(predicate);\n }),\n findByClassname: vi.fn((classname: string) => {\n return entityList.find(e => e.classname === classname);\n }),\n beginFrame: vi.fn((timeSeconds: number) => {\n (entities as any).timeSeconds = timeSeconds;\n }),\n targetAwareness: {\n timeSeconds: 10,\n frameNumber: 1,\n sightEntity: null,\n soundEntity: null,\n },\n // Adding missing properties to satisfy EntitySystem interface partially or fully\n // We cast to unknown first anyway, but filling these in makes it safer for consumers\n skill: 1,\n deathmatch: false,\n coop: false,\n activeCount: entityList.length,\n world: entityList.find(e => e.classname === 'worldspawn') || new Entity(0),\n // ... other EntitySystem properties would go here\n } as unknown as EntitySystem;\n\n return {\n keyValues: {},\n entities,\n game,\n engine,\n health_multiplier: 1,\n warn: vi.fn(),\n free: vi.fn(),\n // Mock precache functions if they are part of SpawnContext in future or TestContext extensions\n precacheModel: vi.fn(),\n precacheSound: vi.fn(),\n precacheImage: vi.fn(),\n } as unknown as TestContext;\n}\n\nexport function createSpawnContext(): SpawnContext {\n return createTestContext();\n}\n\nexport function createEntity(): Entity {\n return new Entity(1);\n}\n","import { Entity, GameExports, GameImports } from '@quake2ts/game';\nimport { vi } from 'vitest';\n\nexport interface GameState {\n levelName: string;\n time: number;\n entities: Entity[];\n clients: any[]; // Mock client objects\n}\n\n/**\n * Creates a mock game state object.\n * @param overrides Optional overrides for the game state.\n */\nexport function createMockGameState(overrides?: Partial<GameState>): GameState {\n return {\n levelName: 'test_level',\n time: 0,\n entities: [],\n clients: [],\n ...overrides\n };\n}\n","import { NetworkTransport } from '@quake2ts/server';\nimport { NetDriver } from '@quake2ts/shared';\nimport { vi } from 'vitest';\n\n/**\n * Mock implementation of the NetworkTransport interface for server testing.\n * Allows simulating connections and errors.\n */\nexport class MockTransport implements NetworkTransport {\n public onConnectionCallback?: (driver: NetDriver, info?: any) => void;\n public onErrorCallback?: (error: Error) => void;\n public address: string = '127.0.0.1';\n public port: number = 27910;\n public sentMessages: Uint8Array[] = [];\n public receivedMessages: Uint8Array[] = [];\n public listening: boolean = false;\n\n public listenSpy = vi.fn().mockImplementation(async (port: number) => {\n this.port = port;\n this.listening = true;\n });\n public closeSpy = vi.fn().mockImplementation(() => {\n this.listening = false;\n });\n\n /**\n * Start listening on the specified port.\n */\n async listen(port: number): Promise<void> {\n return this.listenSpy(port);\n }\n\n /**\n * Close the transport.\n */\n close() {\n this.closeSpy();\n }\n\n /**\n * Register a callback for new connections.\n */\n onConnection(callback: (driver: NetDriver, info?: any) => void) {\n this.onConnectionCallback = callback;\n }\n\n /**\n * Register a callback for errors.\n */\n onError(callback: (error: Error) => void) {\n this.onErrorCallback = callback;\n }\n\n /**\n * Check if the transport is currently listening.\n */\n public isListening(): boolean {\n return this.listening;\n }\n\n /**\n * Helper to simulate a new connection.\n * @param driver The network driver for the connection.\n * @param info Optional connection info.\n */\n public simulateConnection(driver: NetDriver, info?: any) {\n if (this.onConnectionCallback) {\n this.onConnectionCallback(driver, info);\n }\n }\n\n /**\n * Helper to simulate an error.\n * @param error The error to simulate.\n */\n public simulateError(error: Error) {\n if (this.onErrorCallback) {\n this.onErrorCallback(error);\n }\n }\n}\n\n/**\n * Interface for mock UDP socket.\n * This is a partial mock of Node.js dgram.Socket or similar.\n */\nexport interface MockUDPSocket {\n send: (msg: Uint8Array, offset: number, length: number, port: number, address: string, callback?: (error: Error | null, bytes: number) => void) => void;\n on: (event: string, callback: (...args: any[]) => void) => void;\n close: () => void;\n bind: (port: number, address?: string) => void;\n address: () => { address: string; family: string; port: number };\n}\n\n/**\n * Creates a mock UDP socket.\n * @param overrides Optional overrides for the socket methods.\n */\nexport function createMockUDPSocket(overrides?: Partial<MockUDPSocket>): MockUDPSocket {\n const socket: MockUDPSocket = {\n send: vi.fn(),\n on: vi.fn(),\n close: vi.fn(),\n bind: vi.fn(),\n address: vi.fn().mockReturnValue({ address: '127.0.0.1', family: 'IPv4', port: 0 }),\n ...overrides,\n };\n return socket;\n}\n\n/**\n * Interface for network address.\n */\nexport interface NetworkAddress {\n ip: string;\n port: number;\n}\n\n/**\n * Creates a mock network address.\n * @param ip IP address (default: '127.0.0.1')\n * @param port Port number (default: 27910)\n */\nexport function createMockNetworkAddress(ip: string = '127.0.0.1', port: number = 27910): NetworkAddress {\n return { ip, port };\n}\n\n/**\n * Creates a configured MockTransport instance.\n * @param address Address to bind to (default: '127.0.0.1')\n * @param port Port to listen on (default: 27910)\n * @param overrides Optional overrides for the transport properties.\n */\nexport function createMockTransport(\n address: string = '127.0.0.1',\n port: number = 27910,\n overrides?: Partial<MockTransport>\n): MockTransport {\n const transport = new MockTransport();\n transport.address = address;\n transport.port = port;\n Object.assign(transport, overrides);\n return transport;\n}\n","import { Server, ServerState, ServerStatic, Client, ClientState } from '@quake2ts/server';\nimport { NetDriver, MAX_CONFIGSTRINGS, MAX_EDICTS, EntityState } from '@quake2ts/shared';\nimport { Entity } from '@quake2ts/game';\nimport { vi } from 'vitest';\n\n/**\n * Creates a mock server state object.\n * @param overrides Optional overrides for the server state.\n */\nexport function createMockServerState(overrides?: Partial<Server>): Server {\n return {\n state: ServerState.Game,\n attractLoop: false,\n loadGame: false,\n startTime: Date.now(),\n time: 0,\n frame: 0,\n name: 'test_map',\n collisionModel: null,\n configStrings: new Array(MAX_CONFIGSTRINGS).fill(''),\n baselines: new Array(MAX_EDICTS).fill(null),\n multicastBuf: new Uint8Array(0),\n ...overrides\n };\n}\n\n/**\n * Creates a mock server static object.\n * @param maxClients Maximum number of clients.\n * @param overrides Optional overrides for the server static state.\n */\nexport function createMockServerStatic(maxClients: number = 16, overrides?: Partial<ServerStatic>): ServerStatic {\n return {\n initialized: true,\n realTime: Date.now(),\n mapCmd: '',\n spawnCount: 1,\n clients: new Array(maxClients).fill(null),\n lastHeartbeat: 0,\n challenges: [],\n ...overrides\n };\n}\n\n/**\n * Creates a mock server client.\n * @param clientNum The client index.\n * @param overrides Optional overrides for the client.\n */\nexport function createMockServerClient(clientNum: number, overrides?: Partial<Client>): Client {\n // Create a minimal mock net driver\n const mockNet: NetDriver = {\n connect: vi.fn(),\n disconnect: vi.fn(),\n send: vi.fn(),\n onMessage: vi.fn(),\n onClose: vi.fn(),\n onError: vi.fn(),\n isConnected: vi.fn().mockReturnValue(true)\n };\n\n return {\n index: clientNum,\n state: ClientState.Connected,\n edict: { index: clientNum + 1 } as Entity,\n net: mockNet,\n netchan: {\n qport: 0,\n remoteAddress: '127.0.0.1',\n incomingSequence: 0,\n outgoingSequence: 0,\n lastReceived: 0,\n process: vi.fn(),\n transmit: vi.fn(),\n writeReliableByte: vi.fn(),\n writeReliableShort: vi.fn(),\n writeReliableLong: vi.fn(),\n writeReliableString: vi.fn(),\n writeReliableData: vi.fn(),\n } as any, // Cast as any because NetChan might be complex to fully mock here\n userInfo: '',\n lastMessage: 0,\n lastCommandTime: 0,\n commandCount: 0,\n messageQueue: [],\n frames: [],\n lastFrame: 0,\n lastPacketEntities: [],\n challenge: 0,\n lastConnect: 0,\n ping: 0,\n rate: 0,\n name: `Client${clientNum}`,\n messageLevel: 0,\n datagram: new Uint8Array(0),\n downloadSize: 0,\n downloadCount: 0,\n commandMsec: 0,\n frameLatency: [],\n messageSize: [],\n suppressCount: 0,\n commandQueue: [],\n lastCmd: {\n msec: 0,\n buttons: 0,\n angles: { x: 0, y: 0, z: 0 },\n forwardmove: 0,\n sidemove: 0,\n upmove: 0,\n sequence: 0,\n lightlevel: 0,\n impulse: 0,\n serverFrame: 0\n },\n ...overrides\n };\n}\n\n/**\n * Mock interface for the Server class (DedicatedServer).\n * This allows mocking the server instance itself.\n */\nexport interface MockServer {\n start(mapName: string): Promise<void>;\n stop(): void;\n // tick(): void; // runFrame is private in DedicatedServer, usually we simulate via game.frame\n multicast(origin: any, type: any, event: any, ...args: any[]): void;\n unicast(ent: Entity, reliable: boolean, event: any, ...args: any[]): void;\n configstring(index: number, value: string): void;\n kickPlayer(clientId: number): void;\n changeMap(mapName: string): Promise<void>;\n}\n\n/**\n * Creates a mock server instance.\n * @param overrides Optional overrides for server methods.\n */\nexport function createMockServer(overrides?: Partial<MockServer>): MockServer {\n return {\n start: vi.fn().mockResolvedValue(undefined),\n stop: vi.fn(),\n multicast: vi.fn(),\n unicast: vi.fn(),\n configstring: vi.fn(),\n kickPlayer: vi.fn(),\n changeMap: vi.fn().mockResolvedValue(undefined),\n ...overrides\n };\n}\n","import { JSDOM } from 'jsdom';\nimport { Canvas, Image, ImageData } from '@napi-rs/canvas';\nimport 'fake-indexeddb/auto';\nimport { MockPointerLock } from '../e2e/input.js';\nimport { createMockWebGL2Context } from './webgl.js';\n\nexport interface BrowserSetupOptions {\n url?: string;\n pretendToBeVisual?: boolean;\n resources?: \"usable\";\n enableWebGL2?: boolean;\n enablePointerLock?: boolean;\n}\n\n/**\n * Sets up a browser environment for testing using JSDOM and napi-rs/canvas.\n * This should be called in your vitest.setup.ts file.\n */\nexport function setupBrowserEnvironment(options: BrowserSetupOptions = {}) {\n const {\n url = 'http://localhost',\n pretendToBeVisual = true,\n resources = undefined,\n enableWebGL2 = false,\n enablePointerLock = false\n } = options;\n\n // Create a JSDOM instance\n const dom = new JSDOM('<!DOCTYPE html><html><head></head><body></body></html>', {\n url,\n pretendToBeVisual,\n resources\n });\n\n // Set up global variables\n global.window = dom.window as any;\n global.document = dom.window.document;\n\n // Handle navigator assignment safely (handling read-only global.navigator if needed)\n try {\n // @ts-ignore\n global.navigator = dom.window.navigator;\n } catch (e) {\n // If direct assignment fails, try Object.defineProperty\n try {\n Object.defineProperty(global, 'navigator', {\n value: dom.window.navigator,\n writable: true,\n configurable: true\n });\n } catch (e2) {\n console.warn('Could not assign global.navigator, skipping.');\n }\n }\n\n global.location = dom.window.location;\n global.HTMLElement = dom.window.HTMLElement;\n global.HTMLCanvasElement = dom.window.HTMLCanvasElement;\n\n // Polyfill global Event constructors to match JSDOM's window\n global.Event = dom.window.Event;\n global.CustomEvent = dom.window.CustomEvent;\n global.DragEvent = dom.window.DragEvent as any;\n global.MouseEvent = dom.window.MouseEvent;\n global.KeyboardEvent = dom.window.KeyboardEvent;\n global.FocusEvent = dom.window.FocusEvent;\n global.WheelEvent = dom.window.WheelEvent;\n global.InputEvent = dom.window.InputEvent;\n global.UIEvent = dom.window.UIEvent;\n\n // Setup Storage mocks\n // First try to use JSDOM's localStorage\n try {\n global.localStorage = dom.window.localStorage;\n } catch (e) {\n // Ignore if it fails (e.g. strict mode)\n }\n\n // Fallback if not present\n if (!global.localStorage) {\n const storage = new Map<string, string>();\n global.localStorage = {\n getItem: (key: string) => storage.get(key) || null,\n setItem: (key: string, value: string) => storage.set(key, value),\n removeItem: (key: string) => storage.delete(key),\n clear: () => storage.clear(),\n key: (index: number) => Array.from(storage.keys())[index] || null,\n get length() { return storage.size; }\n } as Storage;\n }\n\n // Override document.createElement for canvas elements to use napi-rs/canvas\n const originalCreateElement = document.createElement.bind(document);\n document.createElement = function (tagName: string, options?: any) {\n if (tagName.toLowerCase() === 'canvas') {\n const napiCanvas = new Canvas(300, 150); // default canvas size\n\n // Create a wrapper that extends the DOM canvas element\n const domCanvas = originalCreateElement('canvas', options);\n\n // Copy properties and methods from napi-rs canvas to DOM canvas\n Object.defineProperty(domCanvas, 'width', {\n get: () => napiCanvas.width,\n set: (value) => { napiCanvas.width = value; },\n enumerable: true,\n configurable: true\n });\n\n Object.defineProperty(domCanvas, 'height', {\n get: () => napiCanvas.height,\n set: (value) => { napiCanvas.height = value; },\n enumerable: true,\n configurable: true\n });\n\n // Override getContext to return appropriate context\n const originalGetContext = domCanvas.getContext.bind(domCanvas);\n domCanvas.getContext = function(contextId: string, options?: any) {\n if (contextId === '2d') {\n return napiCanvas.getContext('2d', options);\n }\n\n if (enableWebGL2 && contextId === 'webgl2') {\n return createMockWebGL2Context(domCanvas as HTMLCanvasElement);\n }\n\n // For webgl/webgl2, return jsdom's default context (null or mock)\n // or the original behavior if needed.\n if (contextId === 'webgl' || contextId === 'webgl2') {\n return originalGetContext(contextId, options);\n }\n return napiCanvas.getContext(contextId as any, options);\n } as any;\n\n // Store reference to napi canvas for direct access if needed\n (domCanvas as any).__napiCanvas = napiCanvas;\n\n return domCanvas;\n }\n return originalCreateElement(tagName, options);\n } as any;\n\n // Also override HTMLCanvasElement.prototype.getContext to support direct instantiation via JSDOM\n if (enableWebGL2) {\n const originalProtoGetContext = global.HTMLCanvasElement.prototype.getContext;\n global.HTMLCanvasElement.prototype.getContext = function (\n contextId: string,\n options?: any\n ): any {\n if (contextId === 'webgl2') {\n return createMockWebGL2Context(this);\n }\n return originalProtoGetContext.call(this, contextId, options);\n };\n }\n\n // Set up global Image constructor\n global.Image = Image as any;\n\n // Set up global ImageData constructor\n global.ImageData = ImageData as any;\n\n // Mock createImageBitmap if not available\n if (typeof global.createImageBitmap === 'undefined') {\n global.createImageBitmap = async function (\n image: any, // Relax type to allow passing different image sources\n _options?: ImageBitmapOptions\n ): Promise<any> {\n // Handle ImageData specially\n if (image && typeof image.width === 'number' && typeof image.height === 'number') {\n // For testing purposes, we can create a small canvas with the image data\n const canvas = new Canvas(image.width, image.height);\n const ctx = canvas.getContext('2d');\n // Only try to put data if it looks like ImageData\n if (image.data) {\n ctx.putImageData(image as any, 0, 0);\n }\n return canvas;\n }\n // Fallback for other sources (e.g. Image element) - return empty canvas of generic size\n const canvas = new Canvas(100, 100);\n return canvas;\n } as any;\n }\n\n // Mock btoa and atob if not available\n if (typeof global.btoa === 'undefined') {\n global.btoa = function (str: string): string {\n return Buffer.from(str, 'binary').toString('base64');\n };\n }\n\n if (typeof global.atob === 'undefined') {\n global.atob = function (str: string): string {\n return Buffer.from(str, 'base64').toString('binary');\n };\n }\n\n // Mock Pointer Lock API\n if (enablePointerLock) {\n MockPointerLock.setup(global.document);\n }\n\n // Mock requestAnimationFrame\n // We use a simplified version that runs immediately or with small delay for tests\n if (typeof global.requestAnimationFrame === 'undefined') {\n let lastTime = 0;\n global.requestAnimationFrame = (callback: FrameRequestCallback) => {\n const currTime = Date.now();\n const timeToCall = Math.max(0, 16 - (currTime - lastTime));\n const id = setTimeout(() => {\n callback(currTime + timeToCall);\n }, timeToCall);\n lastTime = currTime + timeToCall;\n return id as unknown as number;\n };\n\n global.cancelAnimationFrame = (id: number) => {\n clearTimeout(id);\n };\n }\n}\n\n/**\n * Cleans up the browser environment.\n */\nexport function teardownBrowserEnvironment() {\n // Optional cleanup if needed, though usually global scope cleanup is handled by test runner context\n // or by just overriding it again.\n // For strict cleanup, we could delete globals, but in Vitest environment, it might persist?\n // We'll leave it simple for now or just undefined them.\n\n // @ts-ignore\n delete global.window;\n // @ts-ignore\n delete global.document;\n // @ts-ignore\n delete global.navigator;\n // @ts-ignore\n delete global.localStorage;\n // @ts-ignore\n delete global.location;\n // @ts-ignore\n delete global.HTMLElement;\n // @ts-ignore\n delete global.HTMLCanvasElement;\n // @ts-ignore\n delete global.Image;\n // @ts-ignore\n delete global.ImageData;\n // @ts-ignore\n delete global.createImageBitmap;\n\n // @ts-ignore\n delete global.Event;\n // @ts-ignore\n delete global.CustomEvent;\n // @ts-ignore\n delete global.DragEvent;\n // @ts-ignore\n delete global.MouseEvent;\n // @ts-ignore\n delete global.KeyboardEvent;\n // @ts-ignore\n delete global.FocusEvent;\n // @ts-ignore\n delete global.WheelEvent;\n // @ts-ignore\n delete global.InputEvent;\n // @ts-ignore\n delete global.UIEvent;\n\n // Note: btoa/atob might be native in newer Node versions, so be careful deleting them if they were original.\n // But here we only set them if undefined.\n}\n","\nexport class MockPointerLock {\n static setup(doc: Document) {\n // Mock pointerLockElement property\n let _pointerLockElement: Element | null = null;\n\n Object.defineProperty(doc, 'pointerLockElement', {\n get: () => _pointerLockElement,\n configurable: true\n });\n\n // Mock exitPointerLock\n doc.exitPointerLock = () => {\n if (_pointerLockElement) {\n _pointerLockElement = null;\n doc.dispatchEvent(new Event('pointerlockchange'));\n }\n };\n\n // Mock requestPointerLock on Element prototype\n // We need to extend the Element interface to make TS happy if we were strict,\n // but here we are modifying the prototype directly.\n // @ts-ignore\n (global.HTMLElement.prototype as any).requestPointerLock = function() {\n // In a real browser this is async and requires user gesture,\n // but for tests we make it immediate.\n _pointerLockElement = this;\n doc.dispatchEvent(new Event('pointerlockchange'));\n };\n }\n}\n\nexport class InputInjector {\n constructor(private doc: Document, private win: any) {}\n\n keyDown(key: string, code?: string) {\n const event = new this.win.KeyboardEvent('keydown', {\n key,\n code: code || key,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n this.doc.dispatchEvent(event);\n }\n\n keyUp(key: string, code?: string) {\n const event = new this.win.KeyboardEvent('keyup', {\n key,\n code: code || key,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n this.doc.dispatchEvent(event);\n }\n\n mouseMove(movementX: number, movementY: number, clientX = 0, clientY = 0) {\n const event = new this.win.MouseEvent('mousemove', {\n bubbles: true,\n cancelable: true,\n view: this.win,\n clientX,\n clientY,\n movementX, // Note: JSDOM might not support this standard property fully on event init\n movementY\n } as any);\n\n // Force movement properties if JSDOM doesn't handle them\n Object.defineProperty(event, 'movementX', { value: movementX });\n Object.defineProperty(event, 'movementY', { value: movementY });\n\n // Dispatch to pointer lock element if active, otherwise document\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n mouseDown(button: number = 0) {\n const event = new this.win.MouseEvent('mousedown', {\n button,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n mouseUp(button: number = 0) {\n const event = new this.win.MouseEvent('mouseup', {\n button,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n wheel(deltaY: number) {\n const event = new this.win.WheelEvent('wheel', {\n deltaY,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n}\n","\nexport function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext {\n const gl = {\n canvas,\n drawingBufferWidth: canvas.width,\n drawingBufferHeight: canvas.height,\n\n // Constants\n VERTEX_SHADER: 0x8B31,\n FRAGMENT_SHADER: 0x8B30,\n COMPILE_STATUS: 0x8B81,\n LINK_STATUS: 0x8B82,\n ARRAY_BUFFER: 0x8892,\n ELEMENT_ARRAY_BUFFER: 0x8893,\n STATIC_DRAW: 0x88E4,\n DYNAMIC_DRAW: 0x88E8,\n FLOAT: 0x1406,\n DEPTH_TEST: 0x0B71,\n BLEND: 0x0BE2,\n SRC_ALPHA: 0x0302,\n ONE_MINUS_SRC_ALPHA: 0x0303,\n TEXTURE_2D: 0x0DE1,\n RGBA: 0x1908,\n UNSIGNED_BYTE: 0x1401,\n COLOR_BUFFER_BIT: 0x4000,\n DEPTH_BUFFER_BIT: 0x0100,\n TRIANGLES: 0x0004,\n TRIANGLE_STRIP: 0x0005,\n TRIANGLE_FAN: 0x0006,\n\n // Methods\n createShader: () => ({}),\n shaderSource: () => {},\n compileShader: () => {},\n getShaderParameter: (_: any, param: number) => {\n if (param === 0x8B81) return true; // COMPILE_STATUS\n return true;\n },\n getShaderInfoLog: () => '',\n createProgram: () => ({}),\n attachShader: () => {},\n linkProgram: () => {},\n getProgramParameter: (_: any, param: number) => {\n if (param === 0x8B82) return true; // LINK_STATUS\n return true;\n },\n getProgramInfoLog: () => '',\n useProgram: () => {},\n createBuffer: () => ({}),\n bindBuffer: () => {},\n bufferData: () => {},\n enableVertexAttribArray: () => {},\n vertexAttribPointer: () => {},\n enable: () => {},\n disable: () => {},\n depthMask: () => {},\n blendFunc: () => {},\n viewport: () => {},\n clearColor: () => {},\n clear: () => {},\n createTexture: () => ({}),\n bindTexture: () => {},\n texImage2D: () => {},\n texParameteri: () => {},\n activeTexture: () => {},\n uniform1i: () => {},\n uniform1f: () => {},\n uniform2f: () => {},\n uniform3f: () => {},\n uniform4f: () => {},\n uniformMatrix4fv: () => {},\n getUniformLocation: () => ({}),\n getAttribLocation: () => 0,\n drawArrays: () => {},\n drawElements: () => {},\n createVertexArray: () => ({}),\n bindVertexArray: () => {},\n deleteShader: () => {},\n deleteProgram: () => {},\n deleteBuffer: () => {},\n deleteTexture: () => {},\n deleteVertexArray: () => {},\n\n // WebGL2 specific\n texImage3D: () => {},\n uniformBlockBinding: () => {},\n getExtension: () => null,\n } as unknown as WebGL2RenderingContext;\n\n return gl;\n}\n","import { Canvas, Image, ImageData } from '@napi-rs/canvas';\nimport { createMockWebGL2Context } from './webgl.js';\n\nexport interface DrawCall {\n method: string;\n args: any[];\n}\n\n/**\n * Creates a mock canvas element with WebGL2 support.\n */\nexport function createMockCanvas(width: number = 300, height: number = 150): HTMLCanvasElement {\n // If we are in JSDOM environment, use document.createElement\n if (typeof document !== 'undefined' && document.createElement) {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n\n // Otherwise use napi-rs/canvas directly\n const canvas = new Canvas(width, height);\n\n // Patch getContext to return mock WebGL2 context\n const originalGetContext = canvas.getContext.bind(canvas);\n canvas.getContext = function(contextId: string, options?: any) {\n if (contextId === 'webgl2') {\n return createMockWebGL2Context(canvas as unknown as HTMLCanvasElement);\n }\n if (contextId === '2d') {\n return originalGetContext('2d', options);\n }\n return originalGetContext(contextId as any, options);\n } as any;\n\n return canvas as unknown as HTMLCanvasElement;\n}\n\n/**\n * Creates a mock 2D rendering context.\n */\nexport function createMockCanvasContext2D(canvas?: HTMLCanvasElement): CanvasRenderingContext2D {\n if (!canvas) {\n canvas = createMockCanvas();\n }\n return canvas.getContext('2d') as unknown as CanvasRenderingContext2D;\n}\n\n/**\n * Spies on draw operations for verification.\n * Note: This modifies the context prototype or instance methods.\n */\nexport function captureCanvasDrawCalls(context: CanvasRenderingContext2D): DrawCall[] {\n const drawCalls: DrawCall[] = [];\n const methodsToSpy = [\n 'fillRect', 'strokeRect', 'clearRect',\n 'fillText', 'strokeText',\n 'drawImage',\n 'beginPath', 'closePath', 'moveTo', 'lineTo', 'arc', 'arcTo', 'bezierCurveTo', 'quadraticCurveTo',\n 'stroke', 'fill',\n 'putImageData'\n ];\n\n methodsToSpy.forEach(method => {\n // @ts-ignore\n const original = context[method];\n if (typeof original === 'function') {\n // @ts-ignore\n context[method] = function(...args: any[]) {\n drawCalls.push({ method, args });\n return original.apply(this, args);\n };\n }\n });\n\n return drawCalls;\n}\n\n/**\n * Creates a mock ImageData object.\n */\nexport function createMockImageData(width: number, height: number, fillColor?: [number, number, number, number]): ImageData {\n const imageData = new ImageData(width, height);\n if (fillColor) {\n const [r, g, b, a] = fillColor;\n for (let i = 0; i < imageData.data.length; i += 4) {\n imageData.data[i] = r;\n imageData.data[i + 1] = g;\n imageData.data[i + 2] = b;\n imageData.data[i + 3] = a;\n }\n }\n return imageData;\n}\n\n/**\n * Creates a mock Image element.\n */\nexport function createMockImage(width?: number, height?: number, src?: string): HTMLImageElement {\n const img = new Image();\n if (width) img.width = width;\n if (height) img.height = height;\n if (src) img.src = src;\n return img as unknown as HTMLImageElement;\n}\n","export interface NodeSetupOptions {\n polyfillFetch?: boolean;\n}\n\n/**\n * Sets up a Node.js environment for testing.\n * This is primarily for backend or shared logic that doesn't rely on browser APIs.\n */\nexport function setupNodeEnvironment(options: NodeSetupOptions = {}) {\n // Add any Node-specific global setup here\n // For now, this is a placeholder or can be used for things like\n // polyfilling fetch if not present in older Node versions (though Quake2TS targets recent Node)\n\n if (options.polyfillFetch && typeof global.fetch === 'undefined') {\n // In a real scenario, we might import node-fetch here\n // global.fetch = ...\n }\n}\n","\nimport 'fake-indexeddb/auto';\n\n/**\n * Creates a mock Storage implementation (localStorage/sessionStorage).\n */\nexport function createMockLocalStorage(initialData: Record<string, string> = {}): Storage {\n const storage = new Map<string, string>(Object.entries(initialData));\n\n return {\n getItem: (key: string) => storage.get(key) || null,\n setItem: (key: string, value: string) => storage.set(key, value),\n removeItem: (key: string) => storage.delete(key),\n clear: () => storage.clear(),\n key: (index: number) => Array.from(storage.keys())[index] || null,\n get length() { return storage.size; }\n } as Storage;\n}\n\n/**\n * Creates a mock SessionStorage implementation.\n * Functionally identical to LocalStorage mock but distinct for testing isolation.\n */\nexport function createMockSessionStorage(initialData: Record<string, string> = {}): Storage {\n return createMockLocalStorage(initialData);\n}\n\n/**\n * Creates a mock IndexedDB factory.\n * Currently relies on 'fake-indexeddb/auto' being imported which mocks the global indexedDB.\n * This helper ensures the global is available or resets it.\n */\nexport function createMockIndexedDB(): IDBFactory {\n if (typeof indexedDB === 'undefined') {\n throw new Error('IndexedDB mock not found. Ensure fake-indexeddb is loaded.');\n }\n // In a real mock scenario we might want to return a fresh instance,\n // but fake-indexeddb patches the global.\n return indexedDB;\n}\n\nexport interface StorageScenario {\n storage: Storage | IDBFactory;\n populate(data: Record<string, any>): Promise<void> | void;\n verify(key: string, value: any): Promise<boolean> | boolean;\n}\n\n/**\n * Helper to setup a storage test scenario.\n */\nexport function createStorageTestScenario(storageType: 'local' | 'session' | 'indexed' = 'local'): StorageScenario {\n if (storageType === 'indexed') {\n const dbName = `test-db-${Math.random().toString(36).substring(7)}`;\n const storeName = 'test-store';\n const storage = createMockIndexedDB();\n\n return {\n storage,\n populate: async (data: Record<string, any>) => {\n return new Promise((resolve, reject) => {\n const req = storage.open(dbName, 1);\n req.onupgradeneeded = (e: any) => {\n const db = e.target.result;\n db.createObjectStore(storeName);\n };\n req.onsuccess = (e: any) => {\n const db = e.target.result;\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n Object.entries(data).forEach(([k, v]) => store.put(v, k));\n tx.oncomplete = () => {\n db.close();\n resolve();\n };\n tx.onerror = () => reject(tx.error);\n };\n req.onerror = () => reject(req.error);\n });\n },\n verify: async (key: string, value: any) => {\n return new Promise((resolve, reject) => {\n const req = storage.open(dbName, 1);\n req.onsuccess = (e: any) => {\n const db = e.target.result;\n if (!db.objectStoreNames.contains(storeName)) {\n db.close();\n resolve(false);\n return;\n }\n const tx = db.transaction(storeName, 'readonly');\n const store = tx.objectStore(storeName);\n const getReq = store.get(key);\n getReq.onsuccess = () => {\n const result = getReq.result === value;\n db.close();\n resolve(result);\n };\n getReq.onerror = () => {\n db.close();\n resolve(false);\n };\n };\n req.onerror = () => reject(req.error);\n });\n }\n };\n }\n\n const storage = storageType === 'local' ? createMockLocalStorage() : createMockSessionStorage();\n\n return {\n storage,\n populate(data) {\n Object.entries(data).forEach(([k, v]) => storage.setItem(k, v));\n },\n verify(key, value) {\n return storage.getItem(key) === value;\n }\n };\n}\n","\n// Basic mock of AudioContext\nexport function createMockAudioContext(): AudioContext {\n const context = {\n createGain: () => ({\n connect: () => {},\n gain: { value: 1, setValueAtTime: () => {} }\n }),\n createOscillator: () => ({\n connect: () => {},\n start: () => {},\n stop: () => {},\n frequency: { value: 440 }\n }),\n createBufferSource: () => ({\n connect: () => {},\n start: () => {},\n stop: () => {},\n buffer: null,\n playbackRate: { value: 1 },\n loop: false\n }),\n destination: {},\n currentTime: 0,\n state: 'running',\n resume: async () => {},\n suspend: async () => {},\n close: async () => {},\n decodeAudioData: async (buffer: ArrayBuffer) => ({\n duration: 1,\n length: 44100,\n sampleRate: 44100,\n numberOfChannels: 2,\n getChannelData: () => new Float32Array(44100)\n }),\n createBuffer: (channels: number, length: number, sampleRate: number) => ({\n duration: length / sampleRate,\n length,\n sampleRate,\n numberOfChannels: channels,\n getChannelData: () => new Float32Array(length)\n }),\n // Helper to track events if needed\n _events: [] as AudioEvent[]\n };\n\n // Proxy to capture events\n return new Proxy(context as unknown as AudioContext, {\n get(target, prop, receiver) {\n if (prop === '_events') return (target as any)._events;\n const value = Reflect.get(target, prop, receiver);\n if (typeof value === 'function') {\n return (...args: any[]) => {\n (target as any)._events.push({ type: String(prop), args });\n return Reflect.apply(value, target, args);\n };\n }\n return value;\n }\n });\n}\n\n/**\n * Replaces the global AudioContext with a mock.\n */\nexport function setupMockAudioContext() {\n if (typeof global.AudioContext === 'undefined' && typeof global.window !== 'undefined') {\n // @ts-ignore\n global.AudioContext = class {\n constructor() {\n return createMockAudioContext();\n }\n };\n // @ts-ignore\n global.window.AudioContext = global.AudioContext;\n // @ts-ignore\n global.window.webkitAudioContext = global.AudioContext;\n }\n}\n\n/**\n * Restores the original AudioContext (if it was mocked).\n */\nexport function teardownMockAudioContext() {\n // If we mocked it on global, we might want to remove it.\n // However, usually in JSDOM it doesn't exist, so we just leave it or delete it.\n // @ts-ignore\n if (global.AudioContext && global.AudioContext.toString().includes('class')) {\n // @ts-ignore\n delete global.AudioContext;\n // @ts-ignore\n delete global.window.AudioContext;\n // @ts-ignore\n delete global.window.webkitAudioContext;\n }\n}\n\nexport interface AudioEvent {\n type: string;\n args: any[];\n}\n\n/**\n * Captures audio operations for verification.\n * Note: Only works if the context was created via createMockAudioContext which proxies calls.\n */\nexport function captureAudioEvents(context: AudioContext): AudioEvent[] {\n return (context as any)._events || [];\n}\n","\nexport interface MockRAF {\n tick(timestamp?: number): void;\n advance(deltaMs?: number): void;\n getCallbacks(): FrameRequestCallback[];\n reset(): void;\n enable(): void;\n disable(): void;\n}\n\nlet activeMockRAF: MockRAF | undefined;\n\n/**\n * Creates a mock implementation of requestAnimationFrame that allows manual control.\n * It replaces the global requestAnimationFrame and cancelAnimationFrame.\n */\nexport function createMockRAF(): MockRAF {\n let callbacks: { id: number; callback: FrameRequestCallback }[] = [];\n let nextId = 1;\n let currentTime = 0;\n\n const originalRAF = global.requestAnimationFrame;\n const originalCancelRAF = global.cancelAnimationFrame;\n\n const raf = (callback: FrameRequestCallback): number => {\n const id = nextId++;\n callbacks.push({ id, callback });\n return id;\n };\n\n const cancel = (id: number): void => {\n callbacks = callbacks.filter(cb => cb.id !== id);\n };\n\n const mock: MockRAF = {\n tick(timestamp?: number) {\n if (typeof timestamp !== 'number') {\n currentTime += 16.6; // Default to ~60fps\n } else {\n currentTime = timestamp;\n }\n\n const currentCallbacks = [...callbacks];\n callbacks = []; // Clear before execution so new RAFs go to next frame\n\n currentCallbacks.forEach(({ callback }) => {\n callback(currentTime);\n });\n },\n\n advance(deltaMs: number = 16.6) {\n this.tick(currentTime + deltaMs);\n },\n\n getCallbacks() {\n return callbacks.map(c => c.callback);\n },\n\n reset() {\n callbacks = [];\n nextId = 1;\n currentTime = 0;\n },\n\n enable() {\n activeMockRAF = this;\n global.requestAnimationFrame = raf as any;\n global.cancelAnimationFrame = cancel as any;\n },\n\n disable() {\n if (activeMockRAF === this) {\n activeMockRAF = undefined;\n }\n\n if (originalRAF) {\n global.requestAnimationFrame = originalRAF;\n } else {\n // @ts-ignore\n delete global.requestAnimationFrame;\n }\n\n if (originalCancelRAF) {\n global.cancelAnimationFrame = originalCancelRAF;\n } else {\n // @ts-ignore\n delete global.cancelAnimationFrame;\n }\n }\n };\n\n return mock;\n}\n\n/**\n * Creates a mock Performance object with controllable time.\n */\nexport function createMockPerformance(startTime: number = 0): Performance {\n let currentTime = startTime;\n\n const mockPerf = {\n now: () => currentTime,\n timeOrigin: startTime,\n timing: {\n navigationStart: startTime,\n },\n clearMarks: () => {},\n clearMeasures: () => {},\n clearResourceTimings: () => {},\n getEntries: () => [],\n getEntriesByName: () => [],\n getEntriesByType: () => [],\n mark: () => {},\n measure: () => {},\n setResourceTimingBufferSize: () => {},\n toJSON: () => ({}),\n addEventListener: () => {},\n removeEventListener: () => {},\n dispatchEvent: () => true,\n } as unknown as Performance;\n\n (mockPerf as any).advance = (deltaMs: number) => {\n currentTime += deltaMs;\n };\n (mockPerf as any).setTime = (time: number) => {\n currentTime = time;\n };\n\n return mockPerf;\n}\n\nexport interface ControlledTimer {\n tick(): void;\n advanceBy(ms: number): void;\n clear(): void;\n restore(): void;\n}\n\n/**\n * Creates a controlled timer that replaces global setTimeout/setInterval.\n * Allows deterministic time advancement.\n */\nexport function createControlledTimer(): ControlledTimer {\n let currentTime = 0;\n interface Timer {\n id: number;\n callback: Function;\n dueTime: number;\n interval?: number;\n args: any[];\n }\n let timers: Timer[] = [];\n let nextId = 1;\n\n const originalSetTimeout = global.setTimeout;\n const originalClearTimeout = global.clearTimeout;\n const originalSetInterval = global.setInterval;\n const originalClearInterval = global.clearInterval;\n\n const mockSetTimeout = (callback: Function, delay: number = 0, ...args: any[]) => {\n const id = nextId++;\n timers.push({ id, callback, dueTime: currentTime + delay, args });\n return id;\n };\n\n const mockClearTimeout = (id: any) => {\n timers = timers.filter(t => t.id !== id);\n };\n\n const mockSetInterval = (callback: Function, delay: number = 0, ...args: any[]) => {\n const id = nextId++;\n timers.push({ id, callback, dueTime: currentTime + delay, interval: delay, args });\n return id;\n };\n\n const mockClearInterval = (id: any) => {\n timers = timers.filter(t => t.id !== id);\n };\n\n global.setTimeout = mockSetTimeout as any;\n global.clearTimeout = mockClearTimeout as any;\n global.setInterval = mockSetInterval as any;\n global.clearInterval = mockClearInterval as any;\n\n return {\n tick() {\n this.advanceBy(0);\n },\n advanceBy(ms: number) {\n const targetTime = currentTime + ms;\n\n // Process timers until targetTime\n while (true) {\n // Find earliest timer\n let earliest: Timer | null = null;\n for (const t of timers) {\n if (!earliest || t.dueTime < earliest.dueTime) {\n earliest = t;\n }\n }\n\n if (!earliest || earliest.dueTime > targetTime) {\n break;\n }\n\n // Advance time to this timer\n currentTime = earliest.dueTime;\n\n // Execute\n const { callback, args, interval, id } = earliest;\n\n if (interval !== undefined) {\n earliest.dueTime += interval;\n // Prevent infinite loops with 0 interval\n if (interval === 0) earliest.dueTime += 1;\n } else {\n timers = timers.filter(t => t.id !== id);\n }\n\n callback(...args);\n }\n\n currentTime = targetTime;\n },\n clear() {\n timers = [];\n },\n restore() {\n global.setTimeout = originalSetTimeout;\n global.clearTimeout = originalClearTimeout;\n global.setInterval = originalSetInterval;\n global.clearInterval = originalClearInterval;\n }\n };\n}\n\n/**\n * Helper to simulate multiple frames of a game loop.\n * @param count Number of frames to simulate\n * @param frameTimeMs Time per frame in milliseconds\n * @param callback Optional callback to run inside the loop (e.g. triggering inputs)\n */\nexport function simulateFrames(count: number, frameTimeMs: number = 16.6, callback?: (frameIndex: number) => void) {\n if (!activeMockRAF) {\n throw new Error(\"simulateFrames requires an active MockRAF. Ensure createMockRAF().enable() is called.\");\n }\n\n for (let i = 0; i < count; i++) {\n if (callback) callback(i);\n activeMockRAF.advance(frameTimeMs);\n }\n}\n\n/**\n * Simulates frames using a provided MockRAF controller.\n */\nexport function simulateFramesWithMock(mock: MockRAF, count: number, frameTimeMs: number = 16.6, callback?: (frameIndex: number) => void) {\n for (let i = 0; i < count; i++) {\n if (callback) callback(i);\n mock.advance(frameTimeMs);\n }\n}\n","\nimport { chromium, Browser, Page, BrowserContext, BrowserContextOptions, LaunchOptions } from 'playwright';\nimport { createServer, IncomingMessage, ServerResponse, Server } from 'http';\nimport handler from 'serve-handler';\nimport path from 'path';\n\n/**\n * Interface for Test Client options\n */\nexport interface PlaywrightOptions {\n headless?: boolean;\n width?: number;\n height?: number;\n clientUrl?: string; // If provided, uses this URL. Otherwise starts a static server.\n serverUrl?: string; // Game server URL to connect to via query param\n rootPath?: string; // Root path for static server (defaults to process.cwd())\n launchOptions?: LaunchOptions;\n contextOptions?: BrowserContextOptions;\n}\n\nexport interface PlaywrightTestClient {\n browser: Browser;\n context: BrowserContext;\n page: Page;\n server?: Server; // HTTP server instance\n close: () => Promise<void>;\n navigate: (url?: string) => Promise<void>;\n waitForGame: (timeout?: number) => Promise<void>;\n injectInput: (type: string, data: any) => Promise<void>;\n}\n\n/**\n * Creates a Playwright-controlled browser environment for testing.\n * Can start a static server to serve the game client if no clientUrl is provided.\n */\nexport async function createPlaywrightTestClient(options: PlaywrightOptions = {}): Promise<PlaywrightTestClient> {\n let staticServer: Server | undefined;\n let clientUrl = options.clientUrl;\n const rootPath = options.rootPath || process.cwd();\n\n if (!clientUrl) {\n // Start a local static server\n staticServer = createServer((request: IncomingMessage, response: ServerResponse) => {\n return handler(request, response, {\n public: rootPath,\n cleanUrls: false,\n headers: [\n {\n source: '**/*',\n headers: [\n { key: 'Cache-Control', value: 'no-cache' },\n { key: 'Access-Control-Allow-Origin', value: '*' },\n { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },\n { key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' }\n ]\n }\n ]\n });\n });\n\n await new Promise<void>((resolve) => {\n if (!staticServer) return;\n staticServer.listen(0, () => {\n const addr = staticServer?.address();\n const port = typeof addr === 'object' ? addr?.port : 0;\n clientUrl = `http://localhost:${port}`;\n console.log(`Test client serving from ${rootPath} at ${clientUrl}`);\n resolve();\n });\n });\n }\n\n const browser = await chromium.launch({\n headless: options.headless ?? true,\n args: [\n '--use-gl=egl',\n '--ignore-gpu-blocklist',\n ...(options.launchOptions?.args || [])\n ],\n ...options.launchOptions\n });\n\n const width = options.width || 1280;\n const height = options.height || 720;\n\n const context = await browser.newContext({\n viewport: { width, height },\n deviceScaleFactor: 1,\n ...options.contextOptions\n });\n\n const page = await context.newPage();\n\n // Helper for closing\n const close = async () => {\n await browser.close();\n if (staticServer) {\n staticServer.close();\n }\n };\n\n const navigate = async (url?: string) => {\n const targetUrl = url || clientUrl;\n if (!targetUrl) throw new Error(\"No URL to navigate to\");\n\n let finalUrl = targetUrl;\n if (options.serverUrl && !targetUrl.includes('connect=')) {\n const separator = targetUrl.includes('?') ? '&' : '?';\n finalUrl = `${targetUrl}${separator}connect=${encodeURIComponent(options.serverUrl)}`;\n }\n\n console.log(`Navigating to: ${finalUrl}`);\n await page.goto(finalUrl, { waitUntil: 'domcontentloaded' });\n };\n\n return {\n browser,\n context,\n page,\n server: staticServer,\n close,\n navigate,\n waitForGame: async (timeout = 10000) => {\n await waitForGameReady(page, timeout);\n },\n injectInput: async (type, data) => {\n // Placeholder for input injection if we have a mechanism\n await page.evaluate(({type, data}) => {\n // @ts-ignore\n if (window.injectGameInput) window.injectGameInput(type, data);\n }, {type, data});\n }\n };\n}\n\nexport async function waitForGameReady(page: Page, timeout: number = 10000): Promise<void> {\n try {\n await page.waitForFunction(() => {\n // @ts-ignore\n return window.gameInstance && window.gameInstance.isReady; // Example check\n }, null, { timeout });\n } catch (e) {\n await page.waitForSelector('canvas', { timeout });\n }\n}\n\nexport interface GameStateCapture {\n [key: string]: any;\n}\n\nexport async function captureGameState(page: Page): Promise<GameStateCapture> {\n return await page.evaluate(() => {\n // @ts-ignore\n if (window.gameInstance && window.gameInstance.getState) {\n // @ts-ignore\n return window.gameInstance.getState();\n }\n return {};\n });\n}\n","\nexport interface NetworkSimulator {\n apply(page: any): Promise<void>;\n clear(page: any): Promise<void>;\n}\n\nexport type NetworkCondition = 'good' | 'slow' | 'unstable' | 'offline';\n\nexport interface NetworkConfig {\n offline: boolean;\n downloadThroughput: number; // bytes/sec\n uploadThroughput: number; // bytes/sec\n latency: number; // ms\n}\n\nconst CONDITIONS: Record<NetworkCondition, NetworkConfig> = {\n 'good': {\n offline: false,\n downloadThroughput: 10 * 1024 * 1024, // 10 Mbps\n uploadThroughput: 5 * 1024 * 1024, // 5 Mbps\n latency: 20\n },\n 'slow': {\n offline: false,\n downloadThroughput: 500 * 1024, // 500 Kbps\n uploadThroughput: 500 * 1024,\n latency: 400\n },\n 'unstable': {\n offline: false,\n downloadThroughput: 1 * 1024 * 1024,\n uploadThroughput: 1 * 1024 * 1024,\n latency: 100\n },\n 'offline': {\n offline: true,\n downloadThroughput: 0,\n uploadThroughput: 0,\n latency: 0\n }\n};\n\n/**\n * Simulates network conditions using Chrome DevTools Protocol (CDP) via Playwright.\n */\nexport function simulateNetworkCondition(condition: NetworkCondition): NetworkSimulator {\n const config = CONDITIONS[condition];\n return createCustomNetworkCondition(config.latency, 0, 0, config);\n}\n\n/**\n * Creates a custom network condition simulator.\n *\n * @param latency Latency in milliseconds\n * @param jitter Approximate jitter (variation in latency) - Note: CDP doesn't support jitter natively.\n * @param packetLoss Packet loss percentage (0-100) - Ignored for basic CDP emulation.\n */\nexport function createCustomNetworkCondition(\n latency: number,\n jitter: number = 0,\n packetLoss: number = 0,\n baseConfig?: NetworkConfig\n): NetworkSimulator {\n return {\n async apply(page: any) {\n const client = await page.context().newCDPSession(page);\n await client.send('Network.enable');\n await client.send('Network.emulateNetworkConditions', {\n offline: baseConfig?.offline || false,\n latency: latency + (Math.random() * jitter),\n downloadThroughput: baseConfig?.downloadThroughput || -1,\n uploadThroughput: baseConfig?.uploadThroughput || -1,\n });\n },\n async clear(page: any) {\n const client = await page.context().newCDPSession(page);\n await client.send('Network.emulateNetworkConditions', {\n offline: false,\n latency: 0,\n downloadThroughput: -1,\n uploadThroughput: -1,\n });\n }\n };\n}\n\n/**\n * Throttles bandwidth for the given page.\n */\nexport async function throttleBandwidth(page: any, bytesPerSecond: number) {\n const simulator = createCustomNetworkCondition(0, 0, 0, {\n offline: false,\n latency: 0,\n downloadThroughput: bytesPerSecond,\n uploadThroughput: bytesPerSecond\n });\n await simulator.apply(page);\n}\n","\nimport { Page } from 'playwright';\nimport path from 'path';\nimport fs from 'fs/promises';\n\nexport interface VisualDiff {\n pixelDiff: number;\n diffPath?: string;\n matched: boolean;\n}\n\n/**\n * Captures a screenshot of the current game state.\n */\nexport async function captureGameScreenshot(page: Page, name: string, options: { dir?: string, fullPage?: boolean } = {}): Promise<Buffer> {\n const dir = options.dir || '__screenshots__';\n const screenshotPath = path.join(dir, `${name}.png`);\n\n // Ensure directory exists\n await fs.mkdir(dir, { recursive: true });\n\n return await page.screenshot({\n path: screenshotPath,\n fullPage: options.fullPage ?? false,\n animations: 'disabled',\n caret: 'hide'\n });\n}\n\n/**\n * Compares two image buffers pixel-by-pixel.\n * Note: A robust implementation would use a library like 'pixelmatch' or 'looks-same'.\n * For now, we provide a basic placeholder or rely on simple buffer comparison.\n */\nexport async function compareScreenshots(baseline: Buffer, current: Buffer, threshold: number = 0.1): Promise<VisualDiff> {\n if (baseline.equals(current)) {\n return { pixelDiff: 0, matched: true };\n }\n\n return {\n pixelDiff: -1, // Unknown magnitude\n matched: false\n };\n}\n\nexport interface VisualScenario {\n capture(name: string): Promise<Buffer>;\n compare(name: string, baselineDir: string): Promise<VisualDiff>;\n}\n\n/**\n * Creates a helper for visual regression testing scenarios.\n */\nexport function createVisualTestScenario(page: Page, sceneName: string): VisualScenario {\n return {\n async capture(snapshotName: string) {\n return await captureGameScreenshot(page, `${sceneName}-${snapshotName}`);\n },\n async compare(snapshotName: string, baselineDir: string) {\n const name = `${sceneName}-${snapshotName}`;\n const current = await captureGameScreenshot(page, name, { dir: '__screenshots__/current' });\n\n try {\n const baselinePath = path.join(baselineDir, `${name}.png`);\n const baseline = await fs.readFile(baselinePath);\n return await compareScreenshots(baseline, current);\n } catch (e) {\n return { pixelDiff: -1, matched: false };\n }\n }\n };\n}\n"],"mappings":";AAAA,SAAS,UAAqB;AAoBvB,IAAM,yBAAyB,OAAyB;AAAA,EAC7D,WAAW,GAAG,GAAG;AAAA,EACjB,YAAY,GAAG,GAAG;AAAA,EAClB,WAAW,GAAG,GAAG;AAAA,EACjB,aAAa,GAAG,GAAG;AAAA,EACnB,YAAY,GAAG,GAAG;AAAA,EAClB,WAAW,GAAG,GAAmB,MAAM,IAAI,WAAW,CAAC,CAAC;AAAA,EACxD,OAAO,GAAG,GAAG;AAAA;AAAA,EAEb,WAAW,GAAG,GAAG;AAAA,EACjB,YAAY,GAAG,GAAG;AAAA,EAClB,YAAY,GAAG,GAAG;AAAA,EAClB,aAAa,GAAG,GAAG;AAAA,EACnB,YAAY,GAAG,GAAG;AAAA,EAClB,aAAa,GAAG,GAAG;AAAA,EACnB,YAAY,GAAG,GAAG;AAAA,EAClB,SAAS,GAAG,GAAmB,MAAM,IAAI,WAAW,CAAC,CAAC;AACxD;AAEO,IAAM,oBAAoB,OAAO;AAAA,EACtC,OAAO;AAAA;AAAA,EAGP,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA;AAAA,EAGtB,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,iBAAiB,uBAAuB;AAAA,EACxC,gBAAgB;AAAA;AAAA,EAGhB,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA;AAAA,EAGlB,cAAc;AAAA,EACd,UAAU;AAAA,EAEV,eAAe,EAAE,MAAM,MAAM,MAAM,KAAK;AAAA;AAAA,EAGxC,OAAO,GAAG,GAAG;AAAA,EACb,OAAO,GAAG,GAAG;AAAA,EACb,UAAU,GAAG,GAAG;AAAA,EAChB,SAAS,GAAG,GAAG;AAAA,EACf,iBAAiB,GAAG,GAAG,MAAM,IAAI;AAAA,EACjC,mBAAmB,GAAG,GAAG;AAAA,EACzB,oBAAoB,GAAG,GAAG;AAAA,EAC1B,mBAAmB,GAAG,GAAG;AAAA,EACzB,qBAAqB,GAAG,GAAG;AAAA,EAC3B,iBAAiB,GAAG,GAAmB,MAAM,IAAI,WAAW,CAAC,CAAC;AAAA,EAC9D,gBAAgB,GAAG,GAAG,MAAM,KAAK;AAAA,EACjC,YAAY,GAAG,GAAG,MAAM,KAAK;AAC/B;AAiCO,IAAM,yBAAyB,OAAyB;AAAA,EAC7D,aAAa,GAAG,GAAG,MAAM,CAAC;AAAA,EAC1B,iBAAiB,GAAG,GAAG,MAAM,CAAC;AAAA,EAC9B,WAAW,GAAG,GAAG,MAAM,CAAC;AAAA,EACxB,cAAc,GAAG,GAAG,MAAM,CAAC;AAAA,EAC3B,MAAM,GAAG,GAAG;AAAA,EACZ,iBAAiB,GAAG,GAAG;AAAA,EACvB,SAAS,GAAG,GAAG,MAAM,IAAI;AAAA,EACzB,UAAU,GAAG,GAAG,CAAC,WAAmB,IAAI;AAAA,EAExC,UAAU,GAAG,GAAG,MAAM,CAAC;AAAA,EACvB,UAAU,GAAG,GAAG,MAAM,CAAC;AAAA,EACvB,WAAW,GAAG,GAAG,MAAM,CAAC;AAAA,EACxB,YAAY,GAAG,GAAG,MAAM,CAAC;AAAA,EACzB,UAAU,GAAG,GAAG,MAAM,CAAC;AAAA,EACvB,WAAW,GAAG,GAAG,MAAM,CAAC;AAAA,EACxB,WAAW,GAAG,GAAG,MAAM,CAAC;AAAA,EAExB,YAAY,GAAG,GAAG,MAAM,EAAE;AAAA,EAC1B,gBAAgB,GAAG,GAAG,MAAM,EAAE;AAAA,EAE9B,WAAW,GAAG,GAAG,MAAM,CAAC;AAAA,EACxB,WAAW,GAAG,GAAG,MAAM,CAAC;AAAA,EACxB,aAAa,GAAG,GAAG,MAAM,CAAC;AAAA,EAE1B,UAAU,GAAG,GAAyB,CAAC,WAAmB,IAAI,WAAW,MAAM,CAAC;AAAA,EAEhF,SAAS,GAAG,GAAG;AAAA,EACf,SAAS,GAAG,GAAG;AACjB;;;AC7IA;AAAA,EACE;AAAA,EAMA;AAAA,OAEK;AAEA,SAAS,UAAU,QAAc,MAA8B;AACpE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI;AAAA,IACnG,UAAU,qBAAqB,MAAM;AAAA,EACvC;AACF;AAEO,SAAS,cAAc,MAAc,WAAW,gBAAgC;AACrF,QAAM,OAAO,OAAO;AACpB,QAAM,SAAS;AAAA,IACb,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI;AAAA,IACpC,UAAU,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI;AAAA,IACrC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI;AAAA,IACpC,UAAU,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,EAAE,GAAG,IAAI;AAAA,IACrC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI;AAAA,IACpC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI;AAAA,EACvC;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,OAAO,IAAI,CAAC,WAAW,EAAE,OAAO,cAAc,EAAE,EAAE;AAAA,EAC3D;AACF;AAEO,SAAS,SAAS,OAAuB,UAA2C;AACzF,SAAO,EAAE,OAAO,SAAS;AAC3B;AAEO,SAAS,aACd,QACA,OACA,QACA,SACA,aACgB;AAChB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AACF;AAEO,SAAS,SAAS,UAAkB,gBAAwB,gBAAuC;AACxG,SAAO,EAAE,UAAU,SAAS,GAAG,MAAM,GAAG,gBAAgB,eAAe;AACzE;AAEO,SAAS,cAAc,SAA2C;AACvE,QAAM,SAAS,QAAQ,QAAQ,CAAC,UAAU,MAAM,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC;AAE/E,SAAO;AAAA,IACL;AAAA,IACA,OAAO,CAAC;AAAA,IACR,QAAQ,CAAC,SAAS,GAAG,GAAG,QAAQ,MAAM,CAAC;AAAA,IACvC;AAAA,IACA,aAAa,QAAQ,IAAI,CAAC,GAAG,MAAM,CAAC;AAAA,IACpC,SAAS,CAAC;AAAA,EACZ;AACF;AAEO,SAAS,sBAAsB,MAAY,MAAY,WAAW,gBAAgC;AACvG,QAAM,SAAS;AAAA,IACb,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;AAAA,IACtC,UAAU,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC;AAAA,IACxC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;AAAA,IACtC,UAAU,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC;AAAA,IACxC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;AAAA,IACtC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,OAAO,IAAI,CAAC,WAAW,EAAE,OAAO,cAAc,EAAE,EAAE;AAAA,EAC3D;AACF;;;ACtFO,IAAM,2BAA2B,CAAC,eAAmD;AAAA,EAC1F,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC3B,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC7B,YAAY,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC/B,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EACzB,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EACzB,aAAa;AAAA,EACb,kBAAkB,CAAC;AAAA,EACnB,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,EAClB,OAAO,CAAC;AAAA,EACR,aAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAChC,aAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAChC,WAAW,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC9B,WAAW,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC9B,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,KAAK;AAAA,EACL,UAAU;AAAA,EACV,GAAG;AACL;AAEO,IAAM,2BAA2B,CAAC,eAAmD;AAAA,EAC1F,QAAQ;AAAA,EACR,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC3B,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC3B,WAAW,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC9B,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,GAAG;AACL;AAEO,IAAM,iCAAiC,CAAC,eAA+D;AAAA,EAC5G,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK;AAAA,EAC/B,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC3B,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC7B,YAAY,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC/B,OAAO,EAAE,aAAa,GAAG,aAAa,GAAG,qBAAqB,GAAG,cAAc,IAAI;AAAA,EACnF,UAAU;AAAA,IACR,aAAa;AAAA,IACb,gBAAgB;AAAA,EAClB;AAAA,EACA,gBAAgB,CAAC;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,aAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAChC,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,EAClB,aAAa;AAAA,EACb,kBAAkB,CAAC;AAAA,EACnB,OAAO,CAAC;AAAA,EACR,aAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAChC,aAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAChC,WAAW,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC9B,WAAW,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC9B,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,KAAK;AAAA,EACL,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AAAA,EACT,GAAG;AACL;;;ACtFA,SAAS,MAAAA,WAAqB;AAC9B,SAAS,QAAQ,eAAe,0BAAgE;AAChG,SAAS,6BAAwC;AAGjD,SAAS,YAAY,YAAY,mBAAmB;AA+B7C,IAAM,mBAAmB,OAAmB;AAAA,EACjD,OAAOA,IAAG,GAAG;AAAA,EACb,YAAYA,IAAG,GAAG,CAAC,UAAkB,CAAC;AAAA,EACtC,YAAYA,IAAG,GAAG,CAAC,UAAkB,CAAC;AAAA,EACtC,cAAcA,IAAG,GAAG;AACtB;AAEO,IAAM,iBAAiB,CAAC,OAAe,UAA4D;AACxG,QAAM,gBAAgB,IAAI,cAAc;AACxC,QAAM,QAAQ,IAAI,mBAAmB;AAErC,QAAM,OAAiB;AAAA,IACrB,QAAQ,sBAAsB,EAAE,KAAK,CAAC;AAAA,IACtC,qBAAqBA,IAAG,GAAG,CAAC,WAAmB,cAAwC;AACrF,oBAAc,SAAS,WAAW,CAAC,WAAW,UAAU,MAAM,CAAC;AAAA,IACjE,CAAC;AAAA,IACD,uBAAuBA,IAAG,GAAG,CAAC,cAAsB;AAClD,oBAAc,WAAW,SAAS;AAAA,IACpC,CAAC;AAAA,IACD,mBAAmBA,IAAG,GAAG,MAAM,MAAM,KAAK,cAAc,KAAK,CAAC,CAAC;AAAA,IAC/D;AAAA,IACA,eAAeA,IAAG,GAAG,CAAC,aAAa,MAAM,SAAS,QAAQ,CAAC;AAAA,IAC3D,YAAYA,IAAG,GAAG,MAAM;AACtB,YAAM,UAAU,OAAO;AAAA,IACzB,CAAC;AAAA,IACD,aAAaA,IAAG,GAAG,CAAC,WAAW;AAC7B,YAAM,cAAc,CAAC,CAAQ;AAAA,IAC/B,CAAC;AAAA,IACD,QAAQA,IAAG,GAAG,CAAC,WAAmB;AAChC,YAAM,SAAS,CAAC,GAAU,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,IACpD,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,MAAM,cAAc;AAC/B;AAEO,SAAS,kBAAkB,SAAsE;AACtG,QAAM,SAAS,iBAAiB;AAChC,QAAM,OAAO,SAAS,QAAQ;AAC9B,QAAM,EAAE,MAAM,cAAc,IAAI,eAAe,IAAI;AAEnD,QAAM,UAAUA,IAAG,GAAG,CAAC,OAAa,KAAW,MAAa,UAAiB;AAAA,IAC3E,UAAU;AAAA,IACV,KAAK;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO,EAAE,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE;AAAA,IAC/C,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,EAAE;AAEF,QAAM,aAAuB,SAAS,kBAAkB,CAAC,GAAG,QAAQ,eAAe,IAAI,CAAC;AAGxF,QAAM,QAAQ,KAAK;AAEnB,QAAM,WAAW;AAAA,IACf,OAAOA,IAAG,GAAG,MAAM;AACjB,YAAM,MAAM,IAAI,OAAO,WAAW,SAAS,CAAC;AAC5C,iBAAW,KAAK,GAAG;AACnB,YAAM,cAAc,GAAG;AACvB,aAAO;AAAA,IACT,CAAC;AAAA,IACD,MAAMA,IAAG,GAAG,CAAC,QAAgB;AAC3B,YAAM,MAAM,WAAW,QAAQ,GAAG;AAClC,UAAI,QAAQ,IAAI;AACd,mBAAW,OAAO,KAAK,CAAC;AAAA,MAC1B;AACA,YAAM,eAAe,GAAG;AAAA,IAC1B,CAAC;AAAA,IACD,eAAeA,IAAG,GAAG;AAAA,IACrB,eAAeA,IAAG,GAAG,CAAC,QAAgB;AACpC,YAAM,MAAM,WAAW,QAAQ,GAAG;AAClC,UAAI,QAAQ,IAAI;AACd,mBAAW,OAAO,KAAK,CAAC;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,IACD,kBAAkBA,IAAG,GAAG;AAAA,IACxB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,YAAYA,IAAG,GAAG,MAAM,CAAC;AAAA,IACzB,eAAeA,IAAG,GAAG,CAAC,QAAgB,SAAiB;AACrD,aAAO,YAAY;AAAA,IACrB,CAAC;AAAA,IACD,YAAYA,IAAG,GAAG;AAAA,IAClB,OAAO;AAAA,IACP,eAAeA,IAAG,GAAG,MAAM,CAAC;AAAA,IAC5B,WAAWA,IAAG,GAAG;AAAA,IACjB,SAASA,IAAG,GAAG;AAAA,IACf;AAAA,IACA;AAAA,IACA,OAAOA,IAAG,GAAG,CAAC,KAAa,MAAc,OAAe,KAAa,MAAc,YAAoB;AACrG,aAAO,MAAM,KAAK,MAAM,OAAO,KAAK,MAAM,OAAO;AAAA,IACnD,CAAC;AAAA,IACD,YAAYA,IAAG,GAAG,CAAC,UAAkB,OAAO,WAAW,KAAK,CAAC;AAAA,IAC7D,YAAYA,IAAG,GAAG,CAAC,QAAgB,cAA6B;AAAA,IAChE,CAAC;AAAA,IACD,kBAAkBA,IAAG,GAAG,MAAM,CAAC,CAAC;AAAA,IAChC,YAAYA,IAAG,GAAG,MAAM,IAAI;AAAA,IAC5B,SAASA,IAAG,GAAG;AAAA,IACf,KAAK,sBAAsB,EAAE,KAAK,CAAC;AAAA,IACnC,SAAS;AAAA,MACP,cAAcA,IAAG,GAAG;AAAA,MACpB,OAAO;AAAA,MACP,eAAeA,IAAG,GAAG,MAAM,CAAC;AAAA,IAC9B;AAAA,IACA,OAAO;AAAA,MACL,oBAAoB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,MACvC,qBAAqB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,MACxC,gBAAgB;AAAA,MAChB,qBAAqB;AAAA,IACvB;AAAA,IACA,iBAAiB,oBAAI,IAAI;AAAA,IACzB,eAAeA,IAAG,GAAG,CAAC,aAAoC;AACxD,iBAAW,QAAQ,QAAQ;AAAA,IAC7B,CAAC;AAAA,IACD,MAAMA,IAAG,GAAG,CAAC,cAAwC;AACnD,aAAO,WAAW,KAAK,SAAS;AAAA,IAClC,CAAC;AAAA,IACD,iBAAiBA,IAAG,GAAG,CAAC,cAAsB;AAC5C,aAAO,WAAW,KAAK,OAAK,EAAE,cAAc,SAAS;AAAA,IACvD,CAAC;AAAA,IACD,YAAYA,IAAG,GAAG,CAAC,gBAAwB;AACzC,MAAC,SAAiB,cAAc;AAAA,IAClC,CAAC;AAAA,IACD,iBAAiB;AAAA,MACf,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAAA;AAAA;AAAA,IAGA,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa,WAAW;AAAA,IACxB,OAAO,WAAW,KAAK,OAAK,EAAE,cAAc,YAAY,KAAK,IAAI,OAAO,CAAC;AAAA;AAAA,EAE3E;AAEA,SAAO;AAAA,IACL,WAAW,CAAC;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB,MAAMA,IAAG,GAAG;AAAA,IACZ,MAAMA,IAAG,GAAG;AAAA;AAAA,IAEZ,eAAeA,IAAG,GAAG;AAAA,IACrB,eAAeA,IAAG,GAAG;AAAA,IACrB,eAAeA,IAAG,GAAG;AAAA,EACvB;AACF;AAEO,SAAS,qBAAmC;AACjD,SAAO,kBAAkB;AAC3B;AAEO,SAAS,eAAuB;AACrC,SAAO,IAAI,OAAO,CAAC;AACrB;;;ACzLO,SAAS,oBAAoB,WAA2C;AAC3E,SAAO;AAAA,IACH,WAAW;AAAA,IACX,MAAM;AAAA,IACN,UAAU,CAAC;AAAA,IACX,SAAS,CAAC;AAAA,IACV,GAAG;AAAA,EACP;AACJ;;;ACpBA,SAAS,MAAAC,WAAU;AAMZ,IAAM,gBAAN,MAAgD;AAAA,EAAhD;AAGH,SAAO,UAAkB;AACzB,SAAO,OAAe;AACtB,SAAO,eAA6B,CAAC;AACrC,SAAO,mBAAiC,CAAC;AACzC,SAAO,YAAqB;AAE5B,SAAO,YAAYA,IAAG,GAAG,EAAE,mBAAmB,OAAO,SAAiB;AAClE,WAAK,OAAO;AACZ,WAAK,YAAY;AAAA,IACrB,CAAC;AACD,SAAO,WAAWA,IAAG,GAAG,EAAE,mBAAmB,MAAM;AAC/C,WAAK,YAAY;AAAA,IACrB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKD,MAAM,OAAO,MAA6B;AACtC,WAAO,KAAK,UAAU,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AACJ,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAmD;AAC5D,SAAK,uBAAuB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,UAAkC;AACtC,SAAK,kBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKO,cAAuB;AAC1B,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,mBAAmB,QAAmB,MAAY;AACrD,QAAI,KAAK,sBAAsB;AAC3B,WAAK,qBAAqB,QAAQ,IAAI;AAAA,IAC1C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,cAAc,OAAc;AAC/B,QAAI,KAAK,iBAAiB;AACtB,WAAK,gBAAgB,KAAK;AAAA,IAC9B;AAAA,EACJ;AACJ;AAkBO,SAAS,oBAAoB,WAAmD;AACnF,QAAM,SAAwB;AAAA,IAC1B,MAAMA,IAAG,GAAG;AAAA,IACZ,IAAIA,IAAG,GAAG;AAAA,IACV,OAAOA,IAAG,GAAG;AAAA,IACb,MAAMA,IAAG,GAAG;AAAA,IACZ,SAASA,IAAG,GAAG,EAAE,gBAAgB,EAAE,SAAS,aAAa,QAAQ,QAAQ,MAAM,EAAE,CAAC;AAAA,IAClF,GAAG;AAAA,EACP;AACA,SAAO;AACX;AAeO,SAAS,yBAAyB,KAAa,aAAa,OAAe,OAAuB;AACrG,SAAO,EAAE,IAAI,KAAK;AACtB;AAQO,SAAS,oBACZ,UAAkB,aAClB,OAAe,OACf,WACa;AACb,QAAM,YAAY,IAAI,cAAc;AACpC,YAAU,UAAU;AACpB,YAAU,OAAO;AACjB,SAAO,OAAO,WAAW,SAAS;AAClC,SAAO;AACX;;;AC/IA,SAAiB,aAAmC,mBAAmB;AACvE,SAAoB,mBAAmB,kBAA+B;AAEtE,SAAS,MAAAC,WAAU;AAMZ,SAAS,sBAAsB,WAAqC;AACvE,SAAO;AAAA,IACH,OAAO,YAAY;AAAA,IACnB,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAW,KAAK,IAAI;AAAA,IACpB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,eAAe,IAAI,MAAM,iBAAiB,EAAE,KAAK,EAAE;AAAA,IACnD,WAAW,IAAI,MAAM,UAAU,EAAE,KAAK,IAAI;AAAA,IAC1C,cAAc,IAAI,WAAW,CAAC;AAAA,IAC9B,GAAG;AAAA,EACP;AACJ;AAOO,SAAS,uBAAuB,aAAqB,IAAI,WAAiD;AAC7G,SAAO;AAAA,IACH,aAAa;AAAA,IACb,UAAU,KAAK,IAAI;AAAA,IACnB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS,IAAI,MAAM,UAAU,EAAE,KAAK,IAAI;AAAA,IACxC,eAAe;AAAA,IACf,YAAY,CAAC;AAAA,IACb,GAAG;AAAA,EACP;AACJ;AAOO,SAAS,uBAAuB,WAAmB,WAAqC;AAE3F,QAAM,UAAqB;AAAA,IACvB,SAASA,IAAG,GAAG;AAAA,IACf,YAAYA,IAAG,GAAG;AAAA,IAClB,MAAMA,IAAG,GAAG;AAAA,IACZ,WAAWA,IAAG,GAAG;AAAA,IACjB,SAASA,IAAG,GAAG;AAAA,IACf,SAASA,IAAG,GAAG;AAAA,IACf,aAAaA,IAAG,GAAG,EAAE,gBAAgB,IAAI;AAAA,EAC7C;AAEA,SAAO;AAAA,IACH,OAAO;AAAA,IACP,OAAO,YAAY;AAAA,IACnB,OAAO,EAAE,OAAO,YAAY,EAAE;AAAA,IAC9B,KAAK;AAAA,IACL,SAAS;AAAA,MACL,OAAO;AAAA,MACP,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,SAASA,IAAG,GAAG;AAAA,MACf,UAAUA,IAAG,GAAG;AAAA,MAChB,mBAAmBA,IAAG,GAAG;AAAA,MACzB,oBAAoBA,IAAG,GAAG;AAAA,MAC1B,mBAAmBA,IAAG,GAAG;AAAA,MACzB,qBAAqBA,IAAG,GAAG;AAAA,MAC3B,mBAAmBA,IAAG,GAAG;AAAA,IAC7B;AAAA;AAAA,IACA,UAAU;AAAA,IACV,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,IACT,WAAW;AAAA,IACX,oBAAoB,CAAC;AAAA,IACrB,WAAW;AAAA,IACX,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM,SAAS,SAAS;AAAA,IACxB,cAAc;AAAA,IACd,UAAU,IAAI,WAAW,CAAC;AAAA,IAC1B,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc,CAAC;AAAA,IACf,aAAa,CAAC;AAAA,IACd,eAAe;AAAA,IACf,cAAc,CAAC;AAAA,IACf,SAAS;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,MAC3B,aAAa;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,aAAa;AAAA,IACjB;AAAA,IACA,GAAG;AAAA,EACP;AACJ;AAqBO,SAAS,iBAAiB,WAA6C;AAC1E,SAAO;AAAA,IACH,OAAOA,IAAG,GAAG,EAAE,kBAAkB,MAAS;AAAA,IAC1C,MAAMA,IAAG,GAAG;AAAA,IACZ,WAAWA,IAAG,GAAG;AAAA,IACjB,SAASA,IAAG,GAAG;AAAA,IACf,cAAcA,IAAG,GAAG;AAAA,IACpB,YAAYA,IAAG,GAAG;AAAA,IAClB,WAAWA,IAAG,GAAG,EAAE,kBAAkB,MAAS;AAAA,IAC9C,GAAG;AAAA,EACP;AACJ;;;ACpJA,SAAS,aAAa;AACtB,SAAS,QAAQ,OAAO,iBAAiB;AACzC,OAAO;;;ACDA,IAAM,kBAAN,MAAsB;AAAA,EAC3B,OAAO,MAAM,KAAe;AAE1B,QAAI,sBAAsC;AAE1C,WAAO,eAAe,KAAK,sBAAsB;AAAA,MAC/C,KAAK,MAAM;AAAA,MACX,cAAc;AAAA,IAChB,CAAC;AAGD,QAAI,kBAAkB,MAAM;AAC1B,UAAI,qBAAqB;AACvB,8BAAsB;AACtB,YAAI,cAAc,IAAI,MAAM,mBAAmB,CAAC;AAAA,MAClD;AAAA,IACF;AAMA,IAAC,OAAO,YAAY,UAAkB,qBAAqB,WAAW;AAGpE,4BAAsB;AACtB,UAAI,cAAc,IAAI,MAAM,mBAAmB,CAAC;AAAA,IAClD;AAAA,EACF;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAAoB,KAAuB,KAAU;AAAjC;AAAuB;AAAA,EAAW;AAAA,EAEtD,QAAQ,KAAa,MAAe;AAClC,UAAM,QAAQ,IAAI,KAAK,IAAI,cAAc,WAAW;AAAA,MAClD;AAAA,MACA,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AACD,SAAK,IAAI,cAAc,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,KAAa,MAAe;AAChC,UAAM,QAAQ,IAAI,KAAK,IAAI,cAAc,SAAS;AAAA,MAChD;AAAA,MACA,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AACD,SAAK,IAAI,cAAc,KAAK;AAAA,EAC9B;AAAA,EAEA,UAAU,WAAmB,WAAmB,UAAU,GAAG,UAAU,GAAG;AACxE,UAAM,QAAQ,IAAI,KAAK,IAAI,WAAW,aAAa;AAAA,MACjD,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACA;AAAA,IACF,CAAQ;AAGR,WAAO,eAAe,OAAO,aAAa,EAAE,OAAO,UAAU,CAAC;AAC9D,WAAO,eAAe,OAAO,aAAa,EAAE,OAAO,UAAU,CAAC;AAI9D,UAAM,SAAS,KAAK,IAAI,sBAAsB,KAAK;AACnD,WAAO,cAAc,KAAK;AAAA,EAC5B;AAAA,EAEA,UAAU,SAAiB,GAAG;AAC3B,UAAM,QAAQ,IAAI,KAAK,IAAI,WAAW,aAAa;AAAA,MAClD;AAAA,MACA,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AAED,UAAM,SAAS,KAAK,IAAI,sBAAsB,KAAK;AACnD,WAAO,cAAc,KAAK;AAAA,EAC5B;AAAA,EAEA,QAAQ,SAAiB,GAAG;AAC1B,UAAM,QAAQ,IAAI,KAAK,IAAI,WAAW,WAAW;AAAA,MAC/C;AAAA,MACA,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AAED,UAAM,SAAS,KAAK,IAAI,sBAAsB,KAAK;AACnD,WAAO,cAAc,KAAK;AAAA,EAC5B;AAAA,EAEA,MAAM,QAAgB;AAClB,UAAM,QAAQ,IAAI,KAAK,IAAI,WAAW,SAAS;AAAA,MAC3C;AAAA,MACA,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,IACf,CAAC;AAED,UAAM,SAAS,KAAK,IAAI,sBAAsB,KAAK;AACnD,WAAO,cAAc,KAAK;AAAA,EAC9B;AACF;;;AChHO,SAAS,wBAAwB,QAAmD;AACvF,QAAM,KAAK;AAAA,IACP;AAAA,IACA,oBAAoB,OAAO;AAAA,IAC3B,qBAAqB,OAAO;AAAA;AAAA,IAG5B,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,cAAc;AAAA;AAAA,IAGd,cAAc,OAAO,CAAC;AAAA,IACtB,cAAc,MAAM;AAAA,IAAC;AAAA,IACrB,eAAe,MAAM;AAAA,IAAC;AAAA,IACtB,oBAAoB,CAAC,GAAQ,UAAkB;AAC3C,UAAI,UAAU,MAAQ,QAAO;AAC7B,aAAO;AAAA,IACX;AAAA,IACA,kBAAkB,MAAM;AAAA,IACxB,eAAe,OAAO,CAAC;AAAA,IACvB,cAAc,MAAM;AAAA,IAAC;AAAA,IACrB,aAAa,MAAM;AAAA,IAAC;AAAA,IACpB,qBAAqB,CAAC,GAAQ,UAAkB;AAC5C,UAAI,UAAU,MAAQ,QAAO;AAC7B,aAAO;AAAA,IACX;AAAA,IACA,mBAAmB,MAAM;AAAA,IACzB,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,cAAc,OAAO,CAAC;AAAA,IACtB,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,yBAAyB,MAAM;AAAA,IAAC;AAAA,IAChC,qBAAqB,MAAM;AAAA,IAAC;AAAA,IAC5B,QAAQ,MAAM;AAAA,IAAC;AAAA,IACf,SAAS,MAAM;AAAA,IAAC;AAAA,IAChB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,UAAU,MAAM;AAAA,IAAC;AAAA,IACjB,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,OAAO,MAAM;AAAA,IAAC;AAAA,IACd,eAAe,OAAO,CAAC;AAAA,IACvB,aAAa,MAAM;AAAA,IAAC;AAAA,IACpB,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,eAAe,MAAM;AAAA,IAAC;AAAA,IACtB,eAAe,MAAM;AAAA,IAAC;AAAA,IACtB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,WAAW,MAAM;AAAA,IAAC;AAAA,IAClB,kBAAkB,MAAM;AAAA,IAAC;AAAA,IACzB,oBAAoB,OAAO,CAAC;AAAA,IAC5B,mBAAmB,MAAM;AAAA,IACzB,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,cAAc,MAAM;AAAA,IAAC;AAAA,IACrB,mBAAmB,OAAO,CAAC;AAAA,IAC3B,iBAAiB,MAAM;AAAA,IAAC;AAAA,IACxB,cAAc,MAAM;AAAA,IAAC;AAAA,IACrB,eAAe,MAAM;AAAA,IAAC;AAAA,IACtB,cAAc,MAAM;AAAA,IAAC;AAAA,IACrB,eAAe,MAAM;AAAA,IAAC;AAAA,IACtB,mBAAmB,MAAM;AAAA,IAAC;AAAA;AAAA,IAG1B,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,qBAAqB,MAAM;AAAA,IAAC;AAAA,IAC5B,cAAc,MAAM;AAAA,EACxB;AAEA,SAAO;AACX;;;AFxEO,SAAS,wBAAwB,UAA+B,CAAC,GAAG;AACzE,QAAM;AAAA,IACJ,MAAM;AAAA,IACN,oBAAoB;AAAA,IACpB,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,oBAAoB;AAAA,EACtB,IAAI;AAGJ,QAAM,MAAM,IAAI,MAAM,0DAA0D;AAAA,IAC9E;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,SAAO,SAAS,IAAI;AACpB,SAAO,WAAW,IAAI,OAAO;AAG7B,MAAI;AAEF,WAAO,YAAY,IAAI,OAAO;AAAA,EAChC,SAAS,GAAG;AAEV,QAAI;AACF,aAAO,eAAe,QAAQ,aAAa;AAAA,QACzC,OAAO,IAAI,OAAO;AAAA,QAClB,UAAU;AAAA,QACV,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,SAAS,IAAI;AACX,cAAQ,KAAK,8CAA8C;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO,WAAW,IAAI,OAAO;AAC7B,SAAO,cAAc,IAAI,OAAO;AAChC,SAAO,oBAAoB,IAAI,OAAO;AAGtC,SAAO,QAAQ,IAAI,OAAO;AAC1B,SAAO,cAAc,IAAI,OAAO;AAChC,SAAO,YAAY,IAAI,OAAO;AAC9B,SAAO,aAAa,IAAI,OAAO;AAC/B,SAAO,gBAAgB,IAAI,OAAO;AAClC,SAAO,aAAa,IAAI,OAAO;AAC/B,SAAO,aAAa,IAAI,OAAO;AAC/B,SAAO,aAAa,IAAI,OAAO;AAC/B,SAAO,UAAU,IAAI,OAAO;AAI5B,MAAI;AACA,WAAO,eAAe,IAAI,OAAO;AAAA,EACrC,SAAS,GAAG;AAAA,EAEZ;AAGA,MAAI,CAAC,OAAO,cAAc;AACxB,UAAM,UAAU,oBAAI,IAAoB;AACxC,WAAO,eAAe;AAAA,MACpB,SAAS,CAAC,QAAgB,QAAQ,IAAI,GAAG,KAAK;AAAA,MAC9C,SAAS,CAAC,KAAa,UAAkB,QAAQ,IAAI,KAAK,KAAK;AAAA,MAC/D,YAAY,CAAC,QAAgB,QAAQ,OAAO,GAAG;AAAA,MAC/C,OAAO,MAAM,QAAQ,MAAM;AAAA,MAC3B,KAAK,CAAC,UAAkB,MAAM,KAAK,QAAQ,KAAK,CAAC,EAAE,KAAK,KAAK;AAAA,MAC7D,IAAI,SAAS;AAAE,eAAO,QAAQ;AAAA,MAAM;AAAA,IACtC;AAAA,EACF;AAGA,QAAM,wBAAwB,SAAS,cAAc,KAAK,QAAQ;AAClE,WAAS,gBAAgB,SAAU,SAAiBC,UAAe;AACjE,QAAI,QAAQ,YAAY,MAAM,UAAU;AACtC,YAAM,aAAa,IAAI,OAAO,KAAK,GAAG;AAGtC,YAAM,YAAY,sBAAsB,UAAUA,QAAO;AAGzD,aAAO,eAAe,WAAW,SAAS;AAAA,QACxC,KAAK,MAAM,WAAW;AAAA,QACtB,KAAK,CAAC,UAAU;AAAE,qBAAW,QAAQ;AAAA,QAAO;AAAA,QAC5C,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAED,aAAO,eAAe,WAAW,UAAU;AAAA,QACzC,KAAK,MAAM,WAAW;AAAA,QACtB,KAAK,CAAC,UAAU;AAAE,qBAAW,SAAS;AAAA,QAAO;AAAA,QAC7C,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAGD,YAAM,qBAAqB,UAAU,WAAW,KAAK,SAAS;AAC9D,gBAAU,aAAa,SAAS,WAAmBA,UAAe;AAChE,YAAI,cAAc,MAAM;AACtB,iBAAO,WAAW,WAAW,MAAMA,QAAO;AAAA,QAC5C;AAEA,YAAI,gBAAgB,cAAc,UAAU;AACzC,iBAAO,wBAAwB,SAA8B;AAAA,QAChE;AAIA,YAAI,cAAc,WAAW,cAAc,UAAU;AACnD,iBAAO,mBAAmB,WAAWA,QAAO;AAAA,QAC9C;AACA,eAAO,WAAW,WAAW,WAAkBA,QAAO;AAAA,MACxD;AAGA,MAAC,UAAkB,eAAe;AAElC,aAAO;AAAA,IACT;AACA,WAAO,sBAAsB,SAASA,QAAO;AAAA,EAC/C;AAGA,MAAI,cAAc;AACd,UAAM,0BAA0B,OAAO,kBAAkB,UAAU;AACnE,WAAO,kBAAkB,UAAU,aAAa,SAC9C,WACAA,UACK;AACL,UAAI,cAAc,UAAU;AAC1B,eAAO,wBAAwB,IAAI;AAAA,MACrC;AACA,aAAO,wBAAwB,KAAK,MAAM,WAAWA,QAAO;AAAA,IAC9D;AAAA,EACJ;AAGA,SAAO,QAAQ;AAGf,SAAO,YAAY;AAGnB,MAAI,OAAO,OAAO,sBAAsB,aAAa;AACnD,WAAO,oBAAoB,eACzB,OACA,UACc;AAEd,UAAI,SAAS,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,WAAW,UAAU;AAEhF,cAAMC,UAAS,IAAI,OAAO,MAAM,OAAO,MAAM,MAAM;AACnD,cAAM,MAAMA,QAAO,WAAW,IAAI;AAElC,YAAI,MAAM,MAAM;AACb,cAAI,aAAa,OAAc,GAAG,CAAC;AAAA,QACtC;AACA,eAAOA;AAAA,MACT;AAEA,YAAM,SAAS,IAAI,OAAO,KAAK,GAAG;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,OAAO,OAAO,SAAS,aAAa;AACtC,WAAO,OAAO,SAAU,KAAqB;AAC3C,aAAO,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,QAAQ;AAAA,IACrD;AAAA,EACF;AAEA,MAAI,OAAO,OAAO,SAAS,aAAa;AACtC,WAAO,OAAO,SAAU,KAAqB;AAC3C,aAAO,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,QAAQ;AAAA,IACrD;AAAA,EACF;AAGA,MAAI,mBAAmB;AACnB,oBAAgB,MAAM,OAAO,QAAQ;AAAA,EACzC;AAIA,MAAI,OAAO,OAAO,0BAA0B,aAAa;AACrD,QAAI,WAAW;AACf,WAAO,wBAAwB,CAAC,aAAmC;AACjE,YAAM,WAAW,KAAK,IAAI;AAC1B,YAAM,aAAa,KAAK,IAAI,GAAG,MAAM,WAAW,SAAS;AACzD,YAAM,KAAK,WAAW,MAAM;AACxB,iBAAS,WAAW,UAAU;AAAA,MAClC,GAAG,UAAU;AACb,iBAAW,WAAW;AACtB,aAAO;AAAA,IACT;AAEA,WAAO,uBAAuB,CAAC,OAAe;AAC5C,mBAAa,EAAE;AAAA,IACjB;AAAA,EACJ;AACF;AAKO,SAAS,6BAA6B;AAO3C,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAGd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAEd,SAAO,OAAO;AAIhB;;;AGlRA,SAAS,UAAAC,SAAQ,SAAAC,QAAO,aAAAC,kBAAiB;AAWlC,SAAS,iBAAiB,QAAgB,KAAK,SAAiB,KAAwB;AAE3F,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe;AAC3D,UAAMC,UAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,QAAO,QAAQ;AACf,IAAAA,QAAO,SAAS;AAChB,WAAOA;AAAA,EACX;AAGA,QAAM,SAAS,IAAIC,QAAO,OAAO,MAAM;AAGvC,QAAM,qBAAqB,OAAO,WAAW,KAAK,MAAM;AACxD,SAAO,aAAa,SAAS,WAAmB,SAAe;AAC3D,QAAI,cAAc,UAAU;AACxB,aAAO,wBAAwB,MAAsC;AAAA,IACzE;AACA,QAAI,cAAc,MAAM;AACnB,aAAO,mBAAmB,MAAM,OAAO;AAAA,IAC5C;AACA,WAAO,mBAAmB,WAAkB,OAAO;AAAA,EACvD;AAEA,SAAO;AACX;AAKO,SAAS,0BAA0B,QAAsD;AAC5F,MAAI,CAAC,QAAQ;AACT,aAAS,iBAAiB;AAAA,EAC9B;AACA,SAAO,OAAO,WAAW,IAAI;AACjC;AAMO,SAAS,uBAAuB,SAA+C;AAClF,QAAM,YAAwB,CAAC;AAC/B,QAAM,eAAe;AAAA,IACjB;AAAA,IAAY;AAAA,IAAc;AAAA,IAC1B;AAAA,IAAY;AAAA,IACZ;AAAA,IACA;AAAA,IAAa;AAAA,IAAa;AAAA,IAAU;AAAA,IAAU;AAAA,IAAO;AAAA,IAAS;AAAA,IAAiB;AAAA,IAC/E;AAAA,IAAU;AAAA,IACV;AAAA,EACJ;AAEA,eAAa,QAAQ,YAAU;AAE3B,UAAM,WAAW,QAAQ,MAAM;AAC/B,QAAI,OAAO,aAAa,YAAY;AAE/B,cAAQ,MAAM,IAAI,YAAY,MAAa;AACvC,kBAAU,KAAK,EAAE,QAAQ,KAAK,CAAC;AAC/B,eAAO,SAAS,MAAM,MAAM,IAAI;AAAA,MACpC;AAAA,IACL;AAAA,EACJ,CAAC;AAED,SAAO;AACX;AAKO,SAAS,oBAAoB,OAAe,QAAgB,WAAyD;AACxH,QAAM,YAAY,IAAIC,WAAU,OAAO,MAAM;AAC7C,MAAI,WAAW;AACX,UAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI;AACrB,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK,QAAQ,KAAK,GAAG;AAC/C,gBAAU,KAAK,CAAC,IAAI;AACpB,gBAAU,KAAK,IAAI,CAAC,IAAI;AACxB,gBAAU,KAAK,IAAI,CAAC,IAAI;AACxB,gBAAU,KAAK,IAAI,CAAC,IAAI;AAAA,IAC5B;AAAA,EACJ;AACA,SAAO;AACX;AAKO,SAAS,gBAAgB,OAAgB,QAAiB,KAAgC;AAC7F,QAAM,MAAM,IAAIC,OAAM;AACtB,MAAI,MAAO,KAAI,QAAQ;AACvB,MAAI,OAAQ,KAAI,SAAS;AACzB,MAAI,IAAK,KAAI,MAAM;AACnB,SAAO;AACX;;;AChGO,SAAS,qBAAqB,UAA4B,CAAC,GAAG;AAKnE,MAAI,QAAQ,iBAAiB,OAAO,OAAO,UAAU,aAAa;AAAA,EAGlE;AACF;;;AChBA,OAAO;AAKA,SAAS,uBAAuB,cAAsC,CAAC,GAAY;AACtF,QAAM,UAAU,IAAI,IAAoB,OAAO,QAAQ,WAAW,CAAC;AAEnE,SAAO;AAAA,IACH,SAAS,CAAC,QAAgB,QAAQ,IAAI,GAAG,KAAK;AAAA,IAC9C,SAAS,CAAC,KAAa,UAAkB,QAAQ,IAAI,KAAK,KAAK;AAAA,IAC/D,YAAY,CAAC,QAAgB,QAAQ,OAAO,GAAG;AAAA,IAC/C,OAAO,MAAM,QAAQ,MAAM;AAAA,IAC3B,KAAK,CAAC,UAAkB,MAAM,KAAK,QAAQ,KAAK,CAAC,EAAE,KAAK,KAAK;AAAA,IAC7D,IAAI,SAAS;AAAE,aAAO,QAAQ;AAAA,IAAM;AAAA,EACxC;AACJ;AAMO,SAAS,yBAAyB,cAAsC,CAAC,GAAY;AACxF,SAAO,uBAAuB,WAAW;AAC7C;AAOO,SAAS,sBAAkC;AAC9C,MAAI,OAAO,cAAc,aAAa;AAClC,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAChF;AAGA,SAAO;AACX;AAWO,SAAS,0BAA0B,cAA+C,SAA0B;AAC/G,MAAI,gBAAgB,WAAW;AAC3B,UAAM,SAAS,WAAW,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC;AACjE,UAAM,YAAY;AAClB,UAAMC,WAAU,oBAAoB;AAEpC,WAAO;AAAA,MACH,SAAAA;AAAA,MACA,UAAU,OAAO,SAA8B;AAC3C,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,gBAAM,MAAMA,SAAQ,KAAK,QAAQ,CAAC;AAClC,cAAI,kBAAkB,CAAC,MAAW;AAC9B,kBAAM,KAAK,EAAE,OAAO;AACpB,eAAG,kBAAkB,SAAS;AAAA,UAClC;AACA,cAAI,YAAY,CAAC,MAAW;AACxB,kBAAM,KAAK,EAAE,OAAO;AACpB,kBAAM,KAAK,GAAG,YAAY,WAAW,WAAW;AAChD,kBAAM,QAAQ,GAAG,YAAY,SAAS;AACtC,mBAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC;AACxD,eAAG,aAAa,MAAM;AAClB,iBAAG,MAAM;AACT,sBAAQ;AAAA,YACZ;AACA,eAAG,UAAU,MAAM,OAAO,GAAG,KAAK;AAAA,UACtC;AACA,cAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,QACxC,CAAC;AAAA,MACL;AAAA,MACA,QAAQ,OAAO,KAAa,UAAe;AACvC,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,gBAAM,MAAMA,SAAQ,KAAK,QAAQ,CAAC;AAClC,cAAI,YAAY,CAAC,MAAW;AACxB,kBAAM,KAAK,EAAE,OAAO;AACpB,gBAAI,CAAC,GAAG,iBAAiB,SAAS,SAAS,GAAG;AAC1C,iBAAG,MAAM;AACT,sBAAQ,KAAK;AACb;AAAA,YACJ;AACA,kBAAM,KAAK,GAAG,YAAY,WAAW,UAAU;AAC/C,kBAAM,QAAQ,GAAG,YAAY,SAAS;AACtC,kBAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,mBAAO,YAAY,MAAM;AACrB,oBAAM,SAAS,OAAO,WAAW;AACjC,iBAAG,MAAM;AACT,sBAAQ,MAAM;AAAA,YAClB;AACA,mBAAO,UAAU,MAAM;AACnB,iBAAG,MAAM;AACT,sBAAQ,KAAK;AAAA,YACjB;AAAA,UACJ;AACA,cAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,QACxC,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,UAAU,gBAAgB,UAAU,uBAAuB,IAAI,yBAAyB;AAE9F,SAAO;AAAA,IACH;AAAA,IACA,SAAS,MAAM;AACX,aAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,QAAQ,QAAQ,GAAG,CAAC,CAAC;AAAA,IAClE;AAAA,IACA,OAAO,KAAK,OAAO;AACf,aAAO,QAAQ,QAAQ,GAAG,MAAM;AAAA,IACpC;AAAA,EACJ;AACJ;;;ACrHO,SAAS,yBAAuC;AACnD,QAAM,UAAU;AAAA,IACZ,YAAY,OAAO;AAAA,MACf,SAAS,MAAM;AAAA,MAAC;AAAA,MAChB,MAAM,EAAE,OAAO,GAAG,gBAAgB,MAAM;AAAA,MAAC,EAAE;AAAA,IAC/C;AAAA,IACA,kBAAkB,OAAO;AAAA,MACrB,SAAS,MAAM;AAAA,MAAC;AAAA,MAChB,OAAO,MAAM;AAAA,MAAC;AAAA,MACd,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,WAAW,EAAE,OAAO,IAAI;AAAA,IAC5B;AAAA,IACA,oBAAoB,OAAO;AAAA,MACvB,SAAS,MAAM;AAAA,MAAC;AAAA,MAChB,OAAO,MAAM;AAAA,MAAC;AAAA,MACd,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,QAAQ;AAAA,MACR,cAAc,EAAE,OAAO,EAAE;AAAA,MACzB,MAAM;AAAA,IACV;AAAA,IACA,aAAa,CAAC;AAAA,IACd,aAAa;AAAA,IACb,OAAO;AAAA,IACP,QAAQ,YAAY;AAAA,IAAC;AAAA,IACrB,SAAS,YAAY;AAAA,IAAC;AAAA,IACtB,OAAO,YAAY;AAAA,IAAC;AAAA,IACpB,iBAAiB,OAAO,YAAyB;AAAA,MAC7C,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,gBAAgB,MAAM,IAAI,aAAa,KAAK;AAAA,IAChD;AAAA,IACA,cAAc,CAAC,UAAkB,QAAgB,gBAAwB;AAAA,MACrE,UAAU,SAAS;AAAA,MACnB;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,MAClB,gBAAgB,MAAM,IAAI,aAAa,MAAM;AAAA,IACjD;AAAA;AAAA,IAEA,SAAS,CAAC;AAAA,EACd;AAGA,SAAO,IAAI,MAAM,SAAoC;AAAA,IACjD,IAAI,QAAQ,MAAM,UAAU;AACvB,UAAI,SAAS,UAAW,QAAQ,OAAe;AAC/C,YAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAChD,UAAI,OAAO,UAAU,YAAY;AAC7B,eAAO,IAAI,SAAgB;AACvB,UAAC,OAAe,QAAQ,KAAK,EAAE,MAAM,OAAO,IAAI,GAAG,KAAK,CAAC;AACzD,iBAAO,QAAQ,MAAM,OAAO,QAAQ,IAAI;AAAA,QAC5C;AAAA,MACJ;AACA,aAAO;AAAA,IACZ;AAAA,EACJ,CAAC;AACL;AAKO,SAAS,wBAAwB;AACpC,MAAI,OAAO,OAAO,iBAAiB,eAAe,OAAO,OAAO,WAAW,aAAa;AAEpF,WAAO,eAAe,MAAM;AAAA,MACxB,cAAc;AACV,eAAO,uBAAuB;AAAA,MAClC;AAAA,IACJ;AAEA,WAAO,OAAO,eAAe,OAAO;AAEpC,WAAO,OAAO,qBAAqB,OAAO;AAAA,EAC9C;AACJ;AAKO,SAAS,2BAA2B;AAIvC,MAAI,OAAO,gBAAgB,OAAO,aAAa,SAAS,EAAE,SAAS,OAAO,GAAG;AAEzE,WAAO,OAAO;AAEd,WAAO,OAAO,OAAO;AAErB,WAAO,OAAO,OAAO;AAAA,EACzB;AACJ;AAWO,SAAS,mBAAmB,SAAqC;AACpE,SAAQ,QAAgB,WAAW,CAAC;AACxC;;;AClGA,IAAI;AAMG,SAAS,gBAAyB;AACvC,MAAI,YAA8D,CAAC;AACnE,MAAI,SAAS;AACb,MAAI,cAAc;AAElB,QAAM,cAAc,OAAO;AAC3B,QAAM,oBAAoB,OAAO;AAEjC,QAAM,MAAM,CAAC,aAA2C;AACtD,UAAM,KAAK;AACX,cAAU,KAAK,EAAE,IAAI,SAAS,CAAC;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,CAAC,OAAqB;AACnC,gBAAY,UAAU,OAAO,QAAM,GAAG,OAAO,EAAE;AAAA,EACjD;AAEA,QAAM,OAAgB;AAAA,IACpB,KAAK,WAAoB;AACvB,UAAI,OAAO,cAAc,UAAU;AACjC,uBAAe;AAAA,MACjB,OAAO;AACL,sBAAc;AAAA,MAChB;AAEA,YAAM,mBAAmB,CAAC,GAAG,SAAS;AACtC,kBAAY,CAAC;AAEb,uBAAiB,QAAQ,CAAC,EAAE,SAAS,MAAM;AACzC,iBAAS,WAAW;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,IAEA,QAAQ,UAAkB,MAAM;AAC9B,WAAK,KAAK,cAAc,OAAO;AAAA,IACjC;AAAA,IAEA,eAAe;AACb,aAAO,UAAU,IAAI,OAAK,EAAE,QAAQ;AAAA,IACtC;AAAA,IAEA,QAAQ;AACN,kBAAY,CAAC;AACb,eAAS;AACT,oBAAc;AAAA,IAChB;AAAA,IAEA,SAAS;AACL,sBAAgB;AAChB,aAAO,wBAAwB;AAC/B,aAAO,uBAAuB;AAAA,IAClC;AAAA,IAEA,UAAU;AACN,UAAI,kBAAkB,MAAM;AACxB,wBAAgB;AAAA,MACpB;AAEA,UAAI,aAAa;AACb,eAAO,wBAAwB;AAAA,MACnC,OAAO;AAEH,eAAO,OAAO;AAAA,MAClB;AAEA,UAAI,mBAAmB;AACnB,eAAO,uBAAuB;AAAA,MAClC,OAAO;AAEH,eAAO,OAAO;AAAA,MAClB;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,sBAAsB,YAAoB,GAAgB;AACxE,MAAI,cAAc;AAElB,QAAM,WAAW;AAAA,IACf,KAAK,MAAM;AAAA,IACX,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,iBAAiB;AAAA,IACnB;AAAA,IACA,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,eAAe,MAAM;AAAA,IAAC;AAAA,IACtB,sBAAsB,MAAM;AAAA,IAAC;AAAA,IAC7B,YAAY,MAAM,CAAC;AAAA,IACnB,kBAAkB,MAAM,CAAC;AAAA,IACzB,kBAAkB,MAAM,CAAC;AAAA,IACzB,MAAM,MAAM;AAAA,IAAC;AAAA,IACb,SAAS,MAAM;AAAA,IAAC;AAAA,IAChB,6BAA6B,MAAM;AAAA,IAAC;AAAA,IACpC,QAAQ,OAAO,CAAC;AAAA,IAChB,kBAAkB,MAAM;AAAA,IAAC;AAAA,IACzB,qBAAqB,MAAM;AAAA,IAAC;AAAA,IAC5B,eAAe,MAAM;AAAA,EACvB;AAEA,EAAC,SAAiB,UAAU,CAAC,YAAoB;AAC/C,mBAAe;AAAA,EACjB;AACA,EAAC,SAAiB,UAAU,CAAC,SAAiB;AAC5C,kBAAc;AAAA,EAChB;AAEA,SAAO;AACT;AAaO,SAAS,wBAAyC;AACrD,MAAI,cAAc;AAQlB,MAAI,SAAkB,CAAC;AACvB,MAAI,SAAS;AAEb,QAAM,qBAAqB,OAAO;AAClC,QAAM,uBAAuB,OAAO;AACpC,QAAM,sBAAsB,OAAO;AACnC,QAAM,wBAAwB,OAAO;AAErC,QAAM,iBAAiB,CAAC,UAAoB,QAAgB,MAAM,SAAgB;AAC9E,UAAM,KAAK;AACX,WAAO,KAAK,EAAE,IAAI,UAAU,SAAS,cAAc,OAAO,KAAK,CAAC;AAChE,WAAO;AAAA,EACX;AAEA,QAAM,mBAAmB,CAAC,OAAY;AAClC,aAAS,OAAO,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,EAC3C;AAEA,QAAM,kBAAkB,CAAC,UAAoB,QAAgB,MAAM,SAAgB;AAC/E,UAAM,KAAK;AACX,WAAO,KAAK,EAAE,IAAI,UAAU,SAAS,cAAc,OAAO,UAAU,OAAO,KAAK,CAAC;AACjF,WAAO;AAAA,EACX;AAEA,QAAM,oBAAoB,CAAC,OAAY;AACnC,aAAS,OAAO,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,EAC3C;AAEA,SAAO,aAAa;AACpB,SAAO,eAAe;AACtB,SAAO,cAAc;AACrB,SAAO,gBAAgB;AAEvB,SAAO;AAAA,IACH,OAAO;AACH,WAAK,UAAU,CAAC;AAAA,IACpB;AAAA,IACA,UAAU,IAAY;AAClB,YAAM,aAAa,cAAc;AAGjC,aAAO,MAAM;AAET,YAAI,WAAyB;AAC7B,mBAAW,KAAK,QAAQ;AACpB,cAAI,CAAC,YAAY,EAAE,UAAU,SAAS,SAAS;AAC3C,uBAAW;AAAA,UACf;AAAA,QACJ;AAEA,YAAI,CAAC,YAAY,SAAS,UAAU,YAAY;AAC5C;AAAA,QACJ;AAGA,sBAAc,SAAS;AAGvB,cAAM,EAAE,UAAU,MAAM,UAAU,GAAG,IAAI;AAEzC,YAAI,aAAa,QAAW;AACxB,mBAAS,WAAW;AAEpB,cAAI,aAAa,EAAG,UAAS,WAAW;AAAA,QAC5C,OAAO;AACH,mBAAS,OAAO,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,QAC3C;AAEA,iBAAS,GAAG,IAAI;AAAA,MACpB;AAEA,oBAAc;AAAA,IAClB;AAAA,IACA,QAAQ;AACJ,eAAS,CAAC;AAAA,IACd;AAAA,IACA,UAAU;AACN,aAAO,aAAa;AACpB,aAAO,eAAe;AACtB,aAAO,cAAc;AACrB,aAAO,gBAAgB;AAAA,IAC3B;AAAA,EACJ;AACJ;AAQO,SAAS,eAAe,OAAe,cAAsB,MAAM,UAAyC;AAC/G,MAAI,CAAC,eAAe;AAChB,UAAM,IAAI,MAAM,uFAAuF;AAAA,EAC3G;AAEA,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,QAAI,SAAU,UAAS,CAAC;AACxB,kBAAc,QAAQ,WAAW;AAAA,EACrC;AACJ;AAKO,SAAS,uBAAuB,MAAe,OAAe,cAAsB,MAAM,UAAyC;AACtI,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,QAAI,SAAU,UAAS,CAAC;AACxB,SAAK,QAAQ,WAAW;AAAA,EAC5B;AACJ;;;ACpQA,SAAS,gBAAqF;AAC9F,SAAS,oBAA6D;AACtE,OAAO,aAAa;AAgCpB,eAAsB,2BAA2B,UAA6B,CAAC,GAAkC;AAC/G,MAAI;AACJ,MAAI,YAAY,QAAQ;AACxB,QAAM,WAAW,QAAQ,YAAY,QAAQ,IAAI;AAEjD,MAAI,CAAC,WAAW;AAEd,mBAAe,aAAa,CAAC,SAA0B,aAA6B;AAClF,aAAO,QAAQ,SAAS,UAAU;AAAA,QAChC,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,SAAS;AAAA,UACP;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,EAAE,KAAK,iBAAiB,OAAO,WAAW;AAAA,cAC1C,EAAE,KAAK,+BAA+B,OAAO,IAAI;AAAA,cACjD,EAAE,KAAK,8BAA8B,OAAO,cAAc;AAAA,cAC1D,EAAE,KAAK,gCAAgC,OAAO,eAAe;AAAA,YAC/D;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,UAAM,IAAI,QAAc,CAAC,YAAY;AACjC,UAAI,CAAC,aAAc;AACnB,mBAAa,OAAO,GAAG,MAAM;AACzB,cAAM,OAAO,cAAc,QAAQ;AACnC,cAAM,OAAO,OAAO,SAAS,WAAW,MAAM,OAAO;AACrD,oBAAY,oBAAoB,IAAI;AACpC,gBAAQ,IAAI,4BAA4B,QAAQ,OAAO,SAAS,EAAE;AAClE,gBAAQ;AAAA,MACZ,CAAC;AAAA,IACL,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,MAAM,SAAS,OAAO;AAAA,IACpC,UAAU,QAAQ,YAAY;AAAA,IAC9B,MAAM;AAAA,MACF;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,eAAe,QAAQ,CAAC;AAAA,IACxC;AAAA,IACA,GAAG,QAAQ;AAAA,EACb,CAAC;AAED,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,QAAQ,UAAU;AAEjC,QAAM,UAAU,MAAM,QAAQ,WAAW;AAAA,IACrC,UAAU,EAAE,OAAO,OAAO;AAAA,IAC1B,mBAAmB;AAAA,IACnB,GAAG,QAAQ;AAAA,EACf,CAAC;AAED,QAAM,OAAO,MAAM,QAAQ,QAAQ;AAGnC,QAAM,QAAQ,YAAY;AACxB,UAAM,QAAQ,MAAM;AACpB,QAAI,cAAc;AACd,mBAAa,MAAM;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,WAAW,OAAO,QAAiB;AACrC,UAAM,YAAY,OAAO;AACzB,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,uBAAuB;AAEvD,QAAI,WAAW;AACf,QAAI,QAAQ,aAAa,CAAC,UAAU,SAAS,UAAU,GAAG;AACtD,YAAM,YAAY,UAAU,SAAS,GAAG,IAAI,MAAM;AAClD,iBAAW,GAAG,SAAS,GAAG,SAAS,WAAW,mBAAmB,QAAQ,SAAS,CAAC;AAAA,IACvF;AAEA,YAAQ,IAAI,kBAAkB,QAAQ,EAAE;AACxC,UAAM,KAAK,KAAK,UAAU,EAAE,WAAW,mBAAmB,CAAC;AAAA,EAC/D;AAEA,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,aAAa,OAAO,UAAU,QAAU;AACpC,YAAM,iBAAiB,MAAM,OAAO;AAAA,IACxC;AAAA,IACA,aAAa,OAAO,MAAM,SAAS;AAE/B,YAAM,KAAK,SAAS,CAAC,EAAC,MAAAC,OAAM,MAAAC,MAAI,MAAM;AAEnC,YAAI,OAAO,gBAAiB,QAAO,gBAAgBD,OAAMC,KAAI;AAAA,MAChE,GAAG,EAAC,MAAM,KAAI,CAAC;AAAA,IACnB;AAAA,EACJ;AACF;AAEA,eAAsB,iBAAiB,MAAY,UAAkB,KAAsB;AACvF,MAAI;AACA,UAAM,KAAK,gBAAgB,MAAM;AAE7B,aAAO,OAAO,gBAAgB,OAAO,aAAa;AAAA,IACtD,GAAG,MAAM,EAAE,QAAQ,CAAC;AAAA,EACxB,SAAS,GAAG;AACR,UAAM,KAAK,gBAAgB,UAAU,EAAE,QAAQ,CAAC;AAAA,EACpD;AACJ;AAMA,eAAsB,iBAAiB,MAAuC;AAC1E,SAAO,MAAM,KAAK,SAAS,MAAM;AAE7B,QAAI,OAAO,gBAAgB,OAAO,aAAa,UAAU;AAErD,aAAO,OAAO,aAAa,SAAS;AAAA,IACxC;AACA,WAAO,CAAC;AAAA,EACZ,CAAC;AACL;;;AChJA,IAAM,aAAsD;AAAA,EACxD,QAAQ;AAAA,IACJ,SAAS;AAAA,IACT,oBAAoB,KAAK,OAAO;AAAA;AAAA,IAChC,kBAAkB,IAAI,OAAO;AAAA;AAAA,IAC7B,SAAS;AAAA,EACb;AAAA,EACA,QAAQ;AAAA,IACJ,SAAS;AAAA,IACT,oBAAoB,MAAM;AAAA;AAAA,IAC1B,kBAAkB,MAAM;AAAA,IACxB,SAAS;AAAA,EACb;AAAA,EACA,YAAY;AAAA,IACR,SAAS;AAAA,IACT,oBAAoB,IAAI,OAAO;AAAA,IAC/B,kBAAkB,IAAI,OAAO;AAAA,IAC7B,SAAS;AAAA,EACb;AAAA,EACA,WAAW;AAAA,IACP,SAAS;AAAA,IACT,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,SAAS;AAAA,EACb;AACJ;AAKO,SAAS,yBAAyB,WAA+C;AACpF,QAAM,SAAS,WAAW,SAAS;AACnC,SAAO,6BAA6B,OAAO,SAAS,GAAG,GAAG,MAAM;AACpE;AASO,SAAS,6BACZ,SACA,SAAiB,GACjB,aAAqB,GACrB,YACgB;AAChB,SAAO;AAAA,IACH,MAAM,MAAM,MAAW;AACnB,YAAM,SAAS,MAAM,KAAK,QAAQ,EAAE,cAAc,IAAI;AACtD,YAAM,OAAO,KAAK,gBAAgB;AAClC,YAAM,OAAO,KAAK,oCAAoC;AAAA,QAClD,SAAS,YAAY,WAAW;AAAA,QAChC,SAAS,UAAW,KAAK,OAAO,IAAI;AAAA,QACpC,oBAAoB,YAAY,sBAAsB;AAAA,QACtD,kBAAkB,YAAY,oBAAoB;AAAA,MACtD,CAAC;AAAA,IACL;AAAA,IACA,MAAM,MAAM,MAAW;AACnB,YAAM,SAAS,MAAM,KAAK,QAAQ,EAAE,cAAc,IAAI;AACtD,YAAM,OAAO,KAAK,oCAAoC;AAAA,QAClD,SAAS;AAAA,QACT,SAAS;AAAA,QACT,oBAAoB;AAAA,QACpB,kBAAkB;AAAA,MACtB,CAAC;AAAA,IACL;AAAA,EACJ;AACJ;AAKA,eAAsB,kBAAkB,MAAW,gBAAwB;AACvE,QAAM,YAAY,6BAA6B,GAAG,GAAG,GAAG;AAAA,IACpD,SAAS;AAAA,IACT,SAAS;AAAA,IACT,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,EACtB,CAAC;AACD,QAAM,UAAU,MAAM,IAAI;AAC9B;;;AC/FA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAWf,eAAsB,sBAAsB,MAAY,MAAc,UAAgD,CAAC,GAAoB;AACvI,QAAM,MAAM,QAAQ,OAAO;AAC3B,QAAM,iBAAiB,KAAK,KAAK,KAAK,GAAG,IAAI,MAAM;AAGnD,QAAM,GAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAEvC,SAAO,MAAM,KAAK,WAAW;AAAA,IACzB,MAAM;AAAA,IACN,UAAU,QAAQ,YAAY;AAAA,IAC9B,YAAY;AAAA,IACZ,OAAO;AAAA,EACX,CAAC;AACL;AAOA,eAAsB,mBAAmB,UAAkB,SAAiB,YAAoB,KAA0B;AACtH,MAAI,SAAS,OAAO,OAAO,GAAG;AAC1B,WAAO,EAAE,WAAW,GAAG,SAAS,KAAK;AAAA,EACzC;AAEA,SAAO;AAAA,IACH,WAAW;AAAA;AAAA,IACX,SAAS;AAAA,EACb;AACJ;AAUO,SAAS,yBAAyB,MAAY,WAAmC;AACpF,SAAO;AAAA,IACH,MAAM,QAAQ,cAAsB;AAChC,aAAO,MAAM,sBAAsB,MAAM,GAAG,SAAS,IAAI,YAAY,EAAE;AAAA,IAC3E;AAAA,IACA,MAAM,QAAQ,cAAsB,aAAqB;AACrD,YAAM,OAAO,GAAG,SAAS,IAAI,YAAY;AACzC,YAAM,UAAU,MAAM,sBAAsB,MAAM,MAAM,EAAE,KAAK,0BAA0B,CAAC;AAE1F,UAAI;AACA,cAAM,eAAe,KAAK,KAAK,aAAa,GAAG,IAAI,MAAM;AACzD,cAAM,WAAW,MAAM,GAAG,SAAS,YAAY;AAC/C,eAAO,MAAM,mBAAmB,UAAU,OAAO;AAAA,MACrD,SAAS,GAAG;AACR,eAAO,EAAE,WAAW,IAAI,SAAS,MAAM;AAAA,MAC3C;AAAA,IACJ;AAAA,EACJ;AACJ;","names":["vi","vi","vi","options","canvas","Canvas","Image","ImageData","canvas","Canvas","ImageData","Image","storage","type","data"]}
1
+ {"version":3,"sources":["../src/shared/mocks.ts","../src/shared/bsp.ts","../src/game/factories.ts","../src/game/helpers.ts","../src/game/mocks.ts","../src/server/mocks/transport.ts","../src/server/mocks/state.ts","../src/server/mocks/connection.ts","../src/server/helpers/multiplayer.ts","../src/server/helpers/snapshot.ts","../src/setup/browser.ts","../src/e2e/input.ts","../src/setup/webgl.ts","../src/setup/canvas.ts","../src/setup/node.ts","../src/setup/storage.ts","../src/setup/audio.ts","../src/setup/timing.ts","../src/e2e/playwright.ts","../src/e2e/network.ts","../src/e2e/visual.ts"],"sourcesContent":["import { vi, type Mock } from 'vitest';\n\nexport interface BinaryWriterMock {\n writeByte: Mock<[number], void>;\n writeShort: Mock<[number], void>;\n writeLong: Mock<[number], void>;\n writeString: Mock<[string], void>;\n writeBytes: Mock<[Uint8Array], void>;\n getBuffer: Mock<[], Uint8Array>;\n reset: Mock<[], void>;\n writeInt8: Mock<[number], void>;\n writeUint8: Mock<[number], void>;\n writeInt16: Mock<[number], void>;\n writeUint16: Mock<[number], void>;\n writeInt32: Mock<[number], void>;\n writeUint32: Mock<[number], void>;\n writeFloat: Mock<[number], void>;\n getData: Mock<[], Uint8Array>;\n}\n\nexport const createBinaryWriterMock = (): BinaryWriterMock => ({\n writeByte: vi.fn(),\n writeShort: vi.fn(),\n writeLong: vi.fn(),\n writeString: vi.fn(),\n writeBytes: vi.fn(),\n getBuffer: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n reset: vi.fn(),\n // Legacy methods (if any)\n writeInt8: vi.fn(),\n writeUint8: vi.fn(),\n writeInt16: vi.fn(),\n writeUint16: vi.fn(),\n writeInt32: vi.fn(),\n writeUint32: vi.fn(),\n writeFloat: vi.fn(),\n getData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n});\n\nexport const createNetChanMock = () => ({\n qport: 1234,\n\n // Sequencing\n incomingSequence: 0,\n outgoingSequence: 0,\n incomingAcknowledged: 0,\n\n // Reliable messaging\n incomingReliableAcknowledged: false,\n incomingReliableSequence: 0,\n outgoingReliableSequence: 0,\n reliableMessage: createBinaryWriterMock(),\n reliableLength: 0,\n\n // Fragmentation\n fragmentSendOffset: 0,\n fragmentBuffer: null,\n fragmentLength: 0,\n fragmentReceived: 0,\n\n // Timing\n lastReceived: 0,\n lastSent: 0,\n\n remoteAddress: { type: 'IP', port: 1234 },\n\n // Methods\n setup: vi.fn(),\n reset: vi.fn(),\n transmit: vi.fn(),\n process: vi.fn(),\n canSendReliable: vi.fn(() => true),\n writeReliableByte: vi.fn(),\n writeReliableShort: vi.fn(),\n writeReliableLong: vi.fn(),\n writeReliableString: vi.fn(),\n getReliableData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n needsKeepalive: vi.fn(() => false),\n isTimedOut: vi.fn(() => false),\n});\n\nexport interface BinaryStreamMock {\n getPosition: Mock<[], number>;\n getReadPosition: Mock<[], number>;\n getLength: Mock<[], number>;\n getRemaining: Mock<[], number>;\n seek: Mock<[number], void>;\n setReadPosition: Mock<[number], void>;\n hasMore: Mock<[], boolean>;\n hasBytes: Mock<[number], boolean>;\n\n readChar: Mock<[], number>;\n readByte: Mock<[], number>;\n readShort: Mock<[], number>;\n readUShort: Mock<[], number>;\n readLong: Mock<[], number>;\n readULong: Mock<[], number>;\n readFloat: Mock<[], number>;\n\n readString: Mock<[], string>;\n readStringLine: Mock<[], string>;\n\n readCoord: Mock<[], number>;\n readAngle: Mock<[], number>;\n readAngle16: Mock<[], number>;\n\n readData: Mock<[number], Uint8Array>;\n\n readPos: Mock<[], any>; // Use proper type if available, e.g., Vec3\n readDir: Mock<[], any>;\n}\n\nexport const createBinaryStreamMock = (): BinaryStreamMock => ({\n getPosition: vi.fn(() => 0),\n getReadPosition: vi.fn(() => 0),\n getLength: vi.fn(() => 0),\n getRemaining: vi.fn(() => 0),\n seek: vi.fn(),\n setReadPosition: vi.fn(),\n hasMore: vi.fn(() => true),\n hasBytes: vi.fn((amount: number) => true),\n\n readChar: vi.fn(() => 0),\n readByte: vi.fn(() => 0),\n readShort: vi.fn(() => 0),\n readUShort: vi.fn(() => 0),\n readLong: vi.fn(() => 0),\n readULong: vi.fn(() => 0),\n readFloat: vi.fn(() => 0),\n\n readString: vi.fn(() => ''),\n readStringLine: vi.fn(() => ''),\n\n readCoord: vi.fn(() => 0),\n readAngle: vi.fn(() => 0),\n readAngle16: vi.fn(() => 0),\n\n readData: vi.fn<[number], Uint8Array>((length: number) => new Uint8Array(length)),\n\n readPos: vi.fn(),\n readDir: vi.fn(),\n});\n","import {\n computePlaneSignBits,\n type CollisionBrush,\n type CollisionModel,\n type CollisionPlane,\n type CollisionNode,\n type CollisionLeaf,\n CONTENTS_SOLID,\n type Vec3\n} from '@quake2ts/shared';\n\nexport function makePlane(normal: Vec3, dist: number): CollisionPlane {\n return {\n normal,\n dist,\n type: Math.abs(normal.x) === 1 ? 0 : Math.abs(normal.y) === 1 ? 1 : Math.abs(normal.z) === 1 ? 2 : 3,\n signbits: computePlaneSignBits(normal),\n };\n}\n\nexport function makeAxisBrush(size: number, contents = CONTENTS_SOLID): CollisionBrush {\n const half = size / 2;\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, half),\n makePlane({ x: -1, y: 0, z: 0 }, half),\n makePlane({ x: 0, y: 1, z: 0 }, half),\n makePlane({ x: 0, y: -1, z: 0 }, half),\n makePlane({ x: 0, y: 0, z: 1 }, half),\n makePlane({ x: 0, y: 0, z: -1 }, half),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n\nexport function makeNode(plane: CollisionPlane, children: [number, number]): CollisionNode {\n return { plane, children };\n}\n\nexport function makeBspModel(\n planes: CollisionPlane[],\n nodes: CollisionNode[],\n leaves: CollisionLeaf[],\n brushes: CollisionBrush[],\n leafBrushes: number[]\n): CollisionModel {\n return {\n planes,\n nodes,\n leaves,\n brushes,\n leafBrushes,\n bmodels: [],\n };\n}\n\nexport function makeLeaf(contents: number, firstLeafBrush: number, numLeafBrushes: number): CollisionLeaf {\n return { contents, cluster: 0, area: 0, firstLeafBrush, numLeafBrushes };\n}\n\nexport function makeLeafModel(brushes: CollisionBrush[]): CollisionModel {\n const planes = brushes.flatMap((brush) => brush.sides.map((side) => side.plane));\n\n return {\n planes,\n nodes: [],\n leaves: [makeLeaf(0, 0, brushes.length)],\n brushes,\n leafBrushes: brushes.map((_, i) => i),\n bmodels: [],\n };\n}\n\nexport function makeBrushFromMinsMaxs(mins: Vec3, maxs: Vec3, contents = CONTENTS_SOLID): CollisionBrush {\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, maxs.x),\n makePlane({ x: -1, y: 0, z: 0 }, -mins.x),\n makePlane({ x: 0, y: 1, z: 0 }, maxs.y),\n makePlane({ x: 0, y: -1, z: 0 }, -mins.y),\n makePlane({ x: 0, y: 0, z: 1 }, maxs.z),\n makePlane({ x: 0, y: 0, z: -1 }, -mins.z),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n","import type { PlayerState, EntityState } from '@quake2ts/shared';\nimport type { GameStateSnapshot } from '@quake2ts/game';\n\nexport const createPlayerStateFactory = (overrides?: Partial<PlayerState>): PlayerState => ({\n pm_type: 0,\n pm_time: 0,\n pm_flags: 0,\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewAngles: { x: 0, y: 0, z: 0 },\n onGround: false,\n waterLevel: 0,\n watertype: 0,\n mins: { x: 0, y: 0, z: 0 },\n maxs: { x: 0, y: 0, z: 0 },\n damageAlpha: 0,\n damageIndicators: [],\n blend: [0, 0, 0, 0],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n ...overrides,\n});\n\nexport const createEntityStateFactory = (overrides?: Partial<EntityState>): EntityState => ({\n number: 0,\n origin: { x: 0, y: 0, z: 0 },\n angles: { x: 0, y: 0, z: 0 },\n oldOrigin: { x: 0, y: 0, z: 0 },\n modelIndex: 0,\n modelIndex2: 0,\n modelIndex3: 0,\n modelIndex4: 0,\n frame: 0,\n skinNum: 0,\n effects: 0,\n renderfx: 0,\n solid: 0,\n sound: 0,\n event: 0,\n ...overrides,\n});\n\nexport const createGameStateSnapshotFactory = (overrides?: Partial<GameStateSnapshot>): GameStateSnapshot => ({\n gravity: { x: 0, y: 0, z: -800 },\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewangles: { x: 0, y: 0, z: 0 },\n level: { timeSeconds: 0, frameNumber: 0, previousTimeSeconds: 0, deltaSeconds: 0.1 },\n entities: {\n activeCount: 0,\n worldClassname: 'worldspawn',\n },\n packetEntities: [],\n pmFlags: 0,\n pmType: 0,\n waterlevel: 0,\n watertype: 0,\n deltaAngles: { x: 0, y: 0, z: 0 },\n health: 100,\n armor: 0,\n ammo: 0,\n blend: [0, 0, 0, 0],\n damageAlpha: 0,\n damageIndicators: [],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n pm_time: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n pm_flags: 0,\n pm_type: 0,\n ...overrides,\n});\n","import { vi, type Mock } from 'vitest';\nimport { Entity, SpawnRegistry, ScriptHookRegistry, type SpawnContext, type EntitySystem } from '@quake2ts/game';\nimport { createRandomGenerator, type Vec3 } from '@quake2ts/shared';\n\n// Re-export generic helpers from shared\nexport { intersects, stairTrace, ladderTrace } from '@quake2ts/shared';\n\n// -- Types --\n\nexport interface MockEngine {\n sound: Mock<[Entity, number, string, number, number, number], void>;\n soundIndex: Mock<[string], number>;\n modelIndex: Mock<[string], number>;\n centerprintf: Mock<[Entity, string], void>;\n}\n\nexport interface MockGame {\n random: ReturnType<typeof createRandomGenerator>;\n registerEntitySpawn: Mock<[string, (entity: Entity) => void], void>;\n unregisterEntitySpawn: Mock<[string], void>;\n getCustomEntities: Mock<[], string[]>;\n hooks: ScriptHookRegistry;\n registerHooks: Mock<[any], any>;\n spawnWorld: Mock<[], void>;\n clientBegin: Mock<[any], void>;\n damage: Mock<[number], void>;\n}\n\nexport interface TestContext extends SpawnContext {\n entities: EntitySystem;\n game: MockGame;\n engine: MockEngine;\n}\n\n// -- Factories --\n\nexport const createMockEngine = (): MockEngine => ({\n sound: vi.fn(),\n soundIndex: vi.fn((sound: string) => 0),\n modelIndex: vi.fn((model: string) => 0),\n centerprintf: vi.fn(),\n});\n\nexport const createMockGame = (seed: number = 12345): { game: MockGame, spawnRegistry: SpawnRegistry } => {\n const spawnRegistry = new SpawnRegistry();\n const hooks = new ScriptHookRegistry();\n\n const game: MockGame = {\n random: createRandomGenerator({ seed }),\n registerEntitySpawn: vi.fn((classname: string, spawnFunc: (entity: Entity) => void) => {\n spawnRegistry.register(classname, (entity) => spawnFunc(entity));\n }),\n unregisterEntitySpawn: vi.fn((classname: string) => {\n spawnRegistry.unregister(classname);\n }),\n getCustomEntities: vi.fn(() => Array.from(spawnRegistry.keys())),\n hooks,\n registerHooks: vi.fn((newHooks) => hooks.register(newHooks)),\n spawnWorld: vi.fn(() => {\n hooks.onMapLoad('q2dm1');\n }),\n clientBegin: vi.fn((client) => {\n hooks.onPlayerSpawn({} as any);\n }),\n damage: vi.fn((amount: number) => {\n hooks.onDamage({} as any, null, null, amount, 0, 0);\n })\n };\n\n return { game, spawnRegistry };\n};\n\nexport function createTestContext(options?: { seed?: number, initialEntities?: Entity[] }): TestContext {\n const engine = createMockEngine();\n const seed = options?.seed ?? 12345;\n const { game, spawnRegistry } = createMockGame(seed);\n\n const traceFn = vi.fn((start: Vec3, end: Vec3, mins?: Vec3, maxs?: Vec3) => ({\n fraction: 1.0,\n ent: null,\n allsolid: false,\n startsolid: false,\n endpos: end,\n plane: { normal: { x: 0, y: 0, z: 1 }, dist: 0 },\n surfaceFlags: 0,\n contents: 0\n }));\n\n const entityList: Entity[] = options?.initialEntities ? [...options.initialEntities] : [];\n\n // Create hooks helper that interacts with the entity list\n const hooks = game.hooks;\n\n const entities = {\n spawn: vi.fn(() => {\n const ent = new Entity(entityList.length + 1);\n entityList.push(ent);\n hooks.onEntitySpawn(ent);\n return ent;\n }),\n free: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n hooks.onEntityRemove(ent);\n }),\n finalizeSpawn: vi.fn(),\n freeImmediate: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n }),\n setSpawnRegistry: vi.fn(),\n timeSeconds: 10,\n deltaSeconds: 0.1,\n modelIndex: vi.fn(() => 0),\n scheduleThink: vi.fn((entity: Entity, time: number) => {\n entity.nextthink = time;\n }),\n linkentity: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n multicast: vi.fn(),\n unicast: vi.fn(),\n engine,\n game,\n sound: vi.fn((ent: Entity, chan: number, sound: string, vol: number, attn: number, timeofs: number) => {\n engine.sound(ent, chan, sound, vol, attn, timeofs);\n }),\n soundIndex: vi.fn((sound: string) => engine.soundIndex(sound)),\n useTargets: vi.fn((entity: Entity, activator: Entity | null) => {\n }),\n findByTargetName: vi.fn(() => []),\n pickTarget: vi.fn(() => null),\n killBox: vi.fn(),\n rng: createRandomGenerator({ seed }),\n imports: {\n configstring: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n },\n level: {\n intermission_angle: { x: 0, y: 0, z: 0 },\n intermission_origin: { x: 0, y: 0, z: 0 },\n next_auto_save: 0,\n health_bar_entities: null\n },\n targetNameIndex: new Map(),\n forEachEntity: vi.fn((callback: (ent: Entity) => void) => {\n entityList.forEach(callback);\n }),\n find: vi.fn((predicate: (ent: Entity) => boolean) => {\n return entityList.find(predicate);\n }),\n findByClassname: vi.fn((classname: string) => {\n return entityList.find(e => e.classname === classname);\n }),\n beginFrame: vi.fn((timeSeconds: number) => {\n (entities as any).timeSeconds = timeSeconds;\n }),\n targetAwareness: {\n timeSeconds: 10,\n frameNumber: 1,\n sightEntity: null,\n soundEntity: null,\n },\n // Adding missing properties to satisfy EntitySystem interface partially or fully\n // We cast to unknown first anyway, but filling these in makes it safer for consumers\n skill: 1,\n deathmatch: false,\n coop: false,\n activeCount: entityList.length,\n world: entityList.find(e => e.classname === 'worldspawn') || new Entity(0),\n // ... other EntitySystem properties would go here\n } as unknown as EntitySystem;\n\n return {\n keyValues: {},\n entities,\n game,\n engine,\n health_multiplier: 1,\n warn: vi.fn(),\n free: vi.fn(),\n // Mock precache functions if they are part of SpawnContext in future or TestContext extensions\n precacheModel: vi.fn(),\n precacheSound: vi.fn(),\n precacheImage: vi.fn(),\n } as unknown as TestContext;\n}\n\nexport function createSpawnContext(): SpawnContext {\n return createTestContext();\n}\n\nexport function createEntity(): Entity {\n return new Entity(1);\n}\n","import { Entity, GameExports, GameImports } from '@quake2ts/game';\nimport { vi } from 'vitest';\n\nexport interface GameState {\n levelName: string;\n time: number;\n entities: Entity[];\n clients: any[]; // Mock client objects\n}\n\n/**\n * Creates a mock game state object.\n * @param overrides Optional overrides for the game state.\n */\nexport function createMockGameState(overrides?: Partial<GameState>): GameState {\n return {\n levelName: 'test_level',\n time: 0,\n entities: [],\n clients: [],\n ...overrides\n };\n}\n","import { NetworkTransport } from '@quake2ts/server';\nimport { NetDriver } from '@quake2ts/shared';\nimport { vi } from 'vitest';\n\n/**\n * Mock implementation of the NetworkTransport interface for server testing.\n * Allows simulating connections and errors.\n */\nexport class MockTransport implements NetworkTransport {\n public onConnectionCallback?: (driver: NetDriver, info?: any) => void;\n public onErrorCallback?: (error: Error) => void;\n public address: string = '127.0.0.1';\n public port: number = 27910;\n public sentMessages: Uint8Array[] = [];\n public receivedMessages: Uint8Array[] = [];\n public listening: boolean = false;\n\n public listenSpy = vi.fn().mockImplementation(async (port: number) => {\n this.port = port;\n this.listening = true;\n });\n public closeSpy = vi.fn().mockImplementation(() => {\n this.listening = false;\n });\n\n /**\n * Start listening on the specified port.\n */\n async listen(port: number): Promise<void> {\n return this.listenSpy(port);\n }\n\n /**\n * Close the transport.\n */\n close() {\n this.closeSpy();\n }\n\n /**\n * Register a callback for new connections.\n */\n onConnection(callback: (driver: NetDriver, info?: any) => void) {\n this.onConnectionCallback = callback;\n }\n\n /**\n * Register a callback for errors.\n */\n onError(callback: (error: Error) => void) {\n this.onErrorCallback = callback;\n }\n\n /**\n * Check if the transport is currently listening.\n */\n public isListening(): boolean {\n return this.listening;\n }\n\n /**\n * Helper to simulate a new connection.\n * @param driver The network driver for the connection.\n * @param info Optional connection info.\n */\n public simulateConnection(driver: NetDriver, info?: any) {\n if (this.onConnectionCallback) {\n this.onConnectionCallback(driver, info);\n }\n }\n\n /**\n * Helper to simulate an error.\n * @param error The error to simulate.\n */\n public simulateError(error: Error) {\n if (this.onErrorCallback) {\n this.onErrorCallback(error);\n }\n }\n}\n\n/**\n * Interface for mock UDP socket.\n * This is a partial mock of Node.js dgram.Socket or similar.\n */\nexport interface MockUDPSocket {\n send: (msg: Uint8Array, offset: number, length: number, port: number, address: string, callback?: (error: Error | null, bytes: number) => void) => void;\n on: (event: string, callback: (...args: any[]) => void) => void;\n close: () => void;\n bind: (port: number, address?: string) => void;\n address: () => { address: string; family: string; port: number };\n}\n\n/**\n * Creates a mock UDP socket.\n * @param overrides Optional overrides for the socket methods.\n */\nexport function createMockUDPSocket(overrides?: Partial<MockUDPSocket>): MockUDPSocket {\n const socket: MockUDPSocket = {\n send: vi.fn(),\n on: vi.fn(),\n close: vi.fn(),\n bind: vi.fn(),\n address: vi.fn().mockReturnValue({ address: '127.0.0.1', family: 'IPv4', port: 0 }),\n ...overrides,\n };\n return socket;\n}\n\n/**\n * Interface for network address.\n */\nexport interface NetworkAddress {\n ip: string;\n port: number;\n}\n\n/**\n * Creates a mock network address.\n * @param ip IP address (default: '127.0.0.1')\n * @param port Port number (default: 27910)\n */\nexport function createMockNetworkAddress(ip: string = '127.0.0.1', port: number = 27910): NetworkAddress {\n return { ip, port };\n}\n\n/**\n * Creates a configured MockTransport instance.\n * @param address Address to bind to (default: '127.0.0.1')\n * @param port Port to listen on (default: 27910)\n * @param overrides Optional overrides for the transport properties.\n */\nexport function createMockTransport(\n address: string = '127.0.0.1',\n port: number = 27910,\n overrides?: Partial<MockTransport>\n): MockTransport {\n const transport = new MockTransport();\n transport.address = address;\n transport.port = port;\n Object.assign(transport, overrides);\n return transport;\n}\n","import { Server, ServerState, ServerStatic, Client, ClientState } from '@quake2ts/server';\nimport { NetDriver, MAX_CONFIGSTRINGS, MAX_EDICTS, EntityState } from '@quake2ts/shared';\nimport { Entity } from '@quake2ts/game';\nimport { vi } from 'vitest';\n\n/**\n * Creates a mock server state object.\n * @param overrides Optional overrides for the server state.\n */\nexport function createMockServerState(overrides?: Partial<Server>): Server {\n return {\n state: ServerState.Game,\n attractLoop: false,\n loadGame: false,\n startTime: Date.now(),\n time: 0,\n frame: 0,\n name: 'test_map',\n collisionModel: null,\n configStrings: new Array(MAX_CONFIGSTRINGS).fill(''),\n baselines: new Array(MAX_EDICTS).fill(null),\n multicastBuf: new Uint8Array(0),\n ...overrides\n };\n}\n\n/**\n * Creates a mock server static object.\n * @param maxClients Maximum number of clients.\n * @param overrides Optional overrides for the server static state.\n */\nexport function createMockServerStatic(maxClients: number = 16, overrides?: Partial<ServerStatic>): ServerStatic {\n return {\n initialized: true,\n realTime: Date.now(),\n mapCmd: '',\n spawnCount: 1,\n clients: new Array(maxClients).fill(null),\n lastHeartbeat: 0,\n challenges: [],\n ...overrides\n };\n}\n\n/**\n * Creates a mock server client.\n * @param clientNum The client index.\n * @param overrides Optional overrides for the client.\n */\nexport function createMockServerClient(clientNum: number, overrides?: Partial<Client>): Client {\n // Create a minimal mock net driver\n const mockNet: NetDriver = {\n connect: vi.fn(),\n disconnect: vi.fn(),\n send: vi.fn(),\n onMessage: vi.fn(),\n onClose: vi.fn(),\n onError: vi.fn(),\n isConnected: vi.fn().mockReturnValue(true)\n };\n\n return {\n index: clientNum,\n state: ClientState.Connected,\n edict: { index: clientNum + 1 } as Entity,\n net: mockNet,\n netchan: {\n qport: 0,\n remoteAddress: '127.0.0.1',\n incomingSequence: 0,\n outgoingSequence: 0,\n lastReceived: 0,\n process: vi.fn(),\n transmit: vi.fn(),\n writeReliableByte: vi.fn(),\n writeReliableShort: vi.fn(),\n writeReliableLong: vi.fn(),\n writeReliableString: vi.fn(),\n writeReliableData: vi.fn(),\n } as any, // Cast as any because NetChan might be complex to fully mock here\n userInfo: '',\n lastMessage: 0,\n lastCommandTime: 0,\n commandCount: 0,\n messageQueue: [],\n frames: [],\n lastFrame: 0,\n lastPacketEntities: [],\n challenge: 0,\n lastConnect: 0,\n ping: 0,\n rate: 0,\n name: `Client${clientNum}`,\n messageLevel: 0,\n datagram: new Uint8Array(0),\n downloadSize: 0,\n downloadCount: 0,\n commandMsec: 0,\n frameLatency: [],\n messageSize: [],\n suppressCount: 0,\n commandQueue: [],\n lastCmd: {\n msec: 0,\n buttons: 0,\n angles: { x: 0, y: 0, z: 0 },\n forwardmove: 0,\n sidemove: 0,\n upmove: 0,\n sequence: 0,\n lightlevel: 0,\n impulse: 0,\n serverFrame: 0\n },\n ...overrides\n };\n}\n\n/**\n * Mock interface for the Server class (DedicatedServer).\n * This allows mocking the server instance itself.\n */\nexport interface MockServer {\n start(mapName: string): Promise<void>;\n stop(): void;\n // tick(): void; // runFrame is private in DedicatedServer, usually we simulate via game.frame\n multicast(origin: any, type: any, event: any, ...args: any[]): void;\n unicast(ent: Entity, reliable: boolean, event: any, ...args: any[]): void;\n configstring(index: number, value: string): void;\n kickPlayer(clientId: number): void;\n changeMap(mapName: string): Promise<void>;\n}\n\n/**\n * Creates a mock server instance.\n * @param overrides Optional overrides for server methods.\n */\nexport function createMockServer(overrides?: Partial<MockServer>): MockServer {\n return {\n start: vi.fn().mockResolvedValue(undefined),\n stop: vi.fn(),\n multicast: vi.fn(),\n unicast: vi.fn(),\n configstring: vi.fn(),\n kickPlayer: vi.fn(),\n changeMap: vi.fn().mockResolvedValue(undefined),\n ...overrides\n };\n}\n","import { Client, ClientState } from '@quake2ts/server';\nimport { createMockServerClient } from './state.js';\n\n/**\n * Interface representing connection state for testing.\n */\nexport interface Connection {\n state: ClientState;\n address: string;\n challenge: number;\n userInfo: UserInfo;\n}\n\n/**\n * Stages of the client connection handshake.\n */\nexport enum HandshakeStage {\n None = 0,\n Challenge = 1,\n Connect = 2,\n Info = 3,\n Active = 4\n}\n\n/**\n * Interface representing a handshake state.\n */\nexport interface Handshake {\n stage: HandshakeStage;\n clientNum: number;\n challenge: number;\n qport: number;\n}\n\n/**\n * Interface for UserInfo structure.\n */\nexport interface UserInfo {\n name: string;\n skin: string;\n model: string;\n fov: number;\n hand: number;\n rate: number;\n msg: number;\n spectator?: number;\n [key: string]: string | number | undefined;\n}\n\n/**\n * Helper to serialize UserInfo to Quake 2 info string format.\n * Format: \\key\\value\\key2\\value2\n */\nexport function serializeUserInfo(info: UserInfo): string {\n return Object.entries(info).reduce((acc, [key, value]) => {\n if (value !== undefined) {\n return `${acc}\\\\${key}\\\\${value}`;\n }\n return acc;\n }, '');\n}\n\n/**\n * Creates a mock UserInfo object.\n * @param overrides Optional overrides for the user info.\n */\nexport function createMockUserInfo(overrides?: Partial<UserInfo>): UserInfo {\n return {\n name: 'Player',\n skin: 'male/grunt',\n model: 'male/grunt',\n fov: 90,\n hand: 0,\n rate: 25000,\n msg: 1,\n ...overrides\n };\n}\n\n/**\n * Creates a mock connection object (Client) with specific state.\n * @param state The client state (default: Connected).\n * @param overrides Optional overrides for the client.\n */\nexport function createMockConnection(state: ClientState = ClientState.Connected, overrides?: Partial<Client>): Client {\n return createMockServerClient(0, {\n state,\n userInfo: serializeUserInfo(createMockUserInfo()),\n challenge: Math.floor(Math.random() * 100000),\n ...overrides\n });\n}\n\n/**\n * Creates a mock handshake object.\n * @param stage The stage of the handshake (default: None).\n */\nexport function createMockHandshake(stage: HandshakeStage = HandshakeStage.None): Handshake {\n return {\n stage,\n clientNum: -1,\n challenge: 0,\n qport: Math.floor(Math.random() * 65536)\n };\n}\n\n/**\n * Simulates a handshake between a mock client and server.\n * Note: This is a high-level simulation helper.\n * @param client The mock client connection.\n * @param server The mock server instance.\n * @returns Promise that resolves to true if handshake succeeded.\n */\nexport async function simulateHandshake(client: Client, server: any): Promise<boolean> {\n // 1. Get Challenge\n // In a real scenario, client sends getchallenge, server responds with challenge\n const challenge = Math.floor(Math.random() * 100000);\n client.challenge = challenge;\n\n // 2. Connect\n // Client sends connect command with qport, challenge, userinfo\n // Server assigns client slot\n if (server && server.clients) {\n // rudimentary check if server has space\n }\n\n // 3. Update state to Connected\n client.state = ClientState.Connected;\n\n // 4. Send configstrings (usually handled by server)\n\n // 5. Client enters game (prespawn)\n // Server sends stuff\n\n // 6. Client ready\n client.state = ClientState.Active;\n\n return true;\n}\n","import { Server, Client, ClientState, ServerState, ServerStatic } from '@quake2ts/server';\nimport { Entity } from '@quake2ts/game';\nimport { UserCommand } from '@quake2ts/shared';\nimport { createMockServerState } from '../mocks/state.js';\nimport { createMockServerClient } from '../mocks/state.js';\nimport { createMockUserInfo, serializeUserInfo, UserInfo } from '../mocks/connection.js';\n\n// Define a type that combines Server and ServerStatic for convenience in tests\n// since the real server implementation splits these but tests often need both.\nexport type MockServerContext = Server & {\n clients: (Client | null)[];\n entities?: Entity[];\n};\n\nexport interface MultiplayerScenario {\n server: MockServerContext;\n clients: Client[];\n entities: Entity[];\n}\n\n/**\n * Creates a multiplayer test scenario with a mock server and a number of clients.\n * @param numPlayers Number of players to simulate.\n */\nexport function createMultiplayerTestScenario(numPlayers: number = 2): MultiplayerScenario {\n const baseServer = createMockServerState();\n const clients: Client[] = [];\n const entities: Entity[] = [];\n\n const server: MockServerContext = {\n ...baseServer,\n clients: new Array(numPlayers).fill(null),\n entities: []\n };\n\n for (let i = 0; i < numPlayers; i++) {\n // Create client\n const client = createMockServerClient(i, {\n state: ClientState.Active,\n userInfo: serializeUserInfo(createMockUserInfo({ name: `Player${i}` }))\n });\n\n // Create player entity\n const entity = {\n classname: 'player',\n s: { origin: { x: 0, y: 0, z: 0 }, number: i + 1 },\n client: client\n } as unknown as Entity;\n\n client.edict = entity;\n server.clients[i] = client;\n clients.push(client);\n entities.push(entity);\n }\n\n // Assign entities to server\n server.entities = entities;\n\n return {\n server,\n clients,\n entities\n };\n}\n\n/**\n * Simulates a player joining the server.\n * @param server The mock server instance.\n * @param userInfo Optional user info overrides.\n */\nexport async function simulatePlayerJoin(server: MockServerContext, userInfo?: Partial<UserInfo>): Promise<Client> {\n // Find free client slot\n const index = server.clients.findIndex((c) => !c || c.state === ClientState.Free);\n if (index === -1) {\n throw new Error('Server full');\n }\n\n const client = createMockServerClient(index, {\n state: ClientState.Connected,\n userInfo: serializeUserInfo(createMockUserInfo(userInfo))\n });\n\n server.clients[index] = client;\n\n // Simulate connection process\n client.state = ClientState.Active;\n\n // Create entity\n const entity = {\n classname: 'player',\n s: { origin: { x: 0, y: 0, z: 0 }, number: index + 1 },\n client: client\n } as unknown as Entity;\n client.edict = entity;\n\n // Add to entities list if possible (mock behavior)\n if (server.entities && Array.isArray(server.entities)) {\n // This is a simplified view, normally entities are in a fixed array\n (server.entities as Entity[])[index + 1] = entity;\n }\n\n return client;\n}\n\n/**\n * Simulates a player leaving the server.\n * @param server The mock server instance.\n * @param clientNum The client number to disconnect.\n */\nexport function simulatePlayerLeave(server: MockServerContext, clientNum: number): void {\n const client = server.clients[clientNum];\n if (client) {\n client.state = ClientState.Free;\n client.edict = null;\n }\n}\n\n/**\n * Simulates a single server frame update.\n * @param server The mock server instance.\n * @param deltaTime Time step in seconds (default: 0.1).\n */\nexport function simulateServerTick(server: MockServerContext, deltaTime: number = 0.1): void {\n server.time += deltaTime;\n server.frame++;\n // In a real server, we would call RunFrame, Physics, etc.\n // For mocks, we might just update client lastCmd times\n\n server.clients.forEach((client: Client | null) => {\n if (client && client.state === ClientState.Active) {\n // Update client logic if needed\n }\n });\n}\n\n/**\n * Simulates player input for a specific client.\n * @param client The server client.\n * @param input The input command.\n */\nexport function simulatePlayerInput(client: Client, input: Partial<UserCommand>): void {\n const cmd: UserCommand = {\n msec: 100,\n buttons: 0,\n angles: { x: 0, y: 0, z: 0 },\n forwardmove: 0,\n sidemove: 0,\n upmove: 0,\n sequence: client.lastCmd.sequence + 1,\n lightlevel: 0,\n impulse: 0,\n ...input\n };\n\n client.lastCmd = cmd;\n client.commandQueue.push(cmd);\n client.commandCount++;\n}\n","import { Server } from '@quake2ts/server';\nimport { EntityState } from '@quake2ts/shared';\n\nexport interface Snapshot {\n serverTime: number;\n playerState: any; // Simplified PlayerState\n entities: EntityState[];\n}\n\nexport interface DeltaSnapshot {\n snapshot: Snapshot;\n deltaEntities: EntityState[];\n removedEntities: number[];\n}\n\nexport interface ConsistencyReport {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Creates a client-specific snapshot from the server state.\n * @param serverState The current server state.\n * @param clientNum The client number to generate snapshot for.\n */\nexport function createServerSnapshot(serverState: Server, clientNum: number): Snapshot {\n // Collect visible entities\n const visibleEntities: EntityState[] = [];\n\n // In a real implementation, this would use PVS/PHS\n // For mock, we just take all entities that have a model or are solid\n if (serverState.baselines) {\n serverState.baselines.forEach((ent: EntityState | null, index: number) => {\n if (ent && index !== clientNum + 1) { // Skip self in packet entities usually\n visibleEntities.push({ ...ent });\n }\n });\n }\n\n return {\n serverTime: serverState.time,\n playerState: {\n origin: { x: 0, y: 0, z: 0 },\n viewangles: { x: 0, y: 0, z: 0 },\n pm_type: 0\n },\n entities: visibleEntities\n };\n}\n\n/**\n * Calculates the delta between two snapshots.\n * @param oldSnapshot The baseline snapshot.\n * @param newSnapshot The current snapshot.\n */\nexport function createDeltaSnapshot(oldSnapshot: Snapshot, newSnapshot: Snapshot): DeltaSnapshot {\n const deltaEntities: EntityState[] = [];\n const removedEntities: number[] = [];\n\n const oldMap = new Map(oldSnapshot.entities.map(e => [e.number, e]));\n const newMap = new Map(newSnapshot.entities.map(e => [e.number, e]));\n\n // Find changed or new entities\n newSnapshot.entities.forEach(newEnt => {\n const oldEnt = oldMap.get(newEnt.number);\n if (!oldEnt) {\n // New entity\n deltaEntities.push(newEnt);\n } else if (JSON.stringify(newEnt) !== JSON.stringify(oldEnt)) {\n // Changed entity (simplified check)\n deltaEntities.push(newEnt);\n }\n });\n\n // Find removed entities\n oldSnapshot.entities.forEach(oldEnt => {\n if (!newMap.has(oldEnt.number)) {\n removedEntities.push(oldEnt.number);\n }\n });\n\n return {\n snapshot: newSnapshot,\n deltaEntities,\n removedEntities\n };\n}\n\n/**\n * Verifies the consistency of a sequence of snapshots.\n * @param snapshots Array of snapshots ordered by time.\n */\nexport function verifySnapshotConsistency(snapshots: Snapshot[]): ConsistencyReport {\n const report: ConsistencyReport = { valid: true, errors: [] };\n\n if (snapshots.length < 2) return report;\n\n for (let i = 1; i < snapshots.length; i++) {\n const prev = snapshots[i-1];\n const curr = snapshots[i];\n\n if (curr.serverTime <= prev.serverTime) {\n report.valid = false;\n report.errors.push(`Snapshot ${i} has time ${curr.serverTime} <= prev ${prev.serverTime}`);\n }\n }\n\n return report;\n}\n\n/**\n * Simulates network delivery of a snapshot with potential packet loss.\n * @param snapshot The snapshot to deliver.\n * @param reliability Probability of successful delivery (0.0 to 1.0).\n */\nexport async function simulateSnapshotDelivery(snapshot: Snapshot, reliability: number = 1.0): Promise<Snapshot | null> {\n if (Math.random() > reliability) {\n return null;\n }\n return snapshot;\n}\n","import { JSDOM } from 'jsdom';\nimport { Canvas, Image, ImageData } from '@napi-rs/canvas';\nimport 'fake-indexeddb/auto';\nimport { MockPointerLock } from '../e2e/input.js';\nimport { createMockWebGL2Context } from './webgl.js';\n\nexport interface BrowserSetupOptions {\n url?: string;\n pretendToBeVisual?: boolean;\n resources?: \"usable\";\n enableWebGL2?: boolean;\n enablePointerLock?: boolean;\n}\n\n/**\n * Sets up a browser environment for testing using JSDOM and napi-rs/canvas.\n * This should be called in your vitest.setup.ts file.\n */\nexport function setupBrowserEnvironment(options: BrowserSetupOptions = {}) {\n const {\n url = 'http://localhost',\n pretendToBeVisual = true,\n resources = undefined,\n enableWebGL2 = false,\n enablePointerLock = false\n } = options;\n\n // Create a JSDOM instance\n const dom = new JSDOM('<!DOCTYPE html><html><head></head><body></body></html>', {\n url,\n pretendToBeVisual,\n resources\n });\n\n // Set up global variables\n global.window = dom.window as any;\n global.document = dom.window.document;\n\n // Handle navigator assignment safely (handling read-only global.navigator if needed)\n try {\n // @ts-ignore\n global.navigator = dom.window.navigator;\n } catch (e) {\n // If direct assignment fails, try Object.defineProperty\n try {\n Object.defineProperty(global, 'navigator', {\n value: dom.window.navigator,\n writable: true,\n configurable: true\n });\n } catch (e2) {\n console.warn('Could not assign global.navigator, skipping.');\n }\n }\n\n global.location = dom.window.location;\n global.HTMLElement = dom.window.HTMLElement;\n global.HTMLCanvasElement = dom.window.HTMLCanvasElement;\n\n // Polyfill global Event constructors to match JSDOM's window\n global.Event = dom.window.Event;\n global.CustomEvent = dom.window.CustomEvent;\n global.DragEvent = dom.window.DragEvent as any;\n global.MouseEvent = dom.window.MouseEvent;\n global.KeyboardEvent = dom.window.KeyboardEvent;\n global.FocusEvent = dom.window.FocusEvent;\n global.WheelEvent = dom.window.WheelEvent;\n global.InputEvent = dom.window.InputEvent;\n global.UIEvent = dom.window.UIEvent;\n\n // Setup Storage mocks\n // First try to use JSDOM's localStorage\n try {\n global.localStorage = dom.window.localStorage;\n } catch (e) {\n // Ignore if it fails (e.g. strict mode)\n }\n\n // Fallback if not present\n if (!global.localStorage) {\n const storage = new Map<string, string>();\n global.localStorage = {\n getItem: (key: string) => storage.get(key) || null,\n setItem: (key: string, value: string) => storage.set(key, value),\n removeItem: (key: string) => storage.delete(key),\n clear: () => storage.clear(),\n key: (index: number) => Array.from(storage.keys())[index] || null,\n get length() { return storage.size; }\n } as Storage;\n }\n\n // Override document.createElement for canvas elements to use napi-rs/canvas\n const originalCreateElement = document.createElement.bind(document);\n document.createElement = function (tagName: string, options?: any) {\n if (tagName.toLowerCase() === 'canvas') {\n const napiCanvas = new Canvas(300, 150); // default canvas size\n\n // Create a wrapper that extends the DOM canvas element\n const domCanvas = originalCreateElement('canvas', options);\n\n // Copy properties and methods from napi-rs canvas to DOM canvas\n Object.defineProperty(domCanvas, 'width', {\n get: () => napiCanvas.width,\n set: (value) => { napiCanvas.width = value; },\n enumerable: true,\n configurable: true\n });\n\n Object.defineProperty(domCanvas, 'height', {\n get: () => napiCanvas.height,\n set: (value) => { napiCanvas.height = value; },\n enumerable: true,\n configurable: true\n });\n\n // Override getContext to return appropriate context\n const originalGetContext = domCanvas.getContext.bind(domCanvas);\n domCanvas.getContext = function(contextId: string, options?: any) {\n if (contextId === '2d') {\n return napiCanvas.getContext('2d', options);\n }\n\n if (enableWebGL2 && contextId === 'webgl2') {\n return createMockWebGL2Context(domCanvas as HTMLCanvasElement);\n }\n\n // For webgl/webgl2, return jsdom's default context (null or mock)\n // or the original behavior if needed.\n if (contextId === 'webgl' || contextId === 'webgl2') {\n return originalGetContext(contextId, options);\n }\n return napiCanvas.getContext(contextId as any, options);\n } as any;\n\n // Store reference to napi canvas for direct access if needed\n (domCanvas as any).__napiCanvas = napiCanvas;\n\n return domCanvas;\n }\n return originalCreateElement(tagName, options);\n } as any;\n\n // Also override HTMLCanvasElement.prototype.getContext to support direct instantiation via JSDOM\n if (enableWebGL2) {\n const originalProtoGetContext = global.HTMLCanvasElement.prototype.getContext;\n global.HTMLCanvasElement.prototype.getContext = function (\n contextId: string,\n options?: any\n ): any {\n if (contextId === 'webgl2') {\n return createMockWebGL2Context(this);\n }\n return originalProtoGetContext.call(this, contextId, options);\n };\n }\n\n // Set up global Image constructor\n global.Image = Image as any;\n\n // Set up global ImageData constructor\n global.ImageData = ImageData as any;\n\n // Mock createImageBitmap if not available\n if (typeof global.createImageBitmap === 'undefined') {\n global.createImageBitmap = async function (\n image: any, // Relax type to allow passing different image sources\n _options?: ImageBitmapOptions\n ): Promise<any> {\n // Handle ImageData specially\n if (image && typeof image.width === 'number' && typeof image.height === 'number') {\n // For testing purposes, we can create a small canvas with the image data\n const canvas = new Canvas(image.width, image.height);\n const ctx = canvas.getContext('2d');\n // Only try to put data if it looks like ImageData\n if (image.data) {\n ctx.putImageData(image as any, 0, 0);\n }\n return canvas;\n }\n // Fallback for other sources (e.g. Image element) - return empty canvas of generic size\n const canvas = new Canvas(100, 100);\n return canvas;\n } as any;\n }\n\n // Mock btoa and atob if not available\n if (typeof global.btoa === 'undefined') {\n global.btoa = function (str: string): string {\n return Buffer.from(str, 'binary').toString('base64');\n };\n }\n\n if (typeof global.atob === 'undefined') {\n global.atob = function (str: string): string {\n return Buffer.from(str, 'base64').toString('binary');\n };\n }\n\n // Mock Pointer Lock API\n if (enablePointerLock) {\n MockPointerLock.setup(global.document);\n }\n\n // Mock requestAnimationFrame\n // We use a simplified version that runs immediately or with small delay for tests\n if (typeof global.requestAnimationFrame === 'undefined') {\n let lastTime = 0;\n global.requestAnimationFrame = (callback: FrameRequestCallback) => {\n const currTime = Date.now();\n const timeToCall = Math.max(0, 16 - (currTime - lastTime));\n const id = setTimeout(() => {\n callback(currTime + timeToCall);\n }, timeToCall);\n lastTime = currTime + timeToCall;\n return id as unknown as number;\n };\n\n global.cancelAnimationFrame = (id: number) => {\n clearTimeout(id);\n };\n }\n}\n\n/**\n * Cleans up the browser environment.\n */\nexport function teardownBrowserEnvironment() {\n // Optional cleanup if needed, though usually global scope cleanup is handled by test runner context\n // or by just overriding it again.\n // For strict cleanup, we could delete globals, but in Vitest environment, it might persist?\n // We'll leave it simple for now or just undefined them.\n\n // @ts-ignore\n delete global.window;\n // @ts-ignore\n delete global.document;\n // @ts-ignore\n delete global.navigator;\n // @ts-ignore\n delete global.localStorage;\n // @ts-ignore\n delete global.location;\n // @ts-ignore\n delete global.HTMLElement;\n // @ts-ignore\n delete global.HTMLCanvasElement;\n // @ts-ignore\n delete global.Image;\n // @ts-ignore\n delete global.ImageData;\n // @ts-ignore\n delete global.createImageBitmap;\n\n // @ts-ignore\n delete global.Event;\n // @ts-ignore\n delete global.CustomEvent;\n // @ts-ignore\n delete global.DragEvent;\n // @ts-ignore\n delete global.MouseEvent;\n // @ts-ignore\n delete global.KeyboardEvent;\n // @ts-ignore\n delete global.FocusEvent;\n // @ts-ignore\n delete global.WheelEvent;\n // @ts-ignore\n delete global.InputEvent;\n // @ts-ignore\n delete global.UIEvent;\n\n // Note: btoa/atob might be native in newer Node versions, so be careful deleting them if they were original.\n // But here we only set them if undefined.\n}\n","\nexport class MockPointerLock {\n static setup(doc: Document) {\n // Mock pointerLockElement property\n let _pointerLockElement: Element | null = null;\n\n Object.defineProperty(doc, 'pointerLockElement', {\n get: () => _pointerLockElement,\n configurable: true\n });\n\n // Mock exitPointerLock\n doc.exitPointerLock = () => {\n if (_pointerLockElement) {\n _pointerLockElement = null;\n doc.dispatchEvent(new Event('pointerlockchange'));\n }\n };\n\n // Mock requestPointerLock on Element prototype\n // We need to extend the Element interface to make TS happy if we were strict,\n // but here we are modifying the prototype directly.\n // @ts-ignore\n (global.HTMLElement.prototype as any).requestPointerLock = function() {\n // In a real browser this is async and requires user gesture,\n // but for tests we make it immediate.\n _pointerLockElement = this;\n doc.dispatchEvent(new Event('pointerlockchange'));\n };\n }\n}\n\nexport class InputInjector {\n constructor(private doc: Document, private win: any) {}\n\n keyDown(key: string, code?: string) {\n const event = new this.win.KeyboardEvent('keydown', {\n key,\n code: code || key,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n this.doc.dispatchEvent(event);\n }\n\n keyUp(key: string, code?: string) {\n const event = new this.win.KeyboardEvent('keyup', {\n key,\n code: code || key,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n this.doc.dispatchEvent(event);\n }\n\n mouseMove(movementX: number, movementY: number, clientX = 0, clientY = 0) {\n const event = new this.win.MouseEvent('mousemove', {\n bubbles: true,\n cancelable: true,\n view: this.win,\n clientX,\n clientY,\n movementX, // Note: JSDOM might not support this standard property fully on event init\n movementY\n } as any);\n\n // Force movement properties if JSDOM doesn't handle them\n Object.defineProperty(event, 'movementX', { value: movementX });\n Object.defineProperty(event, 'movementY', { value: movementY });\n\n // Dispatch to pointer lock element if active, otherwise document\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n mouseDown(button: number = 0) {\n const event = new this.win.MouseEvent('mousedown', {\n button,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n mouseUp(button: number = 0) {\n const event = new this.win.MouseEvent('mouseup', {\n button,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n wheel(deltaY: number) {\n const event = new this.win.WheelEvent('wheel', {\n deltaY,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n}\n","\nexport function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext {\n const gl = {\n canvas,\n drawingBufferWidth: canvas.width,\n drawingBufferHeight: canvas.height,\n\n // Constants\n VERTEX_SHADER: 0x8B31,\n FRAGMENT_SHADER: 0x8B30,\n COMPILE_STATUS: 0x8B81,\n LINK_STATUS: 0x8B82,\n ARRAY_BUFFER: 0x8892,\n ELEMENT_ARRAY_BUFFER: 0x8893,\n STATIC_DRAW: 0x88E4,\n DYNAMIC_DRAW: 0x88E8,\n FLOAT: 0x1406,\n DEPTH_TEST: 0x0B71,\n BLEND: 0x0BE2,\n SRC_ALPHA: 0x0302,\n ONE_MINUS_SRC_ALPHA: 0x0303,\n TEXTURE_2D: 0x0DE1,\n RGBA: 0x1908,\n UNSIGNED_BYTE: 0x1401,\n COLOR_BUFFER_BIT: 0x4000,\n DEPTH_BUFFER_BIT: 0x0100,\n TRIANGLES: 0x0004,\n TRIANGLE_STRIP: 0x0005,\n TRIANGLE_FAN: 0x0006,\n\n // Methods\n createShader: () => ({}),\n shaderSource: () => {},\n compileShader: () => {},\n getShaderParameter: (_: any, param: number) => {\n if (param === 0x8B81) return true; // COMPILE_STATUS\n return true;\n },\n getShaderInfoLog: () => '',\n createProgram: () => ({}),\n attachShader: () => {},\n linkProgram: () => {},\n getProgramParameter: (_: any, param: number) => {\n if (param === 0x8B82) return true; // LINK_STATUS\n return true;\n },\n getProgramInfoLog: () => '',\n useProgram: () => {},\n createBuffer: () => ({}),\n bindBuffer: () => {},\n bufferData: () => {},\n enableVertexAttribArray: () => {},\n vertexAttribPointer: () => {},\n enable: () => {},\n disable: () => {},\n depthMask: () => {},\n blendFunc: () => {},\n viewport: () => {},\n clearColor: () => {},\n clear: () => {},\n createTexture: () => ({}),\n bindTexture: () => {},\n texImage2D: () => {},\n texParameteri: () => {},\n activeTexture: () => {},\n uniform1i: () => {},\n uniform1f: () => {},\n uniform2f: () => {},\n uniform3f: () => {},\n uniform4f: () => {},\n uniformMatrix4fv: () => {},\n getUniformLocation: () => ({}),\n getAttribLocation: () => 0,\n drawArrays: () => {},\n drawElements: () => {},\n createVertexArray: () => ({}),\n bindVertexArray: () => {},\n deleteShader: () => {},\n deleteProgram: () => {},\n deleteBuffer: () => {},\n deleteTexture: () => {},\n deleteVertexArray: () => {},\n\n // WebGL2 specific\n texImage3D: () => {},\n uniformBlockBinding: () => {},\n getExtension: () => null,\n } as unknown as WebGL2RenderingContext;\n\n return gl;\n}\n","import { Canvas, Image, ImageData } from '@napi-rs/canvas';\nimport { createMockWebGL2Context } from './webgl.js';\n\nexport interface DrawCall {\n method: string;\n args: any[];\n}\n\n/**\n * Creates a mock canvas element with WebGL2 support.\n */\nexport function createMockCanvas(width: number = 300, height: number = 150): HTMLCanvasElement {\n // If we are in JSDOM environment, use document.createElement\n if (typeof document !== 'undefined' && document.createElement) {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n\n // Otherwise use napi-rs/canvas directly\n const canvas = new Canvas(width, height);\n\n // Patch getContext to return mock WebGL2 context\n const originalGetContext = canvas.getContext.bind(canvas);\n canvas.getContext = function(contextId: string, options?: any) {\n if (contextId === 'webgl2') {\n return createMockWebGL2Context(canvas as unknown as HTMLCanvasElement);\n }\n if (contextId === '2d') {\n return originalGetContext('2d', options);\n }\n return originalGetContext(contextId as any, options);\n } as any;\n\n return canvas as unknown as HTMLCanvasElement;\n}\n\n/**\n * Creates a mock 2D rendering context.\n */\nexport function createMockCanvasContext2D(canvas?: HTMLCanvasElement): CanvasRenderingContext2D {\n if (!canvas) {\n canvas = createMockCanvas();\n }\n return canvas.getContext('2d') as unknown as CanvasRenderingContext2D;\n}\n\n/**\n * Spies on draw operations for verification.\n * Note: This modifies the context prototype or instance methods.\n */\nexport function captureCanvasDrawCalls(context: CanvasRenderingContext2D): DrawCall[] {\n const drawCalls: DrawCall[] = [];\n const methodsToSpy = [\n 'fillRect', 'strokeRect', 'clearRect',\n 'fillText', 'strokeText',\n 'drawImage',\n 'beginPath', 'closePath', 'moveTo', 'lineTo', 'arc', 'arcTo', 'bezierCurveTo', 'quadraticCurveTo',\n 'stroke', 'fill',\n 'putImageData'\n ];\n\n methodsToSpy.forEach(method => {\n // @ts-ignore\n const original = context[method];\n if (typeof original === 'function') {\n // @ts-ignore\n context[method] = function(...args: any[]) {\n drawCalls.push({ method, args });\n return original.apply(this, args);\n };\n }\n });\n\n return drawCalls;\n}\n\n/**\n * Creates a mock ImageData object.\n */\nexport function createMockImageData(width: number, height: number, fillColor?: [number, number, number, number]): ImageData {\n const imageData = new ImageData(width, height);\n if (fillColor) {\n const [r, g, b, a] = fillColor;\n for (let i = 0; i < imageData.data.length; i += 4) {\n imageData.data[i] = r;\n imageData.data[i + 1] = g;\n imageData.data[i + 2] = b;\n imageData.data[i + 3] = a;\n }\n }\n return imageData;\n}\n\n/**\n * Creates a mock Image element.\n */\nexport function createMockImage(width?: number, height?: number, src?: string): HTMLImageElement {\n const img = new Image();\n if (width) img.width = width;\n if (height) img.height = height;\n if (src) img.src = src;\n return img as unknown as HTMLImageElement;\n}\n","export interface NodeSetupOptions {\n polyfillFetch?: boolean;\n}\n\n/**\n * Sets up a Node.js environment for testing.\n * This is primarily for backend or shared logic that doesn't rely on browser APIs.\n */\nexport function setupNodeEnvironment(options: NodeSetupOptions = {}) {\n // Add any Node-specific global setup here\n // For now, this is a placeholder or can be used for things like\n // polyfilling fetch if not present in older Node versions (though Quake2TS targets recent Node)\n\n if (options.polyfillFetch && typeof global.fetch === 'undefined') {\n // In a real scenario, we might import node-fetch here\n // global.fetch = ...\n }\n}\n","\nimport 'fake-indexeddb/auto';\n\n/**\n * Creates a mock Storage implementation (localStorage/sessionStorage).\n */\nexport function createMockLocalStorage(initialData: Record<string, string> = {}): Storage {\n const storage = new Map<string, string>(Object.entries(initialData));\n\n return {\n getItem: (key: string) => storage.get(key) || null,\n setItem: (key: string, value: string) => storage.set(key, value),\n removeItem: (key: string) => storage.delete(key),\n clear: () => storage.clear(),\n key: (index: number) => Array.from(storage.keys())[index] || null,\n get length() { return storage.size; }\n } as Storage;\n}\n\n/**\n * Creates a mock SessionStorage implementation.\n * Functionally identical to LocalStorage mock but distinct for testing isolation.\n */\nexport function createMockSessionStorage(initialData: Record<string, string> = {}): Storage {\n return createMockLocalStorage(initialData);\n}\n\n/**\n * Creates a mock IndexedDB factory.\n * Currently relies on 'fake-indexeddb/auto' being imported which mocks the global indexedDB.\n * This helper ensures the global is available or resets it.\n */\nexport function createMockIndexedDB(): IDBFactory {\n if (typeof indexedDB === 'undefined') {\n throw new Error('IndexedDB mock not found. Ensure fake-indexeddb is loaded.');\n }\n // In a real mock scenario we might want to return a fresh instance,\n // but fake-indexeddb patches the global.\n return indexedDB;\n}\n\nexport interface StorageScenario {\n storage: Storage | IDBFactory;\n populate(data: Record<string, any>): Promise<void> | void;\n verify(key: string, value: any): Promise<boolean> | boolean;\n}\n\n/**\n * Helper to setup a storage test scenario.\n */\nexport function createStorageTestScenario(storageType: 'local' | 'session' | 'indexed' = 'local'): StorageScenario {\n if (storageType === 'indexed') {\n const dbName = `test-db-${Math.random().toString(36).substring(7)}`;\n const storeName = 'test-store';\n const storage = createMockIndexedDB();\n\n return {\n storage,\n populate: async (data: Record<string, any>) => {\n return new Promise((resolve, reject) => {\n const req = storage.open(dbName, 1);\n req.onupgradeneeded = (e: any) => {\n const db = e.target.result;\n db.createObjectStore(storeName);\n };\n req.onsuccess = (e: any) => {\n const db = e.target.result;\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n Object.entries(data).forEach(([k, v]) => store.put(v, k));\n tx.oncomplete = () => {\n db.close();\n resolve();\n };\n tx.onerror = () => reject(tx.error);\n };\n req.onerror = () => reject(req.error);\n });\n },\n verify: async (key: string, value: any) => {\n return new Promise((resolve, reject) => {\n const req = storage.open(dbName, 1);\n req.onsuccess = (e: any) => {\n const db = e.target.result;\n if (!db.objectStoreNames.contains(storeName)) {\n db.close();\n resolve(false);\n return;\n }\n const tx = db.transaction(storeName, 'readonly');\n const store = tx.objectStore(storeName);\n const getReq = store.get(key);\n getReq.onsuccess = () => {\n const result = getReq.result === value;\n db.close();\n resolve(result);\n };\n getReq.onerror = () => {\n db.close();\n resolve(false);\n };\n };\n req.onerror = () => reject(req.error);\n });\n }\n };\n }\n\n const storage = storageType === 'local' ? createMockLocalStorage() : createMockSessionStorage();\n\n return {\n storage,\n populate(data) {\n Object.entries(data).forEach(([k, v]) => storage.setItem(k, v));\n },\n verify(key, value) {\n return storage.getItem(key) === value;\n }\n };\n}\n","\n// Basic mock of AudioContext\nexport function createMockAudioContext(): AudioContext {\n const context = {\n createGain: () => ({\n connect: () => {},\n gain: { value: 1, setValueAtTime: () => {} }\n }),\n createOscillator: () => ({\n connect: () => {},\n start: () => {},\n stop: () => {},\n frequency: { value: 440 }\n }),\n createBufferSource: () => ({\n connect: () => {},\n start: () => {},\n stop: () => {},\n buffer: null,\n playbackRate: { value: 1 },\n loop: false\n }),\n destination: {},\n currentTime: 0,\n state: 'running',\n resume: async () => {},\n suspend: async () => {},\n close: async () => {},\n decodeAudioData: async (buffer: ArrayBuffer) => ({\n duration: 1,\n length: 44100,\n sampleRate: 44100,\n numberOfChannels: 2,\n getChannelData: () => new Float32Array(44100)\n }),\n createBuffer: (channels: number, length: number, sampleRate: number) => ({\n duration: length / sampleRate,\n length,\n sampleRate,\n numberOfChannels: channels,\n getChannelData: () => new Float32Array(length)\n }),\n // Helper to track events if needed\n _events: [] as AudioEvent[]\n };\n\n // Proxy to capture events\n return new Proxy(context as unknown as AudioContext, {\n get(target, prop, receiver) {\n if (prop === '_events') return (target as any)._events;\n const value = Reflect.get(target, prop, receiver);\n if (typeof value === 'function') {\n return (...args: any[]) => {\n (target as any)._events.push({ type: String(prop), args });\n return Reflect.apply(value, target, args);\n };\n }\n return value;\n }\n });\n}\n\n/**\n * Replaces the global AudioContext with a mock.\n */\nexport function setupMockAudioContext() {\n if (typeof global.AudioContext === 'undefined' && typeof global.window !== 'undefined') {\n // @ts-ignore\n global.AudioContext = class {\n constructor() {\n return createMockAudioContext();\n }\n };\n // @ts-ignore\n global.window.AudioContext = global.AudioContext;\n // @ts-ignore\n global.window.webkitAudioContext = global.AudioContext;\n }\n}\n\n/**\n * Restores the original AudioContext (if it was mocked).\n */\nexport function teardownMockAudioContext() {\n // If we mocked it on global, we might want to remove it.\n // However, usually in JSDOM it doesn't exist, so we just leave it or delete it.\n // @ts-ignore\n if (global.AudioContext && global.AudioContext.toString().includes('class')) {\n // @ts-ignore\n delete global.AudioContext;\n // @ts-ignore\n delete global.window.AudioContext;\n // @ts-ignore\n delete global.window.webkitAudioContext;\n }\n}\n\nexport interface AudioEvent {\n type: string;\n args: any[];\n}\n\n/**\n * Captures audio operations for verification.\n * Note: Only works if the context was created via createMockAudioContext which proxies calls.\n */\nexport function captureAudioEvents(context: AudioContext): AudioEvent[] {\n return (context as any)._events || [];\n}\n","\nexport interface MockRAF {\n tick(timestamp?: number): void;\n advance(deltaMs?: number): void;\n getCallbacks(): FrameRequestCallback[];\n reset(): void;\n enable(): void;\n disable(): void;\n}\n\nlet activeMockRAF: MockRAF | undefined;\n\n/**\n * Creates a mock implementation of requestAnimationFrame that allows manual control.\n * It replaces the global requestAnimationFrame and cancelAnimationFrame.\n */\nexport function createMockRAF(): MockRAF {\n let callbacks: { id: number; callback: FrameRequestCallback }[] = [];\n let nextId = 1;\n let currentTime = 0;\n\n const originalRAF = global.requestAnimationFrame;\n const originalCancelRAF = global.cancelAnimationFrame;\n\n const raf = (callback: FrameRequestCallback): number => {\n const id = nextId++;\n callbacks.push({ id, callback });\n return id;\n };\n\n const cancel = (id: number): void => {\n callbacks = callbacks.filter(cb => cb.id !== id);\n };\n\n const mock: MockRAF = {\n tick(timestamp?: number) {\n if (typeof timestamp !== 'number') {\n currentTime += 16.6; // Default to ~60fps\n } else {\n currentTime = timestamp;\n }\n\n const currentCallbacks = [...callbacks];\n callbacks = []; // Clear before execution so new RAFs go to next frame\n\n currentCallbacks.forEach(({ callback }) => {\n callback(currentTime);\n });\n },\n\n advance(deltaMs: number = 16.6) {\n this.tick(currentTime + deltaMs);\n },\n\n getCallbacks() {\n return callbacks.map(c => c.callback);\n },\n\n reset() {\n callbacks = [];\n nextId = 1;\n currentTime = 0;\n },\n\n enable() {\n activeMockRAF = this;\n global.requestAnimationFrame = raf as any;\n global.cancelAnimationFrame = cancel as any;\n },\n\n disable() {\n if (activeMockRAF === this) {\n activeMockRAF = undefined;\n }\n\n if (originalRAF) {\n global.requestAnimationFrame = originalRAF;\n } else {\n // @ts-ignore\n delete global.requestAnimationFrame;\n }\n\n if (originalCancelRAF) {\n global.cancelAnimationFrame = originalCancelRAF;\n } else {\n // @ts-ignore\n delete global.cancelAnimationFrame;\n }\n }\n };\n\n return mock;\n}\n\n/**\n * Creates a mock Performance object with controllable time.\n */\nexport function createMockPerformance(startTime: number = 0): Performance {\n let currentTime = startTime;\n\n const mockPerf = {\n now: () => currentTime,\n timeOrigin: startTime,\n timing: {\n navigationStart: startTime,\n },\n clearMarks: () => {},\n clearMeasures: () => {},\n clearResourceTimings: () => {},\n getEntries: () => [],\n getEntriesByName: () => [],\n getEntriesByType: () => [],\n mark: () => {},\n measure: () => {},\n setResourceTimingBufferSize: () => {},\n toJSON: () => ({}),\n addEventListener: () => {},\n removeEventListener: () => {},\n dispatchEvent: () => true,\n } as unknown as Performance;\n\n (mockPerf as any).advance = (deltaMs: number) => {\n currentTime += deltaMs;\n };\n (mockPerf as any).setTime = (time: number) => {\n currentTime = time;\n };\n\n return mockPerf;\n}\n\nexport interface ControlledTimer {\n tick(): void;\n advanceBy(ms: number): void;\n clear(): void;\n restore(): void;\n}\n\n/**\n * Creates a controlled timer that replaces global setTimeout/setInterval.\n * Allows deterministic time advancement.\n */\nexport function createControlledTimer(): ControlledTimer {\n let currentTime = 0;\n interface Timer {\n id: number;\n callback: Function;\n dueTime: number;\n interval?: number;\n args: any[];\n }\n let timers: Timer[] = [];\n let nextId = 1;\n\n const originalSetTimeout = global.setTimeout;\n const originalClearTimeout = global.clearTimeout;\n const originalSetInterval = global.setInterval;\n const originalClearInterval = global.clearInterval;\n\n const mockSetTimeout = (callback: Function, delay: number = 0, ...args: any[]) => {\n const id = nextId++;\n timers.push({ id, callback, dueTime: currentTime + delay, args });\n return id;\n };\n\n const mockClearTimeout = (id: any) => {\n timers = timers.filter(t => t.id !== id);\n };\n\n const mockSetInterval = (callback: Function, delay: number = 0, ...args: any[]) => {\n const id = nextId++;\n timers.push({ id, callback, dueTime: currentTime + delay, interval: delay, args });\n return id;\n };\n\n const mockClearInterval = (id: any) => {\n timers = timers.filter(t => t.id !== id);\n };\n\n global.setTimeout = mockSetTimeout as any;\n global.clearTimeout = mockClearTimeout as any;\n global.setInterval = mockSetInterval as any;\n global.clearInterval = mockClearInterval as any;\n\n return {\n tick() {\n this.advanceBy(0);\n },\n advanceBy(ms: number) {\n const targetTime = currentTime + ms;\n\n // Process timers until targetTime\n while (true) {\n // Find earliest timer\n let earliest: Timer | null = null;\n for (const t of timers) {\n if (!earliest || t.dueTime < earliest.dueTime) {\n earliest = t;\n }\n }\n\n if (!earliest || earliest.dueTime > targetTime) {\n break;\n }\n\n // Advance time to this timer\n currentTime = earliest.dueTime;\n\n // Execute\n const { callback, args, interval, id } = earliest;\n\n if (interval !== undefined) {\n earliest.dueTime += interval;\n // Prevent infinite loops with 0 interval\n if (interval === 0) earliest.dueTime += 1;\n } else {\n timers = timers.filter(t => t.id !== id);\n }\n\n callback(...args);\n }\n\n currentTime = targetTime;\n },\n clear() {\n timers = [];\n },\n restore() {\n global.setTimeout = originalSetTimeout;\n global.clearTimeout = originalClearTimeout;\n global.setInterval = originalSetInterval;\n global.clearInterval = originalClearInterval;\n }\n };\n}\n\n/**\n * Helper to simulate multiple frames of a game loop.\n * @param count Number of frames to simulate\n * @param frameTimeMs Time per frame in milliseconds\n * @param callback Optional callback to run inside the loop (e.g. triggering inputs)\n */\nexport function simulateFrames(count: number, frameTimeMs: number = 16.6, callback?: (frameIndex: number) => void) {\n if (!activeMockRAF) {\n throw new Error(\"simulateFrames requires an active MockRAF. Ensure createMockRAF().enable() is called.\");\n }\n\n for (let i = 0; i < count; i++) {\n if (callback) callback(i);\n activeMockRAF.advance(frameTimeMs);\n }\n}\n\n/**\n * Simulates frames using a provided MockRAF controller.\n */\nexport function simulateFramesWithMock(mock: MockRAF, count: number, frameTimeMs: number = 16.6, callback?: (frameIndex: number) => void) {\n for (let i = 0; i < count; i++) {\n if (callback) callback(i);\n mock.advance(frameTimeMs);\n }\n}\n","\nimport { chromium, Browser, Page, BrowserContext, BrowserContextOptions, LaunchOptions } from 'playwright';\nimport { createServer, IncomingMessage, ServerResponse, Server } from 'http';\nimport handler from 'serve-handler';\nimport path from 'path';\n\n/**\n * Interface for Test Client options\n */\nexport interface PlaywrightOptions {\n headless?: boolean;\n width?: number;\n height?: number;\n clientUrl?: string; // If provided, uses this URL. Otherwise starts a static server.\n serverUrl?: string; // Game server URL to connect to via query param\n rootPath?: string; // Root path for static server (defaults to process.cwd())\n launchOptions?: LaunchOptions;\n contextOptions?: BrowserContextOptions;\n}\n\nexport interface PlaywrightTestClient {\n browser: Browser;\n context: BrowserContext;\n page: Page;\n server?: Server; // HTTP server instance\n close: () => Promise<void>;\n navigate: (url?: string) => Promise<void>;\n waitForGame: (timeout?: number) => Promise<void>;\n injectInput: (type: string, data: any) => Promise<void>;\n}\n\n/**\n * Creates a Playwright-controlled browser environment for testing.\n * Can start a static server to serve the game client if no clientUrl is provided.\n */\nexport async function createPlaywrightTestClient(options: PlaywrightOptions = {}): Promise<PlaywrightTestClient> {\n let staticServer: Server | undefined;\n let clientUrl = options.clientUrl;\n const rootPath = options.rootPath || process.cwd();\n\n if (!clientUrl) {\n // Start a local static server\n staticServer = createServer((request: IncomingMessage, response: ServerResponse) => {\n return handler(request, response, {\n public: rootPath,\n cleanUrls: false,\n headers: [\n {\n source: '**/*',\n headers: [\n { key: 'Cache-Control', value: 'no-cache' },\n { key: 'Access-Control-Allow-Origin', value: '*' },\n { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },\n { key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' }\n ]\n }\n ]\n });\n });\n\n await new Promise<void>((resolve) => {\n if (!staticServer) return;\n staticServer.listen(0, () => {\n const addr = staticServer?.address();\n const port = typeof addr === 'object' ? addr?.port : 0;\n clientUrl = `http://localhost:${port}`;\n console.log(`Test client serving from ${rootPath} at ${clientUrl}`);\n resolve();\n });\n });\n }\n\n const browser = await chromium.launch({\n headless: options.headless ?? true,\n args: [\n '--use-gl=egl',\n '--ignore-gpu-blocklist',\n ...(options.launchOptions?.args || [])\n ],\n ...options.launchOptions\n });\n\n const width = options.width || 1280;\n const height = options.height || 720;\n\n const context = await browser.newContext({\n viewport: { width, height },\n deviceScaleFactor: 1,\n ...options.contextOptions\n });\n\n const page = await context.newPage();\n\n // Helper for closing\n const close = async () => {\n await browser.close();\n if (staticServer) {\n staticServer.close();\n }\n };\n\n const navigate = async (url?: string) => {\n const targetUrl = url || clientUrl;\n if (!targetUrl) throw new Error(\"No URL to navigate to\");\n\n let finalUrl = targetUrl;\n if (options.serverUrl && !targetUrl.includes('connect=')) {\n const separator = targetUrl.includes('?') ? '&' : '?';\n finalUrl = `${targetUrl}${separator}connect=${encodeURIComponent(options.serverUrl)}`;\n }\n\n console.log(`Navigating to: ${finalUrl}`);\n await page.goto(finalUrl, { waitUntil: 'domcontentloaded' });\n };\n\n return {\n browser,\n context,\n page,\n server: staticServer,\n close,\n navigate,\n waitForGame: async (timeout = 10000) => {\n await waitForGameReady(page, timeout);\n },\n injectInput: async (type, data) => {\n // Placeholder for input injection if we have a mechanism\n await page.evaluate(({type, data}) => {\n // @ts-ignore\n if (window.injectGameInput) window.injectGameInput(type, data);\n }, {type, data});\n }\n };\n}\n\nexport async function waitForGameReady(page: Page, timeout: number = 10000): Promise<void> {\n try {\n await page.waitForFunction(() => {\n // @ts-ignore\n return window.gameInstance && window.gameInstance.isReady; // Example check\n }, null, { timeout });\n } catch (e) {\n await page.waitForSelector('canvas', { timeout });\n }\n}\n\nexport interface GameStateCapture {\n [key: string]: any;\n}\n\nexport async function captureGameState(page: Page): Promise<GameStateCapture> {\n return await page.evaluate(() => {\n // @ts-ignore\n if (window.gameInstance && window.gameInstance.getState) {\n // @ts-ignore\n return window.gameInstance.getState();\n }\n return {};\n });\n}\n","\nexport interface NetworkSimulator {\n apply(page: any): Promise<void>;\n clear(page: any): Promise<void>;\n}\n\nexport type NetworkCondition = 'good' | 'slow' | 'unstable' | 'offline';\n\nexport interface NetworkConfig {\n offline: boolean;\n downloadThroughput: number; // bytes/sec\n uploadThroughput: number; // bytes/sec\n latency: number; // ms\n}\n\nconst CONDITIONS: Record<NetworkCondition, NetworkConfig> = {\n 'good': {\n offline: false,\n downloadThroughput: 10 * 1024 * 1024, // 10 Mbps\n uploadThroughput: 5 * 1024 * 1024, // 5 Mbps\n latency: 20\n },\n 'slow': {\n offline: false,\n downloadThroughput: 500 * 1024, // 500 Kbps\n uploadThroughput: 500 * 1024,\n latency: 400\n },\n 'unstable': {\n offline: false,\n downloadThroughput: 1 * 1024 * 1024,\n uploadThroughput: 1 * 1024 * 1024,\n latency: 100\n },\n 'offline': {\n offline: true,\n downloadThroughput: 0,\n uploadThroughput: 0,\n latency: 0\n }\n};\n\n/**\n * Simulates network conditions using Chrome DevTools Protocol (CDP) via Playwright.\n */\nexport function simulateNetworkCondition(condition: NetworkCondition): NetworkSimulator {\n const config = CONDITIONS[condition];\n return createCustomNetworkCondition(config.latency, 0, 0, config);\n}\n\n/**\n * Creates a custom network condition simulator.\n *\n * @param latency Latency in milliseconds\n * @param jitter Approximate jitter (variation in latency) - Note: CDP doesn't support jitter natively.\n * @param packetLoss Packet loss percentage (0-100) - Ignored for basic CDP emulation.\n */\nexport function createCustomNetworkCondition(\n latency: number,\n jitter: number = 0,\n packetLoss: number = 0,\n baseConfig?: NetworkConfig\n): NetworkSimulator {\n return {\n async apply(page: any) {\n const client = await page.context().newCDPSession(page);\n await client.send('Network.enable');\n await client.send('Network.emulateNetworkConditions', {\n offline: baseConfig?.offline || false,\n latency: latency + (Math.random() * jitter),\n downloadThroughput: baseConfig?.downloadThroughput || -1,\n uploadThroughput: baseConfig?.uploadThroughput || -1,\n });\n },\n async clear(page: any) {\n const client = await page.context().newCDPSession(page);\n await client.send('Network.emulateNetworkConditions', {\n offline: false,\n latency: 0,\n downloadThroughput: -1,\n uploadThroughput: -1,\n });\n }\n };\n}\n\n/**\n * Throttles bandwidth for the given page.\n */\nexport async function throttleBandwidth(page: any, bytesPerSecond: number) {\n const simulator = createCustomNetworkCondition(0, 0, 0, {\n offline: false,\n latency: 0,\n downloadThroughput: bytesPerSecond,\n uploadThroughput: bytesPerSecond\n });\n await simulator.apply(page);\n}\n","\nimport { Page } from 'playwright';\nimport path from 'path';\nimport fs from 'fs/promises';\n\nexport interface VisualDiff {\n pixelDiff: number;\n diffPath?: string;\n matched: boolean;\n}\n\n/**\n * Captures a screenshot of the current game state.\n */\nexport async function captureGameScreenshot(page: Page, name: string, options: { dir?: string, fullPage?: boolean } = {}): Promise<Buffer> {\n const dir = options.dir || '__screenshots__';\n const screenshotPath = path.join(dir, `${name}.png`);\n\n // Ensure directory exists\n await fs.mkdir(dir, { recursive: true });\n\n return await page.screenshot({\n path: screenshotPath,\n fullPage: options.fullPage ?? false,\n animations: 'disabled',\n caret: 'hide'\n });\n}\n\n/**\n * Compares two image buffers pixel-by-pixel.\n * Note: A robust implementation would use a library like 'pixelmatch' or 'looks-same'.\n * For now, we provide a basic placeholder or rely on simple buffer comparison.\n */\nexport async function compareScreenshots(baseline: Buffer, current: Buffer, threshold: number = 0.1): Promise<VisualDiff> {\n if (baseline.equals(current)) {\n return { pixelDiff: 0, matched: true };\n }\n\n return {\n pixelDiff: -1, // Unknown magnitude\n matched: false\n };\n}\n\nexport interface VisualScenario {\n capture(name: string): Promise<Buffer>;\n compare(name: string, baselineDir: string): Promise<VisualDiff>;\n}\n\n/**\n * Creates a helper for visual regression testing scenarios.\n */\nexport function createVisualTestScenario(page: Page, sceneName: string): VisualScenario {\n return {\n async capture(snapshotName: string) {\n return await captureGameScreenshot(page, `${sceneName}-${snapshotName}`);\n },\n async compare(snapshotName: string, baselineDir: string) {\n const name = `${sceneName}-${snapshotName}`;\n const current = await captureGameScreenshot(page, name, { dir: '__screenshots__/current' });\n\n try {\n const baselinePath = path.join(baselineDir, `${name}.png`);\n const baseline = await fs.readFile(baselinePath);\n return await compareScreenshots(baseline, current);\n } catch (e) {\n return { pixelDiff: -1, matched: false };\n }\n }\n };\n}\n"],"mappings":"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","names":["vi","vi","vi","ClientState","HandshakeStage","ClientState","ClientState","ClientState","options","canvas","Canvas","Image","ImageData","canvas","Canvas","ImageData","Image","storage","type","data"]}