From a2088b0ecb3e41e4c0d6f0ff33e76b5f90f1a570 Mon Sep 17 00:00:00 2001 From: Harper Date: Tue, 18 Aug 2026 14:56:12 +0200 Subject: [PATCH 01/15] feat(raid-survival): player animations and controller --- raid-survival/.dockerignore | 1 + raid-survival/.gitignore | 134 + raid-survival/.nanoforge/client.save.json | 77 + raid-survival/.nanoforge/server.save.json | 49 + raid-survival/.prettierignore | 8 + raid-survival/Dockerfile | 18 + raid-survival/README.md | 158 + .../client/components/player.component.ts | 13 + .../client/components/position.component.ts | 13 + .../client/components/renderable.component.ts | 23 + .../client/components/velocity.component.ts | 8 + raid-survival/client/main.ts | 63 + raid-survival/client/static/map.png | Bin 0 -> 69398 bytes .../client/static/player-animations.txt | 4 + raid-survival/client/static/player.png | Bin 0 -> 3460 bytes .../client/systems/movement.system.ts | 27 + .../client/systems/player-control.system.ts | 66 + raid-survival/client/systems/render.system.ts | 130 + raid-survival/eslint.config.js | 15 + raid-survival/nanoforge.config.json | 10 + raid-survival/package.json | 50 + raid-survival/pnpm-lock.yaml | 2600 +++++++++++++++++ raid-survival/pnpm-workspace.yaml | 3 + raid-survival/prettier.config.js | 6 + .../server/components/example.component.ts | 55 + raid-survival/server/main.ts | 33 + .../server/systems/example.system.ts | 31 + raid-survival/tsconfig.json | 41 + 28 files changed, 3636 insertions(+) create mode 100644 raid-survival/.dockerignore create mode 100644 raid-survival/.gitignore create mode 100644 raid-survival/.nanoforge/client.save.json create mode 100644 raid-survival/.nanoforge/server.save.json create mode 100644 raid-survival/.prettierignore create mode 100644 raid-survival/Dockerfile create mode 100644 raid-survival/README.md create mode 100644 raid-survival/client/components/player.component.ts create mode 100644 raid-survival/client/components/position.component.ts create mode 100644 raid-survival/client/components/renderable.component.ts create mode 100644 raid-survival/client/components/velocity.component.ts create mode 100644 raid-survival/client/main.ts create mode 100644 raid-survival/client/static/map.png create mode 100644 raid-survival/client/static/player-animations.txt create mode 100644 raid-survival/client/static/player.png create mode 100644 raid-survival/client/systems/movement.system.ts create mode 100644 raid-survival/client/systems/player-control.system.ts create mode 100644 raid-survival/client/systems/render.system.ts create mode 100644 raid-survival/eslint.config.js create mode 100644 raid-survival/nanoforge.config.json create mode 100644 raid-survival/package.json create mode 100644 raid-survival/pnpm-lock.yaml create mode 100644 raid-survival/pnpm-workspace.yaml create mode 100644 raid-survival/prettier.config.js create mode 100644 raid-survival/server/components/example.component.ts create mode 100644 raid-survival/server/main.ts create mode 100644 raid-survival/server/systems/example.system.ts create mode 100644 raid-survival/tsconfig.json diff --git a/raid-survival/.dockerignore b/raid-survival/.dockerignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/raid-survival/.dockerignore @@ -0,0 +1 @@ +node_modules/ diff --git a/raid-survival/.gitignore b/raid-survival/.gitignore new file mode 100644 index 0000000..ba6da87 --- /dev/null +++ b/raid-survival/.gitignore @@ -0,0 +1,134 @@ +### VisualStudioCode template +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### JetBrains template + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# File-based project format +*.iws + +# Editor-based Rest Client +.idea/httpRequests + +### Node template +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### NanoForge template +# Compilation directories +.nanoforge/client +.nanoforge/server diff --git a/raid-survival/.nanoforge/client.save.json b/raid-survival/.nanoforge/client.save.json new file mode 100644 index 0000000..a1b3e67 --- /dev/null +++ b/raid-survival/.nanoforge/client.save.json @@ -0,0 +1,77 @@ +{ + "libraries": [ + { + "id": "assetManagerLibrary", + "type": "asset-manager", + "name": "AssetManagerLibrary", + "path": "@nanoforge-dev/asset-manager", + "params": [] + }, + { + "id": "ecsLibrary", + "type": "component-system", + "name": "ECSClientLibrary", + "path": "@nanoforge-dev/ecs-client", + "params": [] + }, + { + "id": "graphicsLibrary", + "type": "graphics", + "name": "Graphics2DLibrary", + "path": "@nanoforge-dev/graphics-2d", + "params": [] + }, + { + "id": "inputLibrary", + "type": "input", + "name": "InputLibrary", + "path": "@nanoforge-dev/input", + "params": [] + }, + { + "id": "musicLibrary", + "type": "music", + "name": "MusicLibrary", + "path": "@nanoforge-dev/music", + "params": [] + }, + { + "id": "networkLibrary", + "type": "network", + "name": "NetworkClientLibrary", + "path": "@nanoforge-dev/network-client", + "params": [] + }, + { + "id": "soundLibrary", + "type": "sound", + "name": "SoundLibrary", + "path": "@nanoforge-dev/sound", + "params": [] + } + ], + "components": [ + { + "name": "ExampleComponent", + "path": "./components/example.component.ts", + "paramsNames": ["paramA", "paramB", "paramC"] + } + ], + "systems": [ + { + "name": "exampleSystem", + "path": "./systems/example.system.ts" + } + ], + "entities": [ + { + "id": "exampleEntity", + "components": { + "ExampleComponent": { + "paramA": "example", + "paramB": 10 + } + } + } + ] +} diff --git a/raid-survival/.nanoforge/server.save.json b/raid-survival/.nanoforge/server.save.json new file mode 100644 index 0000000..56f214b --- /dev/null +++ b/raid-survival/.nanoforge/server.save.json @@ -0,0 +1,49 @@ +{ + "libraries": [ + { + "id": "assetManagerLibrary", + "type": "asset-manager", + "name": "AssetManagerLibrary", + "path": "@nanoforge-dev/asset-manager", + "params": [] + }, + { + "id": "ecsLibrary", + "type": "component-system", + "name": "ECSServerLibrary", + "path": "@nanoforge-dev/ecs-server", + "params": [] + }, + { + "id": "networkLibrary", + "type": "network", + "name": "NetworkServerLibrary", + "path": "@nanoforge-dev/network-server", + "params": [] + } + ], + "components": [ + { + "name": "ExampleComponent", + "path": "./components/example.component.ts", + "paramsNames": ["paramA", "paramB", "paramC"] + } + ], + "systems": [ + { + "name": "exampleSystem", + "path": "./systems/example.system.ts" + } + ], + "entities": [ + { + "id": "exampleEntity", + "components": { + "ExampleComponent": { + "paramA": "example", + "paramB": 10 + } + } + } + ] +} diff --git a/raid-survival/.prettierignore b/raid-survival/.prettierignore new file mode 100644 index 0000000..2f0ede7 --- /dev/null +++ b/raid-survival/.prettierignore @@ -0,0 +1,8 @@ +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock +bun.lock + +/node_modules +/.nanoforge diff --git a/raid-survival/Dockerfile b/raid-survival/Dockerfile new file mode 100644 index 0000000..4c4cd10 --- /dev/null +++ b/raid-survival/Dockerfile @@ -0,0 +1,18 @@ +FROM node:25-slim + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN npm install -g pnpm + +WORKDIR /app + +COPY package.json ./ +COPY pnpm-lock.yaml ./ + +RUN pnpm install --frozen-lockfile --allow-build=bun + +COPY . . + +RUN pnpm run build + +CMD ["pnpm", "run", "start"] diff --git a/raid-survival/README.md b/raid-survival/README.md new file mode 100644 index 0000000..b1a3d4e --- /dev/null +++ b/raid-survival/README.md @@ -0,0 +1,158 @@ +# raid-survival + +--- + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ +- Package manager: **pnpm** +- [NanoForge CLI](https://www.npmjs.com/package/@nanoforge-dev/cli): `pnpm install -g @nanoforge-dev/cli` + +--- + +## Installation + +```bash +pnpm install +``` + +--- + +## Development + +Start the game in watch mode with hot reload: + +```bash +nf dev +``` + +--- + +## Project structure + +``` +raid-survival/ +├── .nanoforge/ # NanoForge internal save files (do not edit manually) +├── client/ # Client-side code (runs in the browser) +│ ├── static/ # Static assets +│ ├── components/ # ECS components +│ ├── systems/ # ECS systems +├── server/ # Server-side code +│ ├── static/ +│ ├── components/ +│ ├── systems/ +├── package.json +├── tsconfig.json +└── nanoforge.config.json # Game configuration +``` + +--- + +## Modifying the game + +### Add a component + +```bash +nf generate component --part client +``` + +A component is a plain class that holds data for an entity. Edit the generated file in `client/components/`: + +```ts +export class MyComponent { + constructor(public speed: number) {} +} + +export default MyComponent.name; +``` + +### Add a system + +```bash +nf generate system --part client +``` + +A system is a function that runs every tick and operates on entities that have specific components. Edit the generated file in `client/systems/`: + +```ts +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { MyComponent } from "../components/my.component"; + +export const mySystem = (registry: Registry, ctx: Context) => { + const entities = registry.getZipper([MyComponent]); + + entities.forEach((entity) => { + entity.MyComponent.speed += 1; + }); +}; + +export default mySystem.name; +``` + + +### Server-side code + +Server components and systems live in `server/` and are imported from `@nanoforge-dev/ecs-server`. They follow the same pattern as the client side. + +Configure the server connection in `.env`: + +| Variable | Default | Description | +|---------------------------------------|-------------|---------------------------------| +| `NANOFORGE_CLIENT_SERVER_ADDRESS` | `127.0.0.1` | Server address (client-side) | +| `NANOFORGE_CLIENT_SERVER_TCP_PORT` | `4444` | TCP port the client connects to | +| `NANOFORGE_CLIENT_SERVER_UDP_PORT` | `4445` | UDP port the client connects to | +| `NANOFORGE_SERVER_LISTENING_TCP_PORT` | `4444` | TCP port the server listens on | +| `NANOFORGE_SERVER_LISTENING_UDP_PORT` | `4445` | UDP port the server listens on | + +--- + +## Build + +Compile the game for production: + +```bash +pnpm run build +# or +nf build +``` + +Output is written to the `.nanoforge/` directory. + +--- + +## Run + +Start the game server and open it in a browser: + +```bash +pnpm run start +# or +nf start +``` + +--- + +## Code quality + +```bash +# Check formatting and linting +pnpm run lint + +# Auto-fix formatting and linting +pnpm run format +``` + +--- + +## CLI reference + +| Command | Description | +|--------------------------------|-------------------------------------------| +| `nf dev` | Start in development mode with hot reload | +| `nf build` | Build for production | +| `nf start` | Run the built game | +| `nf generate component ` | Scaffold a new component | +| `nf generate system ` | Scaffold a new system | + +Full CLI documentation: diff --git a/raid-survival/client/components/player.component.ts b/raid-survival/client/components/player.component.ts new file mode 100644 index 0000000..3b8dc04 --- /dev/null +++ b/raid-survival/client/components/player.component.ts @@ -0,0 +1,13 @@ +import { Vector2d } from "@nanoforge-dev/graphics-2d"; + +export class PlayerComponent { + name = this.constructor.name; + target: Vector2d = {x: 0, y: 0}; +} + +export class LocalPlayerComponent { + name = this.constructor.name; +} + +// * Required to generate code +export default PlayerComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/position.component.ts b/raid-survival/client/components/position.component.ts new file mode 100644 index 0000000..26859d5 --- /dev/null +++ b/raid-survival/client/components/position.component.ts @@ -0,0 +1,13 @@ +export class PositionComponent { + name = this.constructor.name; + x: number = 0; + y: number = 0; + + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } +} + +// * Required to generate code +export default PositionComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/renderable.component.ts b/raid-survival/client/components/renderable.component.ts new file mode 100644 index 0000000..59b24b0 --- /dev/null +++ b/raid-survival/client/components/renderable.component.ts @@ -0,0 +1,23 @@ +import { Sprite, Vector2d } from "@nanoforge-dev/graphics-2d"; + +interface RenderableComponentOptions { + animationsKey?: string; + scale?: Vector2d; +} + +export class RenderableComponent { + name = this.constructor.name; + spriteKey: string; + animationsKey?: string; + sprite: Sprite | undefined; + scale: Vector2d = { x: 1, y: 1 }; + + constructor(spriteKey: string, options?: RenderableComponentOptions) { + this.spriteKey = spriteKey; + if (options?.animationsKey) this.animationsKey = options.animationsKey; + if (options?.scale) this.scale = options.scale; + } +} + +// * Required to generate code +export default RenderableComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/velocity.component.ts b/raid-survival/client/components/velocity.component.ts new file mode 100644 index 0000000..f2a3202 --- /dev/null +++ b/raid-survival/client/components/velocity.component.ts @@ -0,0 +1,8 @@ +export class VelocityComponent { + name = this.constructor.name; + x = 0; + y = 0; +} + +// * Required to generate code +export default VelocityComponent.name; diff --git a/raid-survival/client/main.ts b/raid-survival/client/main.ts new file mode 100644 index 0000000..afae6df --- /dev/null +++ b/raid-survival/client/main.ts @@ -0,0 +1,63 @@ +import { type IRunOptions } from "@nanoforge-dev/common"; +import { NanoforgeFactory } from "@nanoforge-dev/core"; + +import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; +import { ECSClientLibrary } from "@nanoforge-dev/ecs-client"; +import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d"; +import { InputLibrary } from "@nanoforge-dev/input"; +import { MusicLibrary } from "@nanoforge-dev/music"; +import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; +import { SoundLibrary } from "@nanoforge-dev/sound"; +import { movementSystem } from "./systems/movement.system"; +import { playerAnimationSystem, playerControlSystem } from "./systems/player-control.system"; +import { renderSystem } from "./systems/render.system"; +import { LocalPlayerComponent, PlayerComponent } from "./components/player.component"; +import { RenderableComponent } from "./components/renderable.component"; +import { PositionComponent } from "./components/position.component"; +import { VelocityComponent } from "./components/velocity.component"; + +export async function main(options: IRunOptions) { + const app = NanoforgeFactory.createClient(); + + const assetManagerLibrary = new AssetManagerLibrary(); + const ecsLibrary = new ECSClientLibrary(); + const graphicsLibrary = new Graphics2DLibrary(); + const inputLibrary = new InputLibrary(); + const musicLibrary = new MusicLibrary(); + const networkLibrary = new NetworkClientLibrary(); + const soundLibrary = new SoundLibrary(); + + app.useAssetManager(assetManagerLibrary); + app.useComponentSystem(ecsLibrary); + app.useGraphics(graphicsLibrary); + app.useInput(inputLibrary); + app.use(Symbol("music"), musicLibrary); + app.useNetwork(networkLibrary); + app.useSound(soundLibrary); + + await app.init(options); + + const canvas = graphicsLibrary.baseLayer.getCanvas()._canvas; + const canva2D = canvas.getContext("2d"); + if (canva2D) canva2D.imageSmoothingEnabled = false; + + const registry = ecsLibrary.registry; + + const background = registry.spawnEntity(); + registry.addComponent(background, new PositionComponent(0, 0)); + registry.addComponent(background, new RenderableComponent("map.png")); + + const player = registry.spawnEntity(); + registry.addComponent(player, new PlayerComponent()); + registry.addComponent(player, new LocalPlayerComponent()); + registry.addComponent(player, new RenderableComponent("player.png", {animationsKey: "player-animations.txt", scale: {x: 3, y: 3}})); + registry.addComponent(player, new PositionComponent(100, 100)); + registry.addComponent(player, new VelocityComponent()); + + registry.addSystem(movementSystem); + registry.addSystem(playerControlSystem); + registry.addSystem(renderSystem); + registry.addSystem(playerAnimationSystem); + + await app.run(); +} diff --git a/raid-survival/client/static/map.png b/raid-survival/client/static/map.png new file mode 100644 index 0000000000000000000000000000000000000000..930151b3404c5fd8fb6f3abab1e9d4ece058524a GIT binary patch literal 69398 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 { + const entities: { PositionComponent: PositionComponent; VelocityComponent: VelocityComponent }[] = + registry.getZipper([PositionComponent, VelocityComponent]); + + const dt = ctx.app.delta / 1000; + + for (const entity of entities) { + entity.PositionComponent.x += entity.VelocityComponent.x * dt; + entity.PositionComponent.y += entity.VelocityComponent.y * dt; + } +}; + +// * Required to generate code +export default movementSystem.name; + +// * Required for the editor to display the system and generate code +export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = { + name: "movement", + description: + "This system end the game when paramB reaches 0 for any entity with ExampleComponent", + dependencies: ["ExampleComponent"], +}; diff --git a/raid-survival/client/systems/player-control.system.ts b/raid-survival/client/systems/player-control.system.ts new file mode 100644 index 0000000..7c03a5e --- /dev/null +++ b/raid-survival/client/systems/player-control.system.ts @@ -0,0 +1,66 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { LocalPlayerComponent, PlayerComponent } from "../components/player.component"; +import { VelocityComponent } from "../components/velocity.component"; +import { InputEnum, InputLibrary } from "@nanoforge-dev/input"; +import { RenderableComponent } from "../components/renderable.component"; +import { PositionComponent } from "../components/position.component"; + +const SPEED = 200; + +export const playerControlSystem = (registry: Registry, ctx: Context) => { + const entities: { + LocalPlayerComponent: LocalPlayerComponent; + PlayerComponent: PlayerComponent; + VelocityComponent: VelocityComponent; + }[] = registry.getZipper([LocalPlayerComponent, PlayerComponent, VelocityComponent]); + const input = ctx.libs.getInput() + + for (const entity of entities) { + let dx = 0; + let dy = 0; + + if (input.isKeyPressed(InputEnum.KeyZ) || input.isKeyPressed(InputEnum.ArrowUp)) dy -= 1; + if (input.isKeyPressed(InputEnum.KeyS) || input.isKeyPressed(InputEnum.ArrowDown)) dy += 1; + if (input.isKeyPressed(InputEnum.KeyQ) || input.isKeyPressed(InputEnum.ArrowLeft)) dx -= 1; + if (input.isKeyPressed(InputEnum.KeyD) || input.isKeyPressed(InputEnum.ArrowRight)) dx += 1; + + const len = Math.hypot(dx, dy) || 1; + entity.VelocityComponent.x = (dx / len) * SPEED; + entity.VelocityComponent.y = (dy / len) * SPEED; + + if (entity.PlayerComponent) entity.PlayerComponent.target = input.getMousePosition(); + } +}; + +export const playerAnimationSystem = (registry: Registry) => { + const entities: { + PlayerComponent: PlayerComponent; + RenderableComponent: RenderableComponent; + VelocityComponent: VelocityComponent; + PositionComponent: PositionComponent; + }[] = registry.getZipper([ + PlayerComponent, + RenderableComponent, + VelocityComponent, + PositionComponent, + ]); + + for (const entity of entities) { + if (!entity.RenderableComponent.sprite) continue; + if (entity.VelocityComponent.y != 0 || entity.VelocityComponent.x != 0) { + entity.RenderableComponent.sprite.animation("walk"); + } else { + entity.RenderableComponent.sprite.animation("idle"); + } + + if (entity.PlayerComponent.target.x < entity.PositionComponent.x) { + entity.RenderableComponent.sprite.scaleX(-3); + } else { + entity.RenderableComponent.sprite.scaleX(3); + } + } +} + +// * Required to generate code +export default playerControlSystem.name; diff --git a/raid-survival/client/systems/render.system.ts b/raid-survival/client/systems/render.system.ts new file mode 100644 index 0000000..b68de7f --- /dev/null +++ b/raid-survival/client/systems/render.system.ts @@ -0,0 +1,130 @@ +import { type Context, NfFile } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; + +import { Graphics2DLibrary, Sprite } from "@nanoforge-dev/graphics-2d"; +import { PositionComponent } from "../components/position.component"; +import { RenderableComponent } from "../components/renderable.component"; +import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; + +type Animations = Record; + +const imageCache = new Map(); +const imageLoading = new Map>(); + +function loadImage(path: string): Promise { + if (imageCache.has(path)) return Promise.resolve(imageCache.get(path)); + if (imageLoading.has(path)) return Promise.resolve(imageLoading.get(path)); + + const promise = new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => { + imageCache.set(path, image); + resolve(image); + }; + image.onerror = reject; + image.src = path; + }); + + imageLoading.set(path, promise); + return promise; +} + +const animationsCache = new Map(); +const animationsLoading = new Map>(); + +function loadAnimations(file: NfFile): Promise { + if (animationsCache.has(file.path)) return Promise.resolve(animationsCache.get(file.path)); + if (animationsLoading.has(file.path)) return Promise.resolve(animationsLoading.get(file.path)); + + const promise = file.text().then((raw) => { + const result: Animations = {}; + + raw + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.length > 0) + .forEach((line) => { + const [name, framesStr] = line.split(":").map((s) => s.trim()); + if (!name || !framesStr) throw new Error(`${name} failed to parse animations`); + + const frames = framesStr + .split(" ") + .filter((f) => f.length > 0) + .flatMap((frame) => frame.split(",").map(Number)); + + result[name] = frames; + }); + + animationsCache.set(file.path, result); + return result; + }); + + animationsLoading.set(file.path, promise); + return promise; +} + + +const spriteCache = new Map(); +const pendingIds = new Set(); + +export const renderSystem = async (registry: Registry, ctx: Context) => { + const entities = registry.getIndexedZipper([PositionComponent, RenderableComponent]); + const graphics = ctx.libs.getGraphics(); + const assetManager = ctx.libs.getAssetManager(); + const seenIds = new Set(); + + for (const entity of entities) { + seenIds.add(entity.id); + const sprite = spriteCache.get(entity.id); + + if (!sprite && !pendingIds.has(entity.id)) { + pendingIds.add(entity.id); + + const imageFile = assetManager.getAsset(entity.RenderableComponent.spriteKey); + const animationsFile = assetManager.getAsset(entity.RenderableComponent.animationsKey); + + const image = await loadImage(imageFile.path); + if (!image) continue; + const animations = animationsFile + ? await loadAnimations(animationsFile) + : { + idle: [0, 0, image.width, image.height], + }; + + pendingIds.delete(entity.id); + + + const newSprite = new Sprite({ + x: entity.PositionComponent.x, + y: entity.PositionComponent.y, + image, + animation: "idle", + animations, + frameRate: 7, + scale: { x: entity.RenderableComponent.scale.x, y: entity.RenderableComponent.scale.y }, + }); + + newSprite.offsetX(newSprite.width() / 2); + + entity.RenderableComponent.sprite = newSprite; + + newSprite.start(); + graphics.baseLayer.add(newSprite); + spriteCache.set(entity.id, newSprite); + } + + sprite?.position({ x: entity.PositionComponent.x, y: entity.PositionComponent.y }); + } + + for (const [id, sprite] of spriteCache) { + if (!seenIds.has(id)) { + sprite.destroy(); + spriteCache.delete(id); + } + } + + graphics.baseLayer.batchDraw(); +}; + +// * Required to generate code +export default renderSystem.name; diff --git a/raid-survival/eslint.config.js b/raid-survival/eslint.config.js new file mode 100644 index 0000000..2f3639d --- /dev/null +++ b/raid-survival/eslint.config.js @@ -0,0 +1,15 @@ +import pluginJs from "@eslint/js"; +import eslintConfigPrettier from "eslint-config-prettier"; +import globals from "globals"; +import tseslint from "typescript-eslint"; + +export default [ + { files: ["{client,server}/**/*.{ts}"] }, + { languageOptions: { globals: globals.node } }, + + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + ...tseslint.configs.strict, + eslintConfigPrettier, + { ignores: ["**/*.js", "**/*.d.ts"] }, +]; diff --git a/raid-survival/nanoforge.config.json b/raid-survival/nanoforge.config.json new file mode 100644 index 0000000..6923dda --- /dev/null +++ b/raid-survival/nanoforge.config.json @@ -0,0 +1,10 @@ +{ + "name": "raid-survival", + "language": "ts", + "client": { + "enable": true + }, + "server": { + "enable": true + } +} \ No newline at end of file diff --git a/raid-survival/package.json b/raid-survival/package.json new file mode 100644 index 0000000..3f45b4b --- /dev/null +++ b/raid-survival/package.json @@ -0,0 +1,50 @@ +{ + "name": "raid-survival", + "version": "0.0.0", + "description": "", + "author": "", + "scripts": { + "build": "nf build", + "start": "nf start", + "lint": "prettier --check . && eslint --format=pretty \"{client,server}/**/*.ts\"", + "format": "prettier --write . && eslint --fix --format=pretty \"{client,server}/**/*.ts\"" + }, + "devDependencies": { + "@eslint/js": "^9.39.0", + "@nanoforge-dev/asset-manager": "^1", + "@nanoforge-dev/cli": "latest", + "@nanoforge-dev/common": "^1", + "@nanoforge-dev/config": "^1", + "@nanoforge-dev/core": "^1", + "@nanoforge-dev/ecs-client": "^1", + "@nanoforge-dev/ecs-server": "^1", + "@nanoforge-dev/graphics-2d": "^1", + "@nanoforge-dev/input": "^1", + "@nanoforge-dev/music": "^1", + "@nanoforge-dev/network-client": "^1", + "@nanoforge-dev/network-server": "^1", + "@nanoforge-dev/sound": "^1", + "@typescript-eslint/eslint-plugin": "^8.46.2", + "@typescript-eslint/parser": "^8.46.2", + "eslint": "^9.39.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.4", + "globals": "^16.5.0", + "lint-staged": "^16.2.6", + "prettier": "^3.6.2", + "typescript": "^5.9.3", + "typescript-eslint": "^8.46.2" + }, + "lint-staged": { + "**/*.ts": [ + "prettier --write" + ], + "{client,server}/**/*.ts": [ + "eslint --fix" + ] + }, + "pnpm": { + "neverBuiltDependencies": [] + }, + "private": true +} diff --git a/raid-survival/pnpm-lock.yaml b/raid-survival/pnpm-lock.yaml new file mode 100644 index 0000000..6536612 --- /dev/null +++ b/raid-survival/pnpm-lock.yaml @@ -0,0 +1,2600 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@eslint/js': + specifier: ^9.39.0 + version: 9.39.5 + '@nanoforge-dev/asset-manager': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/cli': + specifier: latest + version: 1.6.2 + '@nanoforge-dev/common': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/config': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/core': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/ecs-client': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/ecs-server': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/graphics-2d': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/input': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/music': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/network-client': + specifier: ^1 + version: 1.4.2 + '@nanoforge-dev/network-server': + specifier: ^1 + version: 1.4.2(supports-color@7.2.0) + '@nanoforge-dev/sound': + specifier: ^1 + version: 1.4.2 + '@typescript-eslint/eslint-plugin': + specifier: ^8.46.2 + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.46.2 + version: 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + eslint: + specifier: ^9.39.0 + version: 9.39.5(supports-color@7.2.0) + eslint-config-prettier: + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.5(supports-color@7.2.0)) + eslint-plugin-prettier: + specifier: ^5.5.4 + version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(supports-color@7.2.0)))(eslint@9.39.5(supports-color@7.2.0))(prettier@3.9.6) + globals: + specifier: ^16.5.0 + version: 16.5.0 + lint-staged: + specifier: ^16.2.6 + version: 16.4.0 + prettier: + specifier: ^3.6.2 + version: 3.9.6 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.46.2 + version: 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + +packages: + + '@angular-devkit/core@22.1.4': + resolution: {integrity: sha512-40jG/6chng9fQuWtpg1kadPO17sRTurNh0aav6Uxebn65PfNpTpvhPIYVIcRgv4tCKdMd++YH95A8SiaIOwqig==} + engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^5.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/schematics-cli@22.1.4': + resolution: {integrity: sha512-xcerOAJ2knWBvzliwPjAgbZ15vZ8OZHziv01LolOgKqRVMBu80Ijj8jEcdlj++CXbxPD/X3Hi1OFKuNHVmHwFA==} + engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true + + '@angular-devkit/schematics@22.1.4': + resolution: {integrity: sha512-UBJ7jc7B0vRfmrVwlvpmuudo1D7AfpO6ugf1BxvkM4sw5m8cJpZtaIJFKBorv0QZo78CyDOroQfQdXaijjB2ZA==} + engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.6': + resolution: {integrity: sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.5': + resolution: {integrity: sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@inquirer/ansi@2.0.7': + resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + + '@inquirer/checkbox@5.2.1': + resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@6.1.1': + resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@11.2.1': + resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/editor@5.2.2': + resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/expand@5.1.1': + resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/external-editor@3.0.3': + resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@2.0.7': + resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + + '@inquirer/input@5.1.2': + resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/number@4.1.1': + resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/password@5.1.1': + resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@8.5.2': + resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/rawlist@5.3.1': + resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/search@4.2.1': + resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@5.2.1': + resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/type@4.0.7': + resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@mapbox/node-pre-gyp@2.0.3': + resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} + engines: {node: '>=18'} + hasBin: true + + '@nanoforge-dev/asset-manager@1.4.2': + resolution: {integrity: sha512-CtUoNc5tc2QVdEs6nDER2WutBArS72RFod+cM+fwwrq+1btNeI7ed4sjbxqCBJLASqvZ7HQ3av6P8FGpfjRI6g==} + engines: {node: '25'} + + '@nanoforge-dev/cli@1.6.2': + resolution: {integrity: sha512-BtjWOu6cX7A3sk256cCNA+wyem9oobzhfjg4/7tNt/zN1vLYTb5is3s+D5IRRG6M1ZovW0W1InN53ss5boBxVQ==} + engines: {node: '25'} + hasBin: true + + '@nanoforge-dev/common@1.4.2': + resolution: {integrity: sha512-Km7eTwmpQ0XTx5o15Cu05ojRCL8px/DANVc0eYBLzKnG2/LamKs5P/e3HG+woULPz0/fc+ah/RPKyQwFtx5lBw==} + engines: {node: '25'} + + '@nanoforge-dev/config@1.4.2': + resolution: {integrity: sha512-SdV/nINKC5VQyvKZs6s6T+vlsSfKE47lhYgcacWqSBdi9BTDSTj6GNZRoWpwSMyiKCZ+Wj6DbmyJvPXDc/wTgA==} + engines: {node: '25'} + + '@nanoforge-dev/core@1.4.2': + resolution: {integrity: sha512-Ja7zNj78f/gMipBR7n+4u7Xb/UOZZzPMt55jb/mEj7g+0Qloq66cPwT1lHhx+8owi+lOncJ1bjIu2QUzThHvqg==} + engines: {node: '25'} + + '@nanoforge-dev/ecs-client@1.4.2': + resolution: {integrity: sha512-toeySsQfH0VMsA1UKUrhRWACYj7g7ikru8SqMf5e4LdacQAOkIenMRDyuyo52OVq1fJs1e47jM4XBkX6wGghQA==} + engines: {node: '25'} + + '@nanoforge-dev/ecs-lib@1.4.2': + resolution: {integrity: sha512-FM7lhHvBWvsaZs03biagHAu3P2Hlw1hoEye2b3xjj3EeVbRE8r8CNFcYtCoSbM2cVFKZBr3Z0N0UJBXLnizkgw==} + engines: {node: '25'} + + '@nanoforge-dev/ecs-server@1.4.2': + resolution: {integrity: sha512-P1DCfOe2ke1iL1HvDs2kiz4RYf7NBLYV5Vbkk8jWJlgYrzRS8Lif/xRgPLE4Wjv5uASrMbTCB/M9EI+3cqRvsQ==} + engines: {node: '25'} + + '@nanoforge-dev/editor@0.1.4': + resolution: {integrity: sha512-bqbrH8ulFSiZz1iisJHtHeEzj1RV/70uErCYHeW4DIhVPsWbBfWKFvg/ghAbmPk5vsj0YnhDX6DSpik4S1QoiQ==} + engines: {node: '25'} + + '@nanoforge-dev/graphics-2d@1.4.2': + resolution: {integrity: sha512-wH275hs9nl48HVI8GN5UjUIupylJ9Q9dJAxA8MCxKvgkEUcKwtC2gYXIjxaf5b2CoqG1O+qipnHzpnrAQCqrgA==} + engines: {node: '25'} + + '@nanoforge-dev/input@1.4.2': + resolution: {integrity: sha512-U38Eo1anJe9Fehzq4iQ/xIpDWnoWxXVLkAZ5CPf/k4iKLNm0scUg5LHZ8TswGEoaBtJmwFeiIGWU6OHfYYHcJw==} + engines: {node: '25'} + + '@nanoforge-dev/loader-client@1.4.0': + resolution: {integrity: sha512-YYE41uqp/7+IXRXLi71UuWFBUXf8ZguMf32A/8qzCmbQN+gUtBdTKLwm+2VVcvih6mueCQCGnulH9t5SmC8+Qg==} + engines: {node: '25'} + + '@nanoforge-dev/loader-server@1.4.0': + resolution: {integrity: sha512-jvNoHxx54BAfjUTMZHb/T/8ApbdPV/NNGwiQITUBprH4Uv8jQmbR7zNB5Z6/vIEjSVVxrU0b4fFa+BkdnKX/iQ==} + engines: {node: '25'} + + '@nanoforge-dev/loader-website@1.4.0': + resolution: {integrity: sha512-+5el/zkSJQL9qCd+4a6fGpIDMQi26QRTWXJ24mJFMaDC74P1lvqnes0u0l0+/s9dunJxfgea0Epse0/Jj/3M3Q==} + engines: {node: '25'} + + '@nanoforge-dev/music@1.4.2': + resolution: {integrity: sha512-m0UPkq5SKrjmGpPtGfSRsnEUzczBVubWEmniUD/TbKkKtFgJ/GgHxDwgH4B0LlBdHiCQJPHa8F1eJlnOd3lMsg==} + engines: {node: '25'} + + '@nanoforge-dev/network-client@1.4.2': + resolution: {integrity: sha512-qV56qAjUHDakgBqq9eSvKE9/657rEr3OCP/84kylbsy0TXLGZ/jywUTnvR/9woIVkrUOzdMf2okZzFKfSf28lw==} + engines: {node: '25'} + + '@nanoforge-dev/network-server@1.4.2': + resolution: {integrity: sha512-5pOQ5VuQCof1oSlmgqO0BCs4ScRDk79FFhssUL7rky/sdkyzLKYdqG0UNP6uc8WiJ7E+l8bd7dY2fOgWeLhR3w==} + engines: {node: '25'} + + '@nanoforge-dev/schematics@2.2.1': + resolution: {integrity: sha512-MdmhFncakgejGRIf1HTPKTskhdv8bIst21uWRSZCXGgGv0UNYEfDiziOsWPVCzGc9dXei59RIDznBwgpAMeXLg==} + engines: {node: '25'} + + '@nanoforge-dev/sound@1.4.2': + resolution: {integrity: sha512-1qZdYGeJPwAfZYj3PAIdv/y0+P9NtkVw0J9mrpmLcOyQ7DKKoYzlTPGQkpJzErE0y3epHooFcLBY8jRZegH3dg==} + engines: {node: '25'} + + '@oven/bun-darwin-aarch64@1.3.14': + resolution: {integrity: sha512-Omj20SuiHBOUjUBIyqtkNjSUIjOtEOJwmbix/ZyFH4BaQ6OZTaaRWIR4TjHVz0yadHgli6lLTiAh1uarnvD49A==} + cpu: [arm64] + os: [darwin] + + '@oven/bun-darwin-x64-baseline@1.3.14': + resolution: {integrity: sha512-OSfsTZstc898HHElhU4NccaBGOSSDn5VfahiVTnidZ9B/+wb7WTyfZJaBeJcfjwJ9H2W9uTh2TGtl3UfcXgV9g==} + cpu: [x64] + os: [darwin] + + '@oven/bun-darwin-x64@1.3.14': + resolution: {integrity: sha512-FFj3QdU/OhlDyZOJ8CWfN5eWLpRlT4qjZg7lMQi7jA6GuoY5ajlO1zWLP/MuHYRSbXQUvV52RejNi8DVnAp13w==} + cpu: [x64] + os: [darwin] + + '@oven/bun-freebsd-aarch64@1.3.14': + resolution: {integrity: sha512-LIKrXaFxAHybVO5Pf+9XP2FHUj/5APvXTUKk9dqHm5iFz4oH+W24cmhjkJirNujh9hKeTyrpWSe3no9JZKowIw==} + cpu: [arm64] + os: [freebsd] + + '@oven/bun-freebsd-x64@1.3.14': + resolution: {integrity: sha512-uwD+fGUH1ADpIF3B1U2jWzzb20QwRLZfj5QZ28GUCGrAJ/nTmWrD6YYGsblCY1wuhldRez3lU40AyuvSCyLYmw==} + cpu: [x64] + os: [freebsd] + + '@oven/bun-linux-aarch64-android@1.3.14': + resolution: {integrity: sha512-y4kq5b85lsrmFb9Xvi4w9mA5IEFJkLMrSmYn06q24KjL9rUWDWO3VFZEtteZxUN5+ec3Zm5S8OnJw1umaCbVjA==} + cpu: [arm64] + os: [android] + + '@oven/bun-linux-aarch64-musl@1.3.14': + resolution: {integrity: sha512-jmqOA92Cd1NL/1XBd4bFkJLxQ86K0RW7ohxS2qzzAvuitO4JiIxjjTeCspoU44zCozH72HpfZfUE2On31OjnWA==} + cpu: [arm64] + os: [linux] + + '@oven/bun-linux-aarch64@1.3.14': + resolution: {integrity: sha512-X5SsPZHs+iYO8R/efIcRtc7gT2Q2DgPfliCxEkx4cXBumwkw0c/EsHMNwH3EgGpCDaZ7IYVPhpCG/xBOQHEwZw==} + cpu: [arm64] + os: [linux] + + '@oven/bun-linux-x64-android@1.3.14': + resolution: {integrity: sha512-qe9e1d+3VAEU7nAA2ol9Jvmy/o99PVMSgZhHn7Q/9O3YcDrfEqyQ8zm4zoe5qTEo8HZH0dN03Le0Ys2eQPs7eg==} + cpu: [x64] + os: [android] + + '@oven/bun-linux-x64-baseline@1.3.14': + resolution: {integrity: sha512-q/8EdOC0yUE8FPeoOVq8/Pw5I9/tJaYmUfO/uDUAREx8IUnOJH1RJ5A3BjFqre8pvJoiZA9AovPJq5FnNNjSxA==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64-musl-baseline@1.3.14': + resolution: {integrity: sha512-n6iE71G4lQE4XkrZhQQcL5YUlxDbnq6nqV7zeQi33PMsLT/0kYE+RvHOtBWZ3w0wMdXZfINmp63hIb9ijUBGtw==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64-musl@1.3.14': + resolution: {integrity: sha512-GBCB/k/sIqcr06eTNgg7g46qiUv35Jasx4XiccJ/n7RGqrE4RWUD/XJBbWFprVPjvqd59+QtSnS99XGqvftHfg==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64@1.3.14': + resolution: {integrity: sha512-7OVTAKvwfPmSbIV1HpdOoVVx5VRc427GuPPne93N6vk4eQBPId9nXmZDh9/zGaKPdbVjVtQSZafWQoUjx38Utw==} + cpu: [x64] + os: [linux] + + '@oven/bun-windows-aarch64@1.3.14': + resolution: {integrity: sha512-T7s3x/BsVKQObGU6QDkZeI6wKynzqGbBH1yI77jrrj5siElclxr3DQrDIk8CV4G5/SJq2HHq4kpLyYY2DKCSmA==} + cpu: [arm64] + os: [win32] + + '@oven/bun-windows-x64-baseline@1.3.14': + resolution: {integrity: sha512-uIjLUC1S9DWgICzuoMba7vurBJnBruE4S5CxnvmZkdqWVXRzx1Rgu636HoH+k0qeaQCFh3jeG3JQ1y6fRHv0sw==} + cpu: [x64] + os: [win32] + + '@oven/bun-windows-x64@1.3.14': + resolution: {integrity: sha512-mUFWL3BoYkNpjd8e9PqROiFF/1Xeotq20mABJsiQH62jM1g5zqWh4khw1RZ6bX8Q8fWvlPaxG1PjofkmjUi3vg==} + cpu: [x64] + os: [win32] + + '@pkgr/core@0.3.6': + resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==} + engines: {node: ^14.18.0 || >=16.0.0} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/validator@13.15.10': + resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} + + '@typescript-eslint/eslint-plugin@8.67.0': + resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.67.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.67.0': + resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.67.0': + resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.67.0': + resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.67.0': + resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.67.0': + resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.67.0': + resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.67.0': + resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.67.0': + resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.67.0': + resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} + engines: {node: '>=18'} + + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} + engines: {node: '>=14'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + brace-expansion@1.1.18: + resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} + + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + bun@1.3.14: + resolution: {integrity: sha512-aB6GVd42x1Y5ie1K16SF+oLGtgSkwX9hgoDdIW88pjvfTccU8F1vfpoOt34QLv0dZ1v3XimtaxPlZUG81Gx9Zg==} + cpu: [arm64, x64] + os: [darwin, linux, android, freebsd, win32] + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chardet@2.2.0: + resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + class-validator@0.14.4: + resolution: {integrity: sha512-AwNusCCam51q703dW82x95tOqQp6oC9HNUl724KxJJOfnKscI8dOloXFgyez7LbTTKWuRBA37FScqVbJEoq8Yw==} + + class-validator@0.15.1: + resolution: {integrity: sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@3.4.0: + resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} + engines: {node: '>=18.20'} + + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} + engines: {node: '>=20'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + commander@15.0.0: + resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} + engines: {node: '>=22.12.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + domexception@1.0.1: + resolution: {integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==} + deprecated: Use your platform's native DOMException instead + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-prettier@5.5.6: + resolution: {integrity: sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.5: + resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-uri@3.1.5: + resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + konva@10.3.1: + resolution: {integrity: sha512-7fT/jSkL2bZZOHRBk2QVMKAUbgHoKG72W+KJtpP5YMJUZRmjgoafROgxTADsrxKOY2ZM5eKyN/x6CM9PrlFfOg==} + peerDependencies: + canvas: ^3.0.0 + skia-canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + skia-canvas: + optional: true + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + libphonenumber-js@1.13.11: + resolution: {integrity: sha512-ETER2kMaIFTI/Nh1a8Gk03dUF/SL0VZqtI+CcVHZxp5WIHYwNS7S+uiYZDYCvLy3lOR4/DAD5jf0h5WkePPpqg==} + + lint-staged@16.4.0: + resolution: {integrity: sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==} + engines: {node: '>=20.17'} + hasBin: true + + listr2@9.0.5: + resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} + engines: {node: '>=20.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} + engines: {node: '>=18'} + + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + + magic-string@1.0.0: + resolution: {integrity: sha512-CGvjzMN08iv6w1mm4/x3Gh1hLb4VnyRUA15FFpl6CsCIGGoe36k7kY5KNz9QDbSBN5I/fWHM6ZlIkUTa5xdUEA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mute-stream@3.0.0: + resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} + engines: {node: ^20.17.0 || >=22.9.0} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + open@11.0.1: + resolution: {integrity: sha512-NzwMUB6C1D0+Kd+9iMS/H4k+Ck3cTX6Ckyfr/gAGlmvSE1LUQZnEZvWBi4PYmMwH/S5SMeTXnE+9uAz8uF+pWw==} + engines: {node: '>=20'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@9.4.1: + resolution: {integrity: sha512-6VlU9MLXbjVQD04AZCMX28hVtA5bUoadvUqO76MUCVA0ilwJbMiHsITRPfyVm6p/BC0Av/BXMujx39WCe1LEqw==} + engines: {node: '>=20'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + + powershell-utils@0.2.0: + resolution: {integrity: sha512-ZlsFlG7MtSFCoc5xreOvBAozCJ6Pf06opgJjh9ONEv418xpZSAzNjstD36C6+JwOnfSqOW/9uDkqKjezTdxZhw==} + engines: {node: '>=20'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.1: + resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} + engines: {node: '>=6.0.0'} + + prettier@3.9.6: + resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} + engines: {node: '>=14'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + rc9@3.0.1: + resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} + engines: {node: '>=18'} + + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + stdin-discarder@0.3.2: + resolution: {integrity: sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==} + engines: {node: '>=18'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.2.2: + resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} + engines: {node: '>=20'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + synckit@0.11.13: + resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} + engines: {node: ^14.18.0 || >=16.0.0} + + tar@7.5.22: + resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} + engines: {node: '>=18'} + + tinyexec@1.3.0: + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.67.0: + resolution: {integrity: sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + validator@13.15.35: + resolution: {integrity: sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==} + engines: {node: '>= 0.10'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrtc@0.4.7: + resolution: {integrity: sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g==} + engines: {node: ^8.11.2 || >=10.0.0} + bundledDependencies: + - node-pre-gyp + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@1.0.0: + resolution: {integrity: sha512-Hl0ZOAs672vg+06kfujwRhoS6/jehvULrlFkuF2dRu6pHgA8U06h3xqNIqNNU1LTXPcedxByAR4GS6pwQK0mgA==} + engines: {node: '>=20'} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors@2.2.0: + resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} + engines: {node: '>=18'} + +snapshots: + + '@angular-devkit/core@22.1.4(chokidar@5.0.0)': + dependencies: + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + jsonc-parser: 3.3.1 + picomatch: 4.0.5 + rxjs: 7.8.2 + source-map: 0.7.6 + optionalDependencies: + chokidar: 5.0.0 + + '@angular-devkit/schematics-cli@22.1.4(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 22.1.4(chokidar@5.0.0) + '@angular-devkit/schematics': 22.1.4(chokidar@5.0.0) + '@inquirer/prompts': 8.5.2 + transitivePeerDependencies: + - '@types/node' + - chokidar + + '@angular-devkit/schematics@22.1.4(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 22.1.4(chokidar@5.0.0) + jsonc-parser: 3.3.1 + magic-string: 1.0.0 + ora: 9.4.1 + rxjs: 7.8.2 + transitivePeerDependencies: + - chokidar + + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(supports-color@7.2.0))': + dependencies: + eslint: 9.39.5(supports-color@7.2.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2(supports-color@7.2.0)': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3(supports-color@7.2.0) + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.6(supports-color@7.2.0)': + dependencies: + ajv: 6.15.0 + debug: 4.4.3(supports-color@7.2.0) + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.3.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.5': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@inquirer/ansi@2.0.7': {} + + '@inquirer/checkbox@5.2.1': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7 + + '@inquirer/confirm@6.1.1': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/type': 4.0.7 + + '@inquirer/core@11.2.1': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7 + cli-width: 4.1.0 + fast-wrap-ansi: 0.2.2 + mute-stream: 3.0.0 + signal-exit: 4.1.0 + + '@inquirer/editor@5.2.2': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/external-editor': 3.0.3 + '@inquirer/type': 4.0.7 + + '@inquirer/expand@5.1.1': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/type': 4.0.7 + + '@inquirer/external-editor@3.0.3': + dependencies: + chardet: 2.2.0 + iconv-lite: 0.7.3 + + '@inquirer/figures@2.0.7': {} + + '@inquirer/input@5.1.2': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/type': 4.0.7 + + '@inquirer/number@4.1.1': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/type': 4.0.7 + + '@inquirer/password@5.1.1': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1 + '@inquirer/type': 4.0.7 + + '@inquirer/prompts@8.5.2': + dependencies: + '@inquirer/checkbox': 5.2.1 + '@inquirer/confirm': 6.1.1 + '@inquirer/editor': 5.2.2 + '@inquirer/expand': 5.1.1 + '@inquirer/input': 5.1.2 + '@inquirer/number': 4.1.1 + '@inquirer/password': 5.1.1 + '@inquirer/rawlist': 5.3.1 + '@inquirer/search': 4.2.1 + '@inquirer/select': 5.2.1 + + '@inquirer/rawlist@5.3.1': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/type': 4.0.7 + + '@inquirer/search@4.2.1': + dependencies: + '@inquirer/core': 11.2.1 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7 + + '@inquirer/select@5.2.1': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7 + + '@inquirer/type@4.0.7': {} + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@mapbox/node-pre-gyp@2.0.3(supports-color@7.2.0)': + dependencies: + consola: 3.4.2 + detect-libc: 2.1.2 + https-proxy-agent: 7.0.6(supports-color@7.2.0) + node-fetch: 2.7.0 + nopt: 8.1.0 + semver: 7.8.5 + tar: 7.5.22 + transitivePeerDependencies: + - encoding + - supports-color + + '@nanoforge-dev/asset-manager@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + + '@nanoforge-dev/cli@1.6.2': + dependencies: + '@angular-devkit/schematics': 22.1.4(chokidar@5.0.0) + '@angular-devkit/schematics-cli': 22.1.4(chokidar@5.0.0) + '@inquirer/prompts': 8.5.2 + '@nanoforge-dev/loader-client': 1.4.0 + '@nanoforge-dev/loader-server': 1.4.0 + '@nanoforge-dev/schematics': 2.2.1(chokidar@5.0.0) + ansis: 4.3.1 + bun: 1.3.14 + chokidar: 5.0.0 + class-transformer: 0.5.1 + class-validator: 0.15.1 + commander: 15.0.0 + dotenv: 17.4.2 + node-emoji: 2.2.0 + open: 11.0.1 + ora: 9.4.1 + rc9: 3.0.1 + reflect-metadata: 0.2.2 + optionalDependencies: + '@nanoforge-dev/editor': 0.1.4 + transitivePeerDependencies: + - '@types/node' + + '@nanoforge-dev/common@1.4.2': {} + + '@nanoforge-dev/config@1.4.2': + dependencies: + class-transformer: 0.5.1 + class-validator: 0.14.4 + + '@nanoforge-dev/core@1.4.2': + dependencies: + '@nanoforge-dev/asset-manager': 1.4.2 + '@nanoforge-dev/common': 1.4.2 + '@nanoforge-dev/input': 1.4.2 + class-transformer: 0.5.1 + class-validator: 0.14.4 + + '@nanoforge-dev/ecs-client@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + '@nanoforge-dev/ecs-lib': 1.4.2 + + '@nanoforge-dev/ecs-lib@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + + '@nanoforge-dev/ecs-server@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + '@nanoforge-dev/ecs-lib': 1.4.2 + + '@nanoforge-dev/editor@0.1.4': + dependencies: + bun: 1.3.14 + class-transformer: 0.5.1 + class-validator: 0.15.1 + dotenv: 17.4.2 + micromatch: 4.0.8 + tar: 7.5.22 + typescript: 6.0.3 + optional: true + + '@nanoforge-dev/graphics-2d@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + konva: 10.3.1 + transitivePeerDependencies: + - canvas + - skia-canvas + + '@nanoforge-dev/input@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + + '@nanoforge-dev/loader-client@1.4.0': + dependencies: + '@nanoforge-dev/loader-website': 1.4.0 + bun: 1.3.14 + commander: 15.0.0 + + '@nanoforge-dev/loader-server@1.4.0': + dependencies: + commander: 15.0.0 + + '@nanoforge-dev/loader-website@1.4.0': {} + + '@nanoforge-dev/music@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + + '@nanoforge-dev/network-client@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + '@nanoforge-dev/config': 1.4.2 + + '@nanoforge-dev/network-server@1.4.2(supports-color@7.2.0)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.3(supports-color@7.2.0) + '@nanoforge-dev/common': 1.4.2 + '@nanoforge-dev/config': 1.4.2 + wrtc: 0.4.7 + ws: 8.21.3 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@nanoforge-dev/schematics@2.2.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 22.1.4(chokidar@5.0.0) + '@angular-devkit/schematics': 22.1.4(chokidar@5.0.0) + rxjs: 7.8.2 + transitivePeerDependencies: + - chokidar + + '@nanoforge-dev/sound@1.4.2': + dependencies: + '@nanoforge-dev/common': 1.4.2 + + '@oven/bun-darwin-aarch64@1.3.14': + optional: true + + '@oven/bun-darwin-x64-baseline@1.3.14': + optional: true + + '@oven/bun-darwin-x64@1.3.14': + optional: true + + '@oven/bun-freebsd-aarch64@1.3.14': + optional: true + + '@oven/bun-freebsd-x64@1.3.14': + optional: true + + '@oven/bun-linux-aarch64-android@1.3.14': + optional: true + + '@oven/bun-linux-aarch64-musl@1.3.14': + optional: true + + '@oven/bun-linux-aarch64@1.3.14': + optional: true + + '@oven/bun-linux-x64-android@1.3.14': + optional: true + + '@oven/bun-linux-x64-baseline@1.3.14': + optional: true + + '@oven/bun-linux-x64-musl-baseline@1.3.14': + optional: true + + '@oven/bun-linux-x64-musl@1.3.14': + optional: true + + '@oven/bun-linux-x64@1.3.14': + optional: true + + '@oven/bun-windows-aarch64@1.3.14': + optional: true + + '@oven/bun-windows-x64-baseline@1.3.14': + optional: true + + '@oven/bun-windows-x64@1.3.14': + optional: true + + '@pkgr/core@0.3.6': {} + + '@sindresorhus/is@4.6.0': {} + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/validator@13.15.10': {} + + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/type-utils': 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 + eslint: 9.39.5(supports-color@7.2.0) + ignore: 7.0.6 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.67.0(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + debug: 4.4.3(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.67.0': + dependencies: + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + + '@typescript-eslint/tsconfig-utils@8.67.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(supports-color@7.2.0) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.67.0': {} + + '@typescript-eslint/typescript-estree@8.67.0(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3(supports-color@7.2.0) + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(supports-color@7.2.0)) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.5(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.67.0': + dependencies: + '@typescript-eslint/types': 8.67.0 + eslint-visitor-keys: 5.0.1 + + abbrev@3.0.1: {} + + acorn-jsx@5.3.2(acorn@8.18.0): + dependencies: + acorn: 8.18.0 + + acorn@8.18.0: {} + + agent-base@7.1.4: {} + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.5 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-escapes@7.3.0: + dependencies: + environment: 1.1.0 + + ansi-regex@6.3.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + ansis@4.3.1: {} + + argparse@2.0.1: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + brace-expansion@1.1.18: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.9: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + optional: true + + bun@1.3.14: + optionalDependencies: + '@oven/bun-darwin-aarch64': 1.3.14 + '@oven/bun-darwin-x64': 1.3.14 + '@oven/bun-darwin-x64-baseline': 1.3.14 + '@oven/bun-freebsd-aarch64': 1.3.14 + '@oven/bun-freebsd-x64': 1.3.14 + '@oven/bun-linux-aarch64': 1.3.14 + '@oven/bun-linux-aarch64-android': 1.3.14 + '@oven/bun-linux-aarch64-musl': 1.3.14 + '@oven/bun-linux-x64': 1.3.14 + '@oven/bun-linux-x64-android': 1.3.14 + '@oven/bun-linux-x64-baseline': 1.3.14 + '@oven/bun-linux-x64-musl': 1.3.14 + '@oven/bun-linux-x64-musl-baseline': 1.3.14 + '@oven/bun-windows-aarch64': 1.3.14 + '@oven/bun-windows-x64': 1.3.14 + '@oven/bun-windows-x64-baseline': 1.3.14 + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + callsites@3.1.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + char-regex@1.0.2: {} + + chardet@2.2.0: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + chownr@3.0.0: {} + + class-transformer@0.5.1: {} + + class-validator@0.14.4: + dependencies: + '@types/validator': 13.15.10 + libphonenumber-js: 1.13.11 + validator: 13.15.35 + + class-validator@0.15.1: + dependencies: + '@types/validator': 13.15.10 + libphonenumber-js: 1.13.11 + validator: 13.15.35 + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@3.4.0: {} + + cli-truncate@5.2.0: + dependencies: + slice-ansi: 8.0.0 + string-width: 8.2.2 + + cli-width@4.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + commander@14.0.3: {} + + commander@15.0.0: {} + + concat-map@0.0.1: {} + + consola@3.4.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.4.3(supports-color@7.2.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 7.2.0 + + deep-is@0.1.4: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + defu@6.1.7: {} + + destr@2.0.5: {} + + detect-libc@2.1.2: {} + + domexception@1.0.1: + dependencies: + webidl-conversions: 4.0.2 + optional: true + + dotenv@17.4.2: {} + + emoji-regex@10.6.0: {} + + emojilib@2.4.0: {} + + environment@1.1.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.39.5(supports-color@7.2.0)): + dependencies: + eslint: 9.39.5(supports-color@7.2.0) + + eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(supports-color@7.2.0)))(eslint@9.39.5(supports-color@7.2.0))(prettier@3.9.6): + dependencies: + eslint: 9.39.5(supports-color@7.2.0) + prettier: 3.9.6 + prettier-linter-helpers: 1.0.1 + synckit: 0.11.13 + optionalDependencies: + eslint-config-prettier: 10.1.8(eslint@9.39.5(supports-color@7.2.0)) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.5(supports-color@7.2.0): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(supports-color@7.2.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2(supports-color@7.2.0) + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.6(supports-color@7.2.0) + '@eslint/js': 9.39.5 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@7.2.0) + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + eventemitter3@5.0.4: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-uri@3.1.5: {} + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + optional: true + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.4 + keyv: 4.5.4 + + flatted@3.4.4: {} + + get-east-asian-width@1.6.0: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@16.5.0: {} + + has-flag@4.0.0: {} + + https-proxy-agent@7.0.6(supports-color@7.2.0): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.6: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.6.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-interactive@2.0.0: {} + + is-number@7.0.0: + optional: true + + is-unicode-supported@2.1.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isexe@2.0.0: {} + + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + jsonc-parser@3.3.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + konva@10.3.1: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + libphonenumber-js@1.13.11: {} + + lint-staged@16.4.0: + dependencies: + commander: 14.0.3 + listr2: 9.0.5 + picomatch: 4.0.5 + string-argv: 0.3.2 + tinyexec: 1.3.0 + yaml: 2.9.0 + + listr2@9.0.5: + dependencies: + cli-truncate: 5.2.0 + colorette: 2.0.20 + eventemitter3: 5.0.4 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.2 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + log-symbols@7.0.1: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.2.0 + + log-update@6.1.0: + dependencies: + ansi-escapes: 7.3.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + magic-string@1.0.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + optional: true + + mimic-function@5.0.1: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.9 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.18 + + minipass@7.1.3: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + + ms@2.1.3: {} + + mute-stream@3.0.0: {} + + natural-compare@1.4.0: {} + + node-emoji@2.2.0: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + open@11.0.1: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.2.0 + wsl-utils: 1.0.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@9.4.1: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 3.4.0 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 7.0.1 + stdin-discarder: 0.3.2 + string-width: 8.2.2 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + picomatch@2.3.2: + optional: true + + picomatch@4.0.5: {} + + powershell-utils@0.1.0: {} + + powershell-utils@0.2.0: {} + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.1: + dependencies: + fast-diff: 1.3.0 + + prettier@3.9.6: {} + + punycode@2.3.1: {} + + rc9@3.0.1: + dependencies: + defu: 6.1.7 + destr: 2.0.5 + + readdirp@5.1.1: {} + + reflect-metadata@0.2.2: {} + + require-from-string@2.0.2: {} + + resolve-from@4.0.0: {} + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + rfdc@1.4.1: {} + + run-applescript@7.1.0: {} + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safer-buffer@2.1.2: {} + + semver@7.8.5: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slice-ansi@7.1.2: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + source-map@0.7.6: {} + + stdin-discarder@0.3.2: {} + + string-argv@0.3.2: {} + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string-width@8.2.2: + dependencies: + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.3.0 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + synckit@0.11.13: + dependencies: + '@pkgr/core': 0.3.6 + + tar@7.5.22: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + + tinyexec@1.3.0: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + optional: true + + tr46@0.0.3: {} + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.5(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + typescript@6.0.3: + optional: true + + unicode-emoji-modifier-base@1.0.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + validator@13.15.35: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@4.0.2: + optional: true + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + wrtc@0.4.7: + optionalDependencies: + domexception: 1.0.1 + + ws@8.21.3: {} + + wsl-utils@1.0.0: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + + yallist@5.0.0: {} + + yaml@2.9.0: {} + + yocto-queue@0.1.0: {} + + yoctocolors@2.2.0: {} diff --git a/raid-survival/pnpm-workspace.yaml b/raid-survival/pnpm-workspace.yaml new file mode 100644 index 0000000..3ddf7f1 --- /dev/null +++ b/raid-survival/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +allowBuilds: + bun: true + wrtc: true diff --git a/raid-survival/prettier.config.js b/raid-survival/prettier.config.js new file mode 100644 index 0000000..8e5015d --- /dev/null +++ b/raid-survival/prettier.config.js @@ -0,0 +1,6 @@ +export default { + useTabs: false, + singleQuote: false, + trailingComma: "all", + printWidth: 100, +}; diff --git a/raid-survival/server/components/example.component.ts b/raid-survival/server/components/example.component.ts new file mode 100644 index 0000000..b803aa5 --- /dev/null +++ b/raid-survival/server/components/example.component.ts @@ -0,0 +1,55 @@ +import { type EditorComponentManifest } from "@nanoforge-dev/ecs-server"; + +export class ExampleComponent { + name = this.constructor.name; + + constructor( + public paramA: string, + public paramB: number, + public paramC: boolean = false, + ) {} + + get foo() { + return "bar"; + } + + get paramAOrDefault() { + return this.paramC ? this.paramA : "default"; + } + + addOne() { + this.paramB += 1; + } +} + +// * Required to generate code +export default ExampleComponent.name; + +// * Required for the editor to display the component and generate code +export const EDITOR_COMPONENT_MANIFEST: EditorComponentManifest = { + name: "Example", + description: "Example component description", + params: [ + { + type: "string", + name: "paramA", + description: "Param A description", + example: "Example value", + }, + { + type: "number", + name: "paramB", + description: "Param B description", + example: 3, + }, + { + type: "boolean", + name: "paramC", + description: "Param C description", + example: true, + default: false, + // Not required because it has a default value + optional: true, + }, + ], +}; diff --git a/raid-survival/server/main.ts b/raid-survival/server/main.ts new file mode 100644 index 0000000..60ae143 --- /dev/null +++ b/raid-survival/server/main.ts @@ -0,0 +1,33 @@ +import { type IRunOptions } from "@nanoforge-dev/common"; +import { NanoforgeFactory } from "@nanoforge-dev/core"; + +import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; +import { ECSServerLibrary } from "@nanoforge-dev/ecs-server"; +import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; + +import { ExampleComponent } from "./components/example.component"; + +import { exampleSystem } from "./systems/example.system"; + +export async function main(options: IRunOptions) { + const app = NanoforgeFactory.createServer(); + + const assetManagerLibrary = new AssetManagerLibrary(); + const ecsLibrary = new ECSServerLibrary(); + const networkLibrary = new NetworkServerLibrary(); + + app.useAssetManager(assetManagerLibrary); + app.useComponentSystem(ecsLibrary); + app.useNetwork(networkLibrary); + + await app.init(options); + + const registry = ecsLibrary.registry; + + const exampleEntity = registry.spawnEntity(); + registry.addComponent(exampleEntity, new ExampleComponent("example", 10, undefined)); + + registry.addSystem(exampleSystem); + + await app.run(); +} diff --git a/raid-survival/server/systems/example.system.ts b/raid-survival/server/systems/example.system.ts new file mode 100644 index 0000000..7400df4 --- /dev/null +++ b/raid-survival/server/systems/example.system.ts @@ -0,0 +1,31 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type EditorSystemManifest, type Registry } from "@nanoforge-dev/ecs-server"; + +import { ExampleComponent } from "../components/example.component"; + +export const exampleSystem = (registry: Registry, ctx: Context) => { + const entities = registry.getZipper([ExampleComponent]); + + entities.forEach((entity) => { + if (entity.ExampleComponent.paramA === "end") { + ctx.app.setIsRunning(false); + return; + } + + if (entity.ExampleComponent.paramB === 0) entity.ExampleComponent.paramA = "end"; + + if (entity.ExampleComponent.paramB >= 0) + entity.ExampleComponent.paramB = entity.ExampleComponent.paramB - 1; + }); +}; + +// * Required to generate code +export default exampleSystem.name; + +// * Required for the editor to display the system and generate code +export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = { + name: "Example", + description: + "This system end the game when paramB reaches 0 for any entity with ExampleComponent", + dependencies: ["ExampleComponent"], +}; diff --git a/raid-survival/tsconfig.json b/raid-survival/tsconfig.json new file mode 100644 index 0000000..79e653f --- /dev/null +++ b/raid-survival/tsconfig.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + // Mapped from https://www.typescriptlang.org/tsconfig + "compilerOptions": { + // Type Checking + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "exactOptionalPropertyTypes": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": false, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strict": true, + + // Modules + "allowArbitraryExtensions": false, + "allowImportingTsExtensions": false, + "module": "ESNext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "resolvePackageJsonExports": true, + "resolvePackageJsonImports": true, + + // Interop Constraints + "allowSyntheticDefaultImports": true, + "esModuleInterop": false, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + + // Language and Environment + "experimentalDecorators": true, + "lib": ["ESNext", "esnext.disposable", "DOM"], + "target": "ESNext", + "useDefineForClassFields": true, + }, + "include": ["client/**/*.ts", "server/**/*.ts"], + "exclude": ["node_modules", ".nanoforge"] +} From 189eafc061951c0be96b471185992f09b4bfdc51 Mon Sep 17 00:00:00 2001 From: Harper Date: Tue, 18 Aug 2026 19:04:27 +0200 Subject: [PATCH 02/15] fix(raid-survival): flip player to aim mouse position --- .../client/components/renderable.component.ts | 44 +++++++++++++++++-- .../client/systems/movement.system.ts | 12 +---- .../client/systems/player-control.system.ts | 26 ++++++----- raid-survival/client/systems/render.system.ts | 10 ++++- 4 files changed, 67 insertions(+), 25 deletions(-) diff --git a/raid-survival/client/components/renderable.component.ts b/raid-survival/client/components/renderable.component.ts index 59b24b0..5b14d07 100644 --- a/raid-survival/client/components/renderable.component.ts +++ b/raid-survival/client/components/renderable.component.ts @@ -3,19 +3,57 @@ import { Sprite, Vector2d } from "@nanoforge-dev/graphics-2d"; interface RenderableComponentOptions { animationsKey?: string; scale?: Vector2d; + currentAnimation?: string; } export class RenderableComponent { name = this.constructor.name; spriteKey: string; - animationsKey?: string; sprite: Sprite | undefined; - scale: Vector2d = { x: 1, y: 1 }; + animationsKey?: string; + + private _scale: Vector2d = { x: 1, y: 1 }; + private _currentAnimation: string = "idle"; + private _flipped: boolean = false; constructor(spriteKey: string, options?: RenderableComponentOptions) { this.spriteKey = spriteKey; if (options?.animationsKey) this.animationsKey = options.animationsKey; - if (options?.scale) this.scale = options.scale; + if (options?.scale) this._scale = options.scale; + if (options?.currentAnimation) this._currentAnimation = options.currentAnimation; + } + + getAnimation(): string { + return this._currentAnimation; + } + + setAnimation(animation: string) { + if (animation === this._currentAnimation) return; + this._currentAnimation = animation; + this.sprite?.animation(animation); + } + + getScale(): Vector2d { + return this._scale; + } + + setScale(scale: Vector2d) { + this._scale = scale; + this.sprite?.scale(scale); + } + + isFlipped() { + return this._flipped; + } + + flip() { + this._flipped = true; + this.sprite?.scaleX(this._scale.x * -1) + } + + unflip() { + this._flipped = false; + this.sprite?.scaleX(this._scale.x); } } diff --git a/raid-survival/client/systems/movement.system.ts b/raid-survival/client/systems/movement.system.ts index ecb97a4..d9b7139 100644 --- a/raid-survival/client/systems/movement.system.ts +++ b/raid-survival/client/systems/movement.system.ts @@ -1,5 +1,5 @@ import { type Context } from "@nanoforge-dev/common"; -import { type EditorSystemManifest, type Registry } from "@nanoforge-dev/ecs-client"; +import { type Registry } from "@nanoforge-dev/ecs-client"; import { PositionComponent } from "../components/position.component"; import { VelocityComponent } from "../components/velocity.component"; @@ -16,12 +16,4 @@ export const movementSystem = (registry: Registry, ctx: Context) => { }; // * Required to generate code -export default movementSystem.name; - -// * Required for the editor to display the system and generate code -export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = { - name: "movement", - description: - "This system end the game when paramB reaches 0 for any entity with ExampleComponent", - dependencies: ["ExampleComponent"], -}; +export default movementSystem.name; \ No newline at end of file diff --git a/raid-survival/client/systems/player-control.system.ts b/raid-survival/client/systems/player-control.system.ts index 7c03a5e..0bd7810 100644 --- a/raid-survival/client/systems/player-control.system.ts +++ b/raid-survival/client/systems/player-control.system.ts @@ -20,9 +20,9 @@ export const playerControlSystem = (registry: Registry, ctx: Context) => { let dx = 0; let dy = 0; - if (input.isKeyPressed(InputEnum.KeyZ) || input.isKeyPressed(InputEnum.ArrowUp)) dy -= 1; + if (input.isKeyPressed(InputEnum.KeyW) || input.isKeyPressed(InputEnum.ArrowUp)) dy -= 1; if (input.isKeyPressed(InputEnum.KeyS) || input.isKeyPressed(InputEnum.ArrowDown)) dy += 1; - if (input.isKeyPressed(InputEnum.KeyQ) || input.isKeyPressed(InputEnum.ArrowLeft)) dx -= 1; + if (input.isKeyPressed(InputEnum.KeyA) || input.isKeyPressed(InputEnum.ArrowLeft)) dx -= 1; if (input.isKeyPressed(InputEnum.KeyD) || input.isKeyPressed(InputEnum.ArrowRight)) dx += 1; const len = Math.hypot(dx, dy) || 1; @@ -48,16 +48,22 @@ export const playerAnimationSystem = (registry: Registry) => { for (const entity of entities) { if (!entity.RenderableComponent.sprite) continue; - if (entity.VelocityComponent.y != 0 || entity.VelocityComponent.x != 0) { - entity.RenderableComponent.sprite.animation("walk"); - } else { - entity.RenderableComponent.sprite.animation("idle"); + if ( + entity.VelocityComponent.y != 0 || + (entity.VelocityComponent.x != 0 && entity.RenderableComponent.getAnimation() != "walk") + ) { + entity.RenderableComponent.setAnimation("walk"); + } else if (entity.VelocityComponent.x == 0 && entity.RenderableComponent.getAnimation() != "idle") { + entity.RenderableComponent.setAnimation("idle"); } - if (entity.PlayerComponent.target.x < entity.PositionComponent.x) { - entity.RenderableComponent.sprite.scaleX(-3); - } else { - entity.RenderableComponent.sprite.scaleX(3); + if (entity.PlayerComponent.target.x < entity.PositionComponent.x && !entity.RenderableComponent.isFlipped()) { + entity.RenderableComponent.flip(); + } else if ( + entity.PlayerComponent.target.x > entity.PositionComponent.x && + entity.RenderableComponent.isFlipped() + ) { + entity.RenderableComponent.unflip(); } } } diff --git a/raid-survival/client/systems/render.system.ts b/raid-survival/client/systems/render.system.ts index b68de7f..ad035b0 100644 --- a/raid-survival/client/systems/render.system.ts +++ b/raid-survival/client/systems/render.system.ts @@ -93,6 +93,7 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { pendingIds.delete(entity.id); + const [, , frameWidth, frameHeight] = animations && animations["idle"] ? animations["idle"] : [0, 0, 16, 16]; const newSprite = new Sprite({ x: entity.PositionComponent.x, @@ -101,7 +102,9 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { animation: "idle", animations, frameRate: 7, - scale: { x: entity.RenderableComponent.scale.x, y: entity.RenderableComponent.scale.y }, + width: frameWidth || 16, + height: frameHeight || 16, + scale: { x: entity.RenderableComponent.getScale().x, y: entity.RenderableComponent.getScale().y }, }); newSprite.offsetX(newSprite.width() / 2); @@ -113,7 +116,10 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { spriteCache.set(entity.id, newSprite); } - sprite?.position({ x: entity.PositionComponent.x, y: entity.PositionComponent.y }); + sprite?.position({ + x: entity.PositionComponent.x + sprite.offsetX(), + y: entity.PositionComponent.y + sprite.offsetY(), + }); } for (const [id, sprite] of spriteCache) { From d5242bb0a13e846f9e1e44a4d25414f3704011ec Mon Sep 17 00:00:00 2001 From: Harper Date: Tue, 18 Aug 2026 21:14:17 +0200 Subject: [PATCH 03/15] fix(raid-survival): camera follow player and world mouse position --- .../client/components/pointer.component.ts | 13 +++++++++ .../client/components/renderable.component.ts | 6 +++- raid-survival/client/main.ts | 24 ++++++++++++---- .../client/systems/player-control.system.ts | 28 ++++++++++++++++++- .../client/systems/pointer.system.ts | 19 +++++++++++++ raid-survival/client/systems/render.system.ts | 4 +-- 6 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 raid-survival/client/components/pointer.component.ts create mode 100644 raid-survival/client/systems/pointer.system.ts diff --git a/raid-survival/client/components/pointer.component.ts b/raid-survival/client/components/pointer.component.ts new file mode 100644 index 0000000..74b23c4 --- /dev/null +++ b/raid-survival/client/components/pointer.component.ts @@ -0,0 +1,13 @@ +import { Vector2d } from "@nanoforge-dev/graphics-2d"; + +export class PointerComponent { + name = this.constructor.name; + position: Vector2d = {x: 0, y: 0}; + + constructor(position?: Vector2d) { + if (position) this.position = position; + } +} + +// * Required to generate code +export default PointerComponent.name; diff --git a/raid-survival/client/components/renderable.component.ts b/raid-survival/client/components/renderable.component.ts index 5b14d07..53c9ba9 100644 --- a/raid-survival/client/components/renderable.component.ts +++ b/raid-survival/client/components/renderable.component.ts @@ -1,7 +1,9 @@ -import { Sprite, Vector2d } from "@nanoforge-dev/graphics-2d"; +import { Layer, Sprite, Vector2d } from "@nanoforge-dev/graphics-2d"; +import { WorldLayer } from "../main"; interface RenderableComponentOptions { animationsKey?: string; + layer?: Layer; scale?: Vector2d; currentAnimation?: string; } @@ -11,6 +13,7 @@ export class RenderableComponent { spriteKey: string; sprite: Sprite | undefined; animationsKey?: string; + layer: Layer = WorldLayer; private _scale: Vector2d = { x: 1, y: 1 }; private _currentAnimation: string = "idle"; @@ -19,6 +22,7 @@ export class RenderableComponent { constructor(spriteKey: string, options?: RenderableComponentOptions) { this.spriteKey = spriteKey; if (options?.animationsKey) this.animationsKey = options.animationsKey; + if (options?.layer) this.layer = options.layer; if (options?.scale) this._scale = options.scale; if (options?.currentAnimation) this._currentAnimation = options.currentAnimation; } diff --git a/raid-survival/client/main.ts b/raid-survival/client/main.ts index afae6df..097de92 100644 --- a/raid-survival/client/main.ts +++ b/raid-survival/client/main.ts @@ -3,18 +3,26 @@ import { NanoforgeFactory } from "@nanoforge-dev/core"; import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; import { ECSClientLibrary } from "@nanoforge-dev/ecs-client"; -import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d"; +import { Graphics2DLibrary, Layer } from "@nanoforge-dev/graphics-2d"; import { InputLibrary } from "@nanoforge-dev/input"; import { MusicLibrary } from "@nanoforge-dev/music"; import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; import { SoundLibrary } from "@nanoforge-dev/sound"; import { movementSystem } from "./systems/movement.system"; -import { playerAnimationSystem, playerControlSystem } from "./systems/player-control.system"; +import { + cameraFollowSystem, + playerAnimationSystem, + playerControlSystem, +} from "./systems/player-control.system"; import { renderSystem } from "./systems/render.system"; import { LocalPlayerComponent, PlayerComponent } from "./components/player.component"; import { RenderableComponent } from "./components/renderable.component"; import { PositionComponent } from "./components/position.component"; import { VelocityComponent } from "./components/velocity.component"; +import {PointerComponent} from "./components/pointer.component"; +import {pointerSystem} from "./systems/pointer.system"; + +export const WorldLayer = new Layer(); export async function main(options: IRunOptions) { const app = NanoforgeFactory.createClient(); @@ -37,15 +45,19 @@ export async function main(options: IRunOptions) { await app.init(options); - const canvas = graphicsLibrary.baseLayer.getCanvas()._canvas; + graphicsLibrary.stage.add(WorldLayer); + const canvas = WorldLayer.getCanvas()._canvas; const canva2D = canvas.getContext("2d"); if (canva2D) canva2D.imageSmoothingEnabled = false; - + const registry = ecsLibrary.registry; const background = registry.spawnEntity(); registry.addComponent(background, new PositionComponent(0, 0)); registry.addComponent(background, new RenderableComponent("map.png")); + + const pointer = registry.spawnEntity(); + registry.addComponent(pointer, new PointerComponent()); const player = registry.spawnEntity(); registry.addComponent(player, new PlayerComponent()); @@ -53,9 +65,11 @@ export async function main(options: IRunOptions) { registry.addComponent(player, new RenderableComponent("player.png", {animationsKey: "player-animations.txt", scale: {x: 3, y: 3}})); registry.addComponent(player, new PositionComponent(100, 100)); registry.addComponent(player, new VelocityComponent()); - + + registry.addSystem(pointerSystem); registry.addSystem(movementSystem); registry.addSystem(playerControlSystem); + registry.addSystem(cameraFollowSystem); registry.addSystem(renderSystem); registry.addSystem(playerAnimationSystem); diff --git a/raid-survival/client/systems/player-control.system.ts b/raid-survival/client/systems/player-control.system.ts index 0bd7810..5944864 100644 --- a/raid-survival/client/systems/player-control.system.ts +++ b/raid-survival/client/systems/player-control.system.ts @@ -5,8 +5,11 @@ import { VelocityComponent } from "../components/velocity.component"; import { InputEnum, InputLibrary } from "@nanoforge-dev/input"; import { RenderableComponent } from "../components/renderable.component"; import { PositionComponent } from "../components/position.component"; +import { WorldLayer } from "../main"; +import { PointerComponent } from "../components/pointer.component"; const SPEED = 200; +const CAMERA_SMOOTHING = 0.1; export const playerControlSystem = (registry: Registry, ctx: Context) => { const entities: { @@ -14,6 +17,7 @@ export const playerControlSystem = (registry: Registry, ctx: Context) => { PlayerComponent: PlayerComponent; VelocityComponent: VelocityComponent; }[] = registry.getZipper([LocalPlayerComponent, PlayerComponent, VelocityComponent]); + const pointer: { PointerComponent: PointerComponent } = registry.getZipper([PointerComponent])[0]; const input = ctx.libs.getInput() for (const entity of entities) { @@ -29,10 +33,32 @@ export const playerControlSystem = (registry: Registry, ctx: Context) => { entity.VelocityComponent.x = (dx / len) * SPEED; entity.VelocityComponent.y = (dy / len) * SPEED; - if (entity.PlayerComponent) entity.PlayerComponent.target = input.getMousePosition(); + if (!pointer) continue; + if (entity.PlayerComponent) entity.PlayerComponent.target = pointer.PointerComponent.position; + console.log(pointer.PointerComponent.position); } }; +export const cameraFollowSystem = (registry: Registry) => { + const worldLayer = WorldLayer; + + const entities: {LocalPlayerComponent: LocalPlayerComponent, PositionComponent: PositionComponent}[] = registry.getZipper([LocalPlayerComponent, PositionComponent]); + + for (const entity of entities) { + const viewWidth = worldLayer.width(); + const viewHeight = worldLayer.height(); + + const targetX = viewWidth / 2 - entity.PositionComponent.x; + const targetY = viewHeight / 2 - entity.PositionComponent.y; + + const current = worldLayer.position(); + worldLayer.position({ + x: current.x + (targetX - current.x) * CAMERA_SMOOTHING, + y: current.y + (targetY - current.y) * CAMERA_SMOOTHING + }); + } +} + export const playerAnimationSystem = (registry: Registry) => { const entities: { PlayerComponent: PlayerComponent; diff --git a/raid-survival/client/systems/pointer.system.ts b/raid-survival/client/systems/pointer.system.ts new file mode 100644 index 0000000..e0a56e6 --- /dev/null +++ b/raid-survival/client/systems/pointer.system.ts @@ -0,0 +1,19 @@ +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { PointerComponent } from "../components/pointer.component"; +import { WorldLayer } from "../main"; + +export const pointerSystem = (registry: Registry) => { + const entities: {PointerComponent: PointerComponent}[] = registry.getZipper([PointerComponent]); + + for (const entity of entities) { + const pointerPosition = WorldLayer.getRelativePointerPosition(); + + if (!pointerPosition) continue; + + entity.PointerComponent.position.x = pointerPosition.x; + entity.PointerComponent.position.y = pointerPosition.y; + } +}; + +// * Required to generate code +export default pointerSystem.name; diff --git a/raid-survival/client/systems/render.system.ts b/raid-survival/client/systems/render.system.ts index ad035b0..5787aa3 100644 --- a/raid-survival/client/systems/render.system.ts +++ b/raid-survival/client/systems/render.system.ts @@ -112,7 +112,7 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { entity.RenderableComponent.sprite = newSprite; newSprite.start(); - graphics.baseLayer.add(newSprite); + entity.RenderableComponent.layer.add(newSprite); spriteCache.set(entity.id, newSprite); } @@ -129,7 +129,7 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { } } - graphics.baseLayer.batchDraw(); + graphics.stage.batchDraw(); }; // * Required to generate code From e45e63cef3dbdc0398196722c3b57d883cd9f0af Mon Sep 17 00:00:00 2001 From: Tchips46 Date: Wed, 19 Aug 2026 07:39:11 +0200 Subject: [PATCH 04/15] feat: bugged network --- .idea/.gitignore | 10 ++ .idea/dictionaries/project.xml | 7 ++ .idea/examples.iml | 8 ++ .idea/inspectionProfiles/Project_Default.xml | 6 ++ .idea/modules.xml | 8 ++ .idea/prettier.xml | 6 ++ .idea/vcs.xml | 6 ++ raid-survival/.idea/.gitignore | 10 ++ .../inspectionProfiles/Project_Default.xml | 6 ++ raid-survival/.idea/modules.xml | 8 ++ raid-survival/.idea/prettier.xml | 6 ++ raid-survival/.idea/raid-survival.iml | 8 ++ raid-survival/.idea/vcs.xml | 6 ++ .../client/components/clickable.component.ts | 11 ++ .../client/components/direction.component.ts | 11 ++ .../components/move-controller.component.ts | 23 ++++ .../client/components/network-id.component.ts | 10 ++ .../client/components/player.component.ts | 13 --- .../client/components/pointer.component.ts | 13 --- .../client/components/position.component.ts | 14 ++- .../client/components/renderable.component.ts | 8 +- .../client/components/shoot.controller.ts | 28 +++++ .../client/components/velocity.component.ts | 11 +- raid-survival/client/main.ts | 96 ++++++++++------- .../client/static/client-config.json | 13 +++ raid-survival/client/static/start_button.png | Bin 0 -> 17198 bytes .../client/systems/camera-follow.system.ts | 26 +++++ .../client/systems/clickable.system.ts | 28 +++++ .../systems/move-control.client.system.ts | 19 ++++ raid-survival/client/systems/move.system.ts | 16 +++ .../client/systems/movement.system.ts | 19 ---- .../client/systems/packet-handler.system.ts | 32 ++++++ .../direction-packet.handler.ts | 13 +++ .../join-lobby-packet.handler.ts | 31 ++++++ .../packet-handlers/kill-packet.handler.ts | 11 ++ .../packet-handlers/move-packet.handler.ts | 19 ++++ .../packet-handlers/spawn-packet.handler.ts | 53 ++++++++++ .../client/systems/player-control.system.ts | 98 ------------------ .../client/systems/pointer.system.ts | 19 ---- raid-survival/client/systems/render.system.ts | 21 ++-- .../send-move-control.client.system.ts | 30 ++++++ .../send-shoot-control.client.system.ts | 26 +++++ .../systems/shoot-control.client.system.ts | 26 +++++ .../client/systems/sprite-animator.system.ts | 23 ++++ raid-survival/eslint.config.js | 6 ++ .../server/components/clientId.component.ts | 8 ++ .../server/components/direction.component.ts | 11 ++ .../server/components/example.component.ts | 55 ---------- .../server/components/position.component.ts | 11 ++ .../server/components/velocity.component.ts | 11 ++ raid-survival/server/main.ts | 37 ++++--- raid-survival/server/network-utils.ts | 9 ++ .../server/systems/example.system.ts | 31 ------ raid-survival/server/systems/move.system.ts | 16 +++ .../server/systems/packet-handler.system.ts | 40 +++++++ .../packet-handlers/input-packet.handler.ts | 56 ++++++++++ .../join-lobby-packet.handler.ts | 47 +++++++++ .../start-game-packet.handler.ts | 46 ++++++++ 58 files changed, 915 insertions(+), 325 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/dictionaries/project.xml create mode 100644 .idea/examples.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/prettier.xml create mode 100644 .idea/vcs.xml create mode 100644 raid-survival/.idea/.gitignore create mode 100644 raid-survival/.idea/inspectionProfiles/Project_Default.xml create mode 100644 raid-survival/.idea/modules.xml create mode 100644 raid-survival/.idea/prettier.xml create mode 100644 raid-survival/.idea/raid-survival.iml create mode 100644 raid-survival/.idea/vcs.xml create mode 100644 raid-survival/client/components/clickable.component.ts create mode 100644 raid-survival/client/components/direction.component.ts create mode 100644 raid-survival/client/components/move-controller.component.ts create mode 100644 raid-survival/client/components/network-id.component.ts delete mode 100644 raid-survival/client/components/player.component.ts delete mode 100644 raid-survival/client/components/pointer.component.ts create mode 100644 raid-survival/client/components/shoot.controller.ts create mode 100644 raid-survival/client/static/client-config.json create mode 100644 raid-survival/client/static/start_button.png create mode 100644 raid-survival/client/systems/camera-follow.system.ts create mode 100644 raid-survival/client/systems/clickable.system.ts create mode 100644 raid-survival/client/systems/move-control.client.system.ts create mode 100644 raid-survival/client/systems/move.system.ts delete mode 100644 raid-survival/client/systems/movement.system.ts create mode 100644 raid-survival/client/systems/packet-handler.system.ts create mode 100644 raid-survival/client/systems/packet-handlers/direction-packet.handler.ts create mode 100644 raid-survival/client/systems/packet-handlers/join-lobby-packet.handler.ts create mode 100644 raid-survival/client/systems/packet-handlers/kill-packet.handler.ts create mode 100644 raid-survival/client/systems/packet-handlers/move-packet.handler.ts create mode 100644 raid-survival/client/systems/packet-handlers/spawn-packet.handler.ts delete mode 100644 raid-survival/client/systems/player-control.system.ts delete mode 100644 raid-survival/client/systems/pointer.system.ts create mode 100644 raid-survival/client/systems/send-move-control.client.system.ts create mode 100644 raid-survival/client/systems/send-shoot-control.client.system.ts create mode 100644 raid-survival/client/systems/shoot-control.client.system.ts create mode 100644 raid-survival/client/systems/sprite-animator.system.ts create mode 100644 raid-survival/server/components/clientId.component.ts create mode 100644 raid-survival/server/components/direction.component.ts delete mode 100644 raid-survival/server/components/example.component.ts create mode 100644 raid-survival/server/components/position.component.ts create mode 100644 raid-survival/server/components/velocity.component.ts create mode 100644 raid-survival/server/network-utils.ts delete mode 100644 raid-survival/server/systems/example.system.ts create mode 100644 raid-survival/server/systems/move.system.ts create mode 100644 raid-survival/server/systems/packet-handler.system.ts create mode 100644 raid-survival/server/systems/packet-handlers/input-packet.handler.ts create mode 100644 raid-survival/server/systems/packet-handlers/join-lobby-packet.handler.ts create mode 100644 raid-survival/server/systems/packet-handlers/start-game-packet.handler.ts diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..30cf57e --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml new file mode 100644 index 0000000..48f4f77 --- /dev/null +++ b/.idea/dictionaries/project.xml @@ -0,0 +1,7 @@ + + + + keys + + + \ No newline at end of file diff --git a/.idea/examples.iml b/.idea/examples.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/examples.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..704ff0e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/prettier.xml b/.idea/prettier.xml new file mode 100644 index 0000000..b0c1c68 --- /dev/null +++ b/.idea/prettier.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/raid-survival/.idea/.gitignore b/raid-survival/.idea/.gitignore new file mode 100644 index 0000000..30cf57e --- /dev/null +++ b/raid-survival/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/raid-survival/.idea/inspectionProfiles/Project_Default.xml b/raid-survival/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/raid-survival/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/raid-survival/.idea/modules.xml b/raid-survival/.idea/modules.xml new file mode 100644 index 0000000..40cdb67 --- /dev/null +++ b/raid-survival/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/raid-survival/.idea/prettier.xml b/raid-survival/.idea/prettier.xml new file mode 100644 index 0000000..b0c1c68 --- /dev/null +++ b/raid-survival/.idea/prettier.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/raid-survival/.idea/raid-survival.iml b/raid-survival/.idea/raid-survival.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/raid-survival/.idea/raid-survival.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/raid-survival/.idea/vcs.xml b/raid-survival/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/raid-survival/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/raid-survival/client/components/clickable.component.ts b/raid-survival/client/components/clickable.component.ts new file mode 100644 index 0000000..3b2cbf6 --- /dev/null +++ b/raid-survival/client/components/clickable.component.ts @@ -0,0 +1,11 @@ +export class Clickable { + name = this.constructor.name; + + constructor( + public size: { x: number; y: number }, + public onClick: () => unknown, + ) {} +} + +// * Required to generate code +export default Clickable.name; diff --git a/raid-survival/client/components/direction.component.ts b/raid-survival/client/components/direction.component.ts new file mode 100644 index 0000000..2c14047 --- /dev/null +++ b/raid-survival/client/components/direction.component.ts @@ -0,0 +1,11 @@ +export class Direction { + name = this.constructor.name; + + constructor( + public x: number, + public y: number, + ) {} +} + +// * Required to generate code +export default Direction.name; diff --git a/raid-survival/client/components/move-controller.component.ts b/raid-survival/client/components/move-controller.component.ts new file mode 100644 index 0000000..6e37ac4 --- /dev/null +++ b/raid-survival/client/components/move-controller.component.ts @@ -0,0 +1,23 @@ +import { type InputEnum } from "@nanoforge-dev/input"; + +export class MoveController { + name = this.constructor.name; + public keyUp: InputEnum; + public keyDown: InputEnum; + public keyLeft: InputEnum; + public keyRight: InputEnum; + public movingUp: boolean = false; + public movingDown: boolean = false; + public movingLeft: boolean = false; + public movingRight: boolean = false; + public lastMoveKeys: string[] = [] + + constructor(clientConfig: { + keybinds: { up: InputEnum; left: InputEnum; down: InputEnum; right: InputEnum }; + }) { + this.keyUp = clientConfig.keybinds.up; + this.keyDown = clientConfig.keybinds.down; + this.keyLeft = clientConfig.keybinds.left; + this.keyRight = clientConfig.keybinds.right; + } +} diff --git a/raid-survival/client/components/network-id.component.ts b/raid-survival/client/components/network-id.component.ts new file mode 100644 index 0000000..0c91a82 --- /dev/null +++ b/raid-survival/client/components/network-id.component.ts @@ -0,0 +1,10 @@ +export class NetworkId { + name = this.constructor.name; + + constructor( + public id: number, + ) {} +} + +// * Required to generate code +export default NetworkId.name; diff --git a/raid-survival/client/components/player.component.ts b/raid-survival/client/components/player.component.ts deleted file mode 100644 index 3b8dc04..0000000 --- a/raid-survival/client/components/player.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Vector2d } from "@nanoforge-dev/graphics-2d"; - -export class PlayerComponent { - name = this.constructor.name; - target: Vector2d = {x: 0, y: 0}; -} - -export class LocalPlayerComponent { - name = this.constructor.name; -} - -// * Required to generate code -export default PlayerComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/pointer.component.ts b/raid-survival/client/components/pointer.component.ts deleted file mode 100644 index 74b23c4..0000000 --- a/raid-survival/client/components/pointer.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Vector2d } from "@nanoforge-dev/graphics-2d"; - -export class PointerComponent { - name = this.constructor.name; - position: Vector2d = {x: 0, y: 0}; - - constructor(position?: Vector2d) { - if (position) this.position = position; - } -} - -// * Required to generate code -export default PointerComponent.name; diff --git a/raid-survival/client/components/position.component.ts b/raid-survival/client/components/position.component.ts index 26859d5..23a606a 100644 --- a/raid-survival/client/components/position.component.ts +++ b/raid-survival/client/components/position.component.ts @@ -1,13 +1,11 @@ -export class PositionComponent { +export class Position { name = this.constructor.name; - x: number = 0; - y: number = 0; - constructor(x: number, y: number) { - this.x = x; - this.y = y; - } + constructor( + public x: number, + public y: number, + ) {} } // * Required to generate code -export default PositionComponent.name; \ No newline at end of file +export default Position.name; diff --git a/raid-survival/client/components/renderable.component.ts b/raid-survival/client/components/renderable.component.ts index 53c9ba9..0841034 100644 --- a/raid-survival/client/components/renderable.component.ts +++ b/raid-survival/client/components/renderable.component.ts @@ -1,5 +1,4 @@ import { Layer, Sprite, Vector2d } from "@nanoforge-dev/graphics-2d"; -import { WorldLayer } from "../main"; interface RenderableComponentOptions { animationsKey?: string; @@ -13,18 +12,19 @@ export class RenderableComponent { spriteKey: string; sprite: Sprite | undefined; animationsKey?: string; - layer: Layer = WorldLayer; + layer: Layer; private _scale: Vector2d = { x: 1, y: 1 }; private _currentAnimation: string = "idle"; private _flipped: boolean = false; - constructor(spriteKey: string, options?: RenderableComponentOptions) { + constructor(spriteKey: string, layer: Layer, options?: RenderableComponentOptions) { this.spriteKey = spriteKey; if (options?.animationsKey) this.animationsKey = options.animationsKey; if (options?.layer) this.layer = options.layer; if (options?.scale) this._scale = options.scale; if (options?.currentAnimation) this._currentAnimation = options.currentAnimation; + this.layer = layer; } getAnimation(): string { @@ -52,7 +52,7 @@ export class RenderableComponent { flip() { this._flipped = true; - this.sprite?.scaleX(this._scale.x * -1) + this.sprite?.scaleX(this._scale.x * -1); } unflip() { diff --git a/raid-survival/client/components/shoot.controller.ts b/raid-survival/client/components/shoot.controller.ts new file mode 100644 index 0000000..084c3b4 --- /dev/null +++ b/raid-survival/client/components/shoot.controller.ts @@ -0,0 +1,28 @@ +import { Vector2d } from "@nanoforge-dev/graphics-2d"; +import { InputEnum } from "@nanoforge-dev/input"; + +export class ShootController { + name = this.constructor.name; + public position: Vector2d = { x: 0, y: 0 }; + + public aimingMode: "mouse" | "arrows" | "joystick"; + public keyShootMainWeapon: InputEnum; + public keyShootSecondWeapon: InputEnum; + public mainWeaponShooting: boolean = false; + public secondWeaponShooting: boolean = false; + + constructor(clientConfig: { + keybinds: { + aimingMode: "mouse" | "arrows" | "joystick"; + shootMainWeapon: InputEnum; + shootSecondWeapon: InputEnum; + }; + }) { + this.aimingMode = clientConfig.keybinds.aimingMode; + this.keyShootMainWeapon = clientConfig.keybinds.shootMainWeapon; + this.keyShootSecondWeapon = clientConfig.keybinds.shootSecondWeapon; + } +} + +// * Required to generate code +export default ShootController.name; diff --git a/raid-survival/client/components/velocity.component.ts b/raid-survival/client/components/velocity.component.ts index f2a3202..d9afbfb 100644 --- a/raid-survival/client/components/velocity.component.ts +++ b/raid-survival/client/components/velocity.component.ts @@ -1,8 +1,11 @@ -export class VelocityComponent { +export class Velocity { name = this.constructor.name; - x = 0; - y = 0; + + constructor( + public x: number, + public y: number, + ) {} } // * Required to generate code -export default VelocityComponent.name; +export default Velocity.name; diff --git a/raid-survival/client/main.ts b/raid-survival/client/main.ts index 097de92..00594c5 100644 --- a/raid-survival/client/main.ts +++ b/raid-survival/client/main.ts @@ -3,30 +3,38 @@ import { NanoforgeFactory } from "@nanoforge-dev/core"; import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; import { ECSClientLibrary } from "@nanoforge-dev/ecs-client"; -import { Graphics2DLibrary, Layer } from "@nanoforge-dev/graphics-2d"; -import { InputLibrary } from "@nanoforge-dev/input"; +import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d"; +import { InputEnum, InputLibrary } from "@nanoforge-dev/input"; import { MusicLibrary } from "@nanoforge-dev/music"; import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; import { SoundLibrary } from "@nanoforge-dev/sound"; -import { movementSystem } from "./systems/movement.system"; -import { - cameraFollowSystem, - playerAnimationSystem, - playerControlSystem, -} from "./systems/player-control.system"; +import { moveSystem } from "./systems/move.system"; +import { spriteAnimator } from "./systems/sprite-animator.system"; import { renderSystem } from "./systems/render.system"; -import { LocalPlayerComponent, PlayerComponent } from "./components/player.component"; -import { RenderableComponent } from "./components/renderable.component"; -import { PositionComponent } from "./components/position.component"; -import { VelocityComponent } from "./components/velocity.component"; -import {PointerComponent} from "./components/pointer.component"; -import {pointerSystem} from "./systems/pointer.system"; +import { cameraFollowSystem } from "./systems/camera-follow.system"; +import { moveControl } from "./systems/move-control.client.system"; +import { shootControl } from "./systems/shoot-control.client.system"; +import { sendMoveControl } from "./systems/send-move-control.client.system"; +import { sendShootControl } from "./systems/send-shoot-control.client.system"; +import { clickableSystem } from "./systems/clickable.system"; +import { packetHandler } from "./systems/packet-handler.system"; -export const WorldLayer = new Layer(); +export let clientConfig: { + keybinds: { + aimingMode: "mouse" | "arrows" | "joystick"; + shootMainWeapon: InputEnum; + shootSecondWeapon: InputEnum; + up: InputEnum; + left: InputEnum; + down: InputEnum; + right: InputEnum; + }; + login: string; +}; export async function main(options: IRunOptions) { const app = NanoforgeFactory.createClient(); - + const assetManagerLibrary = new AssetManagerLibrary(); const ecsLibrary = new ECSClientLibrary(); const graphicsLibrary = new Graphics2DLibrary(); @@ -34,7 +42,7 @@ export async function main(options: IRunOptions) { const musicLibrary = new MusicLibrary(); const networkLibrary = new NetworkClientLibrary(); const soundLibrary = new SoundLibrary(); - + app.useAssetManager(assetManagerLibrary); app.useComponentSystem(ecsLibrary); app.useGraphics(graphicsLibrary); @@ -45,33 +53,41 @@ export async function main(options: IRunOptions) { await app.init(options); - graphicsLibrary.stage.add(WorldLayer); - const canvas = WorldLayer.getCanvas()._canvas; - const canva2D = canvas.getContext("2d"); - if (canva2D) canva2D.imageSmoothingEnabled = false; - + const context = graphicsLibrary.baseLayer.getCanvas()._canvas.getContext("2d"); + if (context) context.imageSmoothingEnabled = false; + clientConfig = await assetManagerLibrary.getAsset("client-config.json").json(); const registry = ecsLibrary.registry; - const background = registry.spawnEntity(); - registry.addComponent(background, new PositionComponent(0, 0)); - registry.addComponent(background, new RenderableComponent("map.png")); - - const pointer = registry.spawnEntity(); - registry.addComponent(pointer, new PointerComponent()); - - const player = registry.spawnEntity(); - registry.addComponent(player, new PlayerComponent()); - registry.addComponent(player, new LocalPlayerComponent()); - registry.addComponent(player, new RenderableComponent("player.png", {animationsKey: "player-animations.txt", scale: {x: 3, y: 3}})); - registry.addComponent(player, new PositionComponent(100, 100)); - registry.addComponent(player, new VelocityComponent()); - - registry.addSystem(pointerSystem); - registry.addSystem(movementSystem); - registry.addSystem(playerControlSystem); + registry.addSystem(moveControl); + registry.addSystem(shootControl); + registry.addSystem(sendMoveControl); + registry.addSystem(sendShootControl); + registry.addSystem(spriteAnimator); registry.addSystem(cameraFollowSystem); + registry.addSystem(clickableSystem); + registry.addSystem(packetHandler); + registry.addSystem(moveSystem); registry.addSystem(renderSystem); - registry.addSystem(playerAnimationSystem); + async function waitForConnection(): Promise { + if (networkLibrary.tcp?.isConnected()) return; + + return new Promise((resolve) => { + const check = () => { + if (networkLibrary.tcp.isConnected()) { + resolve(); + } else { + setTimeout(check, 50); + } + }; + check(); + }); + } + + await waitForConnection(); + + networkLibrary.tcp.sendData( + new TextEncoder().encode(JSON.stringify({ type: "joinLobby", login: clientConfig.login })), + ); await app.run(); } diff --git a/raid-survival/client/static/client-config.json b/raid-survival/client/static/client-config.json new file mode 100644 index 0000000..d4ab5b2 --- /dev/null +++ b/raid-survival/client/static/client-config.json @@ -0,0 +1,13 @@ +{ + "keybinds": { + "up": "KeyZ", + "left": "KeyA", + "down": "KeyS", + "right": "KeyD", + "aimingMode": "Mouse", + "shootMainWeapon": "MouseLeft", + "shootSecondWeapon": "KeyF", + "inspectEntity": "MouseRight" + }, + "login": "tchips" +} diff --git a/raid-survival/client/static/start_button.png b/raid-survival/client/static/start_button.png new file mode 100644 index 0000000000000000000000000000000000000000..83fcb616fe35959b1f428bdf367a7d495e7d1c03 GIT binary patch literal 17198 zcmeHvRa9JIvt`o|2rj{0LlWE_A`sl&9fG?{LvRQXg1ZHGcW68~3GR(UaQ9|T{(EQ5 zyv*A?-d>AEcf&b-PJLB-SJk(xBa{>*G0{lTKp+sNw3N6C2m}V6f&;XwK^3Y?*#6ObP-~gQUejsCi}_u6X#WsoxKtO(fuhb3-O&_rj&(OY^?YR|kQ4 zU0+CiaDpVMd$^hF&o(fX7l#vQ;OkctrG_-Ry15w)0IU4)IT_8A?mU@` zB6``fE1ct;C2*6mi-7w-kN>g2{~rsWzDS-zNN_R85mh3S;@{DYrdw+ZAf`V4HKz&A z`$$z7E){`~upsH5fsPMC{*LxD^VCkPn(PghUkX?T^syV0`^6%-BJlP5KXDFMsPqW5 zwA;!Yf%HZw)la{g+@LZ>WH1lrTIctu0UgUogm)K#3P^-cb%Buz$PBc2fzAO9NIwD@ zpu$EXGHAB>NKjJjNz7(q{*zx#r3%ROv?`$#$o?YdM~p@^Fc;1osY0ZjOFUHO+c}UX z;tYB8XYrqp!>_-;^u_c=KXl?wdzp`vV@8U=hkzL1@;f^{T&kHPpdVTUwR~S&w;n9U zVpgO5KK(6*k!YY9Ow}kG_#-2W^`Hx4M}SYj!S6&N+&HOS6n~^uWKqdE zEJ!{Qbq=K?pCi#EbX`kaoSxqu;RJk=a{=BKMfie(fryMygEdG?OPi~Vy7!hvh`6|M)wM5)C15hfElLJ> z0q6k`yyh-8T3Y9K7lB0q+6pLmw&o%TU$EQdU}jz6;Zo9L^rxksiBo|{QA_)vuk;AS z@;UzXgb-ZZw-u{UXCtuE$hy|oyz(QEI3isDW8gciK^0p2d(?PlVlPXxGc<3^XkzM_a-#^19NC9OZRhH)aU{o!<3aAObh zv(hFGU3V>JNW>CGY*&CGe@InI!V9p6dgeq=1!l-4M%L6@sT}-jTI8-&&HUU@_NQ7y zJ+FhZsP`2vYRT6;6L*SHqg}Xb>Tn%#qT-4V#9iHe$zac%!p!JL3SnA6#l z(k_esmqEjw76UiV*>bKMqmXTJG}&d2(`SK~(E|ko#sfpmftFB@M)o1W$c^x@+7E7; zSM-*1Ii6TW!wy*aqy8ptex&#s9!^fjLYK_uuRZweuQSHR=7`hignwnvy1{3 zO8_;$^xc4D;mjR5sI|TGFz{jxs@#)WA-(^}MvE77{nPAx9b5Je)>d#Rn1cIv{~|y# zuqHQazFbNg^bU6qHZ7+1s#Tx0Qm~5PQ{}$giNcs;8|`+ijQCIA3o>LbLWiBqDx!;( z$LQNnJ}alD;1%;;cz_Xox%F6JN${5uvDd@0T~SM?dn`nMN{vn46yoE?Q7<&!;5hhp z2HbS%f3*MbtMb$VbPqoG#FI<1o(0mA%t2F~yjdwzi`)+M-*q~1)0ZyJ^LU`8HJ7&b z#&Ynl`94?lC}UwSHGWWl*o3$iY{JRaBY@zE;~7G|c2q@7Hr6rcu^ksEQcP+{lcE|C z9^Q*(xy|AJ*B5@#^_?D!9EkRnE=VMfWIYAsiJG8GPC6+|F3pb-V095O3HBa-Rq4@YNn+n0|R+_gS1LQLz^ZbOH>Pw0MsiEwc* zlI)gyGbiA&V{Jj_i~f9$G=UU>-(B7z6l0Gfq|J+*!pelsda6aO2bpMT8-I;6ZN=5B zov+`FeC2r50Iq1&2*Y1cfgZ4y;(Hq*l<4T|^TlwR=FQ<4cP!utFm#Yh)A^an5IO(n z>1!CRQP&D$wnFi%fKnvUyQT)0$)Afew_8+vQ$WBAg%RN53XGr2`;hRToBqK5xg>Il z1~Z{Hv%?U{O?w%R+=<+}An>IsM*i-)Ur4%Cb!^;NLR=i4qwrC<>C%4UPqfc`%i1h` z4(}xDEz;?dz-dYFI|N7EFS|Y+nL(@mUMR0cXR;#+@{Y(g#KpG~Hcaw~=i4Yyur2F+ z<14C;({cFeZVEDkvSfPxkkgo#l1spT9U{ zFjdyJV`vWH4YGfY%Va#N1lW=6l$1A<@6>y_{X$DD^ybKZ&=DYqLN|djglKEc?S~g+ zXJn!Jz1K**;1706IEP3%6sIo&Z=RDRd_?4YtwDU(!hKym?i=XX_ITR?~B)MZS($bow1Is&^E1}<6 z&xRTfW<`OcZ!K`ZBEBYqngdJTTM8jZMMZ2xL9p{IC6^A6fnb}@)9yg}2el`sVc&@{lO*hbY9i2a{^?rf*+^p-zF0ZbI!1gzQKd>*ChZh8N169eiO zgxi-1<4x-90E@lUyQ}jR78^cT&+o$CimYTQmt+8f6D)tAzI!;(aQnF1;7);Y_yLx9 z&nkp0G<=Md^Nu|e`T&t#W+kF}Jo;RD;?#Im3|Qb}v3aj}+H}SEoXgx&jmHVHH^K?x zi`g*rY9R#AOFEVRjmmR5BFm|S+r9ljH5F4TfU!;gy}V4-EhZ;2 z9dzVFoYSG`vj!`Xcura4uqH<}QFR1rT$@P(*J@lO5k%U4;VGuas%zl%j1u0&88E{I zVngU)iRsR7();Dd=UOND4Tya$n+5i`!}gDa0`q@}D%82u!HcOuQAQ zBi@hPJN9|)xqs!DX=yhy@=T~YD1E~i$lP@)(fGrlV*x64=V&l>W>z?XY5pCoiqHCt z2;e(9U^RofR>j+|E+fVdo3=i)m!OBMJ@8} z)UvYdx!J!GwzsUpa#->R_vmthcV&L53S+Gxa~x`s-(M?Zk^ifKz5h5xWM{INHwN67 zG=TpN2_THl)>mueYtS2Xxg!|Wfw>W~l3rTaC_TsncTd4g2gutD{9x8hpE9QBE@uA` zx}0aN*vb-jy`OL37UF)ppcm__A{Iu*uE~8z`X2J(QS-;SsJoN;ZQF%-3u}yCcC8LO zv9hM4-K&y|l6ag6=;~4P$-O;yv3CDXIGwC9e3dep!Hw%1su(K$23d=|T&eFZ-?An8N+DA717O<;b^w-3%;gg*=6i?fL~L*{`cV zCu>=~3dnu0@-|yQA=X`b*=?ppBa}biBs&`-pE5QBxeIu*(*BTHCVXqYjkWk}#hovf zE~#8I0T}2jacH;Xl;$M7lB4~4U$6G!Ycf9};lnNLp}@7-1|wheG45-g%28;N6_C2Z z76-+)W-VXGr`flBEuTMJJ!o?_NdK%6W`*=v!i}Bq8X^1zC6hWo<3Ap_htAL}MW%Jw zlIb5S@7VOqQaz6*#dHgjR(=B z^Wn*5)`i9dJ@+#Ev`$6H10eZ)*JX3`Cg|Bi=68G%cO53fWaMOhTh;#PLbQ!GN!~P& z1~nf?pbB$d3;B7oyy#{3JRGC){F_N~`^X@a!Qec7Xuh=PJ)z}q(6UlPJbT116>GeC z>$xK{X!26>?Y@BC&26x=2aIRAL7{XgQ&VS^qDuCyJAzCa$TI-9uty-z+V@3Pdwy~v zjT{$7P>t&D)b4NW`Seo7T86VdvNf(9$VCR$C)&v^?XrK@@iVwv!$rZLCMY|-rx+XJ zDwt5caq-adJX1ydlnST9W}LuinU2x5jaBM-*To4x=Pxl+#{bSwe6~0z$Vl+{UlIzC zVL8@C@(*8SX}o}_KvoS}uk#oK@i66tkkRsVe!Q&qbYO~O;1LP?kS`h?PQe3QCww@$ ze6e+HU#Uk1NX9=IJ}&RGZ-pYE-W_1jrruDME3+ z5MK5j5dl#zn6tCr36o>G$gZ9|V*>!%{%~R7aFd3|Y5m=GTT6o5H=oVUq*H zqg+-)3Km4hc68%0t z!PFEVXIEl8>~xM6>FM5My9$>zTpHlcx0_mAcCnjN5lhb0gl0|4&Dsk=*~;AK-LKAP zhFtDcvt8uXZ95(oS@mZ7RjQif1s&g{6TMDt>yA@mi0N8go!SWpkE1(JwTNBq_tm|E z)Sj>Tp@YK^AfgLwS*!^BN3-3j7%iNN%L<7BZ~`5%&Dudvp5DHGm+0PBk&C2p_kc*{QcBS-YTjwrAS{~N5ZQ(KS0aBgsZoc;O0A7FsOs3v>f7a^@9Lv3 zLY2Q@GILZ#OVgpWY4@UjpHfif_S@3&cFsE@ zre2Ha64Rq}cse;B8Ww%wWdB};On{w zo%dPtpHyzs0+y?%S7jPzf2I&qFS31_DZVR#4}~4s)g_a-og%NqOpUyYGDXa zz|~|+!k^dFnflKGFR!~?LHROQ9iNZjp1xT z%ScC`h)5TXW$(Pl}9mt}(3c)qWSw7WR|6gsi^ zllZXl>3O=BG^MlI&ZV?CtjcEFv#<=F4UHz^KMa39ibCcoW4F1)5p1YU`X;&2JziV- zVeH-I;g@{^Bc7a_A^&wX)b|jkx)ry?hNE)F%b8_2SBiUN^tmHvL3~}i`Bam8?bxNU zGP+8v1Dh<9uCX>%?RNjB0uCL<8ME1xHWs@M&6p_TbFQYzw)p*gnfEyYU`!KzO^a&_U`AoKNSU&{eOr4+^lzjLhytA~<0Kz_(f6b{ z8&mP|sB>@T%s8d&gj46K{-mhC`d%A~8O#XH%ZGc>2Wt6#7p)dlvHU(NoGlycHzZf< zvA9d`2S@eS@_pg8XQbjX$FOxU3Sjf+Sti1eGU)<4iu4xSGgi{yS|??6P;(+p&pu z#!VyrGap(Ru^c}veWq9A=-Te^@>p0puhgYmy{ywXKn?HEV~keLF~ zGd92MB+9hgJ`3ly?00Wn=1Q`PqCH?&&I{>chrBUGDcTwZ^1l@SM)`Q1X$AH!>dc72 zqn*6#ohsQQK_mDLVWlr&C7<{5jt2?@|Gl;>2o}r(2RdkYb@{W>;cOQK7vuB*pOL}u z4Jk<;GVRO-f-1D1kftWa^&5g-*u>j?``n|iVV}Ei`AM0qZU3Z_>WKuH0&Q8Ndxk}G{WM+gY&{Ji<(n_L*uR1a;nqm_Yvk)BWl;gV zZnm3hh)-X;rKLr0qh4iZO3$b{*Mk+5h*-03-5G+^5s4R2z3JZ4T<_unWZx4UV}UX9 zARWY+u^4YJ9MbpVwLm>Jb(F=|)7j&RUlQnx>wle#tM2!2YzqcHlHsXR6BdAyJw{ z;BNVT)a)2?C5sjrnTfUg6R4B+rc1L5IQ;b*6OTWw!60H4G4o3}wB}=b6Fb_1zvc=f z8dg4_#>fis)p^J7Jm!m?W*suhmg(0Cs#V}GEJ+wtC2wrNnE#yk*9DuWUvr)fA#hg^ z`D}pUYBXt!Gn-bwbC6lc z7#39+6n?fZreyS##qa8nZe}?97c%LoSCJ0_scG%7@2jSZz#G^t(8tFtiQRK|cl4nR z>)~7T?cIzO8;>OD-v8R*J7v(i_JI6+chP{+Oy6E9dwt@CrPzKI#L|WjVECQ&v7oG} z=d%4GUsW%|F0Uz+!Okl4r*khYL*kFDUU^0NT36m8peQG}M>E}RurgynxUJwj|Lqry zhIITg4deCss{le49d-!Z_wzSm+yD`N`n;cFc*~PF!a!lej>3d7Op2E@vr80g&i4?we%z#(o0m64&<83wg#RihCrU@ zCZrrpqkDR-x!JgE5U6ipfYbZ(i|F&COR0KYmBwAf>oKkF7dIXKX-6nuc_pnxxT_`S z8!z=+ov`_yH(#|bizFFp96Jh<$5q$S2!sI5zYnqNoAYjy-XcN%+s%ct^!(2m^h~in z0d=q&O;92F?VMuy#}4tSj-Z}DS96AngE15>cRT5K!1Ex^!O$&yZw#L($f_U7&CL;I zf`ClEQ>OK|=6zp-`&-MRPXYx%#qN05d*U=mK;d;4SQgH-PJ$Tc*yum_A&XqBV|s!B zpRkURC!S{sYhI_n+U5XxyY#0IeQB~*DuBuwr4w0*%tC3P6#uvS8d1;Ow)5WwTz1&4 zr{BQuCLkNwJ^R;>JtmYC4-^*~CtG7-RUVJj+nY`LeL%Ohrxi8anArF9NrkX-sejAT zzHu2@qt8nB`sdj>V;4WgfJ5lY`}n zH-(R|!+|7GU#etKiv6L1h6gBSrp?1aqf&3EAlZPlUcmiWare)&Px4&R_@LuywQd-p z8_5%l2UmIK%u$1KPV}0Fsp-%~5I>G{eIZv9sX{k@e#9g*v=B!M)E=-e!*0pP+9m`V zELATfT!TD|D2hFCQz|-QjS%3!FhIrdyf>9)(X40%`lR35M_hHozYmYH0EH!^xcGv3 zoTK|l!BNYW9)W8VKH;l?(11ZqZrH6ih+)UQWmvsMDt55E1sD(jjIHX5#y5D!q;n+$0Oh+2V!REpxWX$xoc@g9 zw({Pzj&8aHmkReJ>d5`9pQz5HAFZ4;J(|-=s+t9 zEzYlC!oK04&)IeOR$41zhgc%F8nr1CjX%BOLoE(+Hr+vSgl zn5Ncv%1-X^XYO3toQ}-rw)1X~;+6IZ;C+(De|QwW-nmf-qrt-k$bA*E@!8Ee+K6xt z=55bh53*NMZOB6q^f(@^H6Phq>w-+~NJ&quw=%vy{WX8`#yQ8XWNF)E&rN^+^mnhY z#|Z& zsLP&E4JW))FJ<>SHyem1la!NlTrD8^FFLx|LphWm!x$#FR4Mt$jlJqBN+#+ZzF&o5 z;kkBPuTV;&F^6pUV4F2X6CT`^f`#P7l;LT9mRsneV+_{}$aK<&w*b5HGODgvxMSe=t)s%f=g{X03fjNN%Q`EqZ20_h*ujVodgj z;yG*)R73y9hw38*_U11XSo~ zQ3Gp=1!%t&!suR4S2rRmtzf1czgJyY-{FZfn#}pYtX&)2XeWQ8E0}Lib~EX>N9N1x z<2JeTvcN@m*7RJ=o@ThGa$s3q=n!4%=eNbq6ZQ#(j3ZZK6BPm*8^>}Yc0Usq-quF~ z1kQZ*G7Va-lE^LdGivUF*1QyuBd*6he)^6ddO&||$%xNB7J^fmnp4mDVs`5WQv^uB)X4=MT4 z3%Qdg{-;%eAOFovtnH^CLorA`dV6~-?EnSQixIvf^9|J}x=zJjM7}HsK?Klzs}Kt< z8nN`fQ`KEXxojph03D?S}c*^f-Ghk*~;{EYfu z>gr%Fc6%gwszUeF+rDbe>pNxd;Mr=EEI@p3fUV-_ohx}m6&fC{xq&a@J(5KlSK93M zDRyH%qEAi@q}CES#5QfGvv>h-Y!)P25)%^o00`|1$EEw~4iT-&316@B9Rk`B-!nCd z69hiel*HWG4IQfJN#I9tqpEM*Zmb0ny9ZrizXICQXND||H1ALgzL2?t#Cwv~PUPt5 zd%Yx7&|6vF$rRB&$}#ZZH}{y)T4BrT)bH7kYT^!R8M z72Pj@mhndv>pzmMZ&eE?b3dUFvT{S3kL3OpTjK|xT3S5Xa>j7cmaZvHE{@fvCdw2- z5*R1eJQ#rOpBnA~An9m$ONtuu^`k7`hXhctjK9Aqw&*Q2->RqSq&*0<>}=)Z@3m?(euAurl&T$6Vo~u0iy?A*6@N=AX zF1RRI!?>n^r+E@{E8S0!Yw0q7dmtF~)!uRoSD7YCm5kwF(p8F>Ju#nwufo4@=s)n_ za@-nB!lKuozEfi+0wK9(F zgwt!4U&mn90*dyS`9;F?iwV^tV1zrPbpaKZ&6|h~2A5a`= z(*6tfRFg|cwqfHR3EdN?ja}N#vkWWr<+Ld%*=;&e{g5N&^oDCa6N=i8GwA><#3}^p#R_&vQ8)Mo`*Vc2IY%oKZ+M0gqwA+J%(*a1>+`y9m zDmeJJ;vuz@-!sDFCx4L@i)gC(v38vh3Z8dK7;{B;Ns>EAMPc8M3qF|XlT*LHpfj(5+O;&T(o z50~^m9rB-wdU2f8%+dAPU1*zKJzF-|Oo|%dm~ZWkvKNXx3U^==B3~E+!YzoA^Ce?< zzM`|f{JXJMXZngTw#zW;nZ#4X9>DpKDdTYd@nNjoi7IDk95mVQI|T|01$cS)g4Wwi;aymNtxB3Dy*M@oF06nw z5IA8tQu2CGyPA8UmJF!TCy>G-d)0$K`>}`i-Buy2RLvj0ktyQC+qB|N=5uq5xk!HX zs*HVo2);PZn)`17_S;yU1OXLC&c!Y{Jzv-N1UcETv8J{_{eTkLIsaaxr9j(9fwx8p zPj+ba9iff zA52Ks-l)v*wm^EW{PKmwA?+)s%?bH#{hFlxFFh;AD{U=Tv$}V8yV*g!l7O!%-{=jT zlC`e?NrFVE#YC-_0UNW*b{9oi65_NWaV|KI{pHfUYi|jpkbNZ;BW-zvhJRB(E<7Nf zFbwCAa9K>2s21h0!hr^r(fGlQBV_GZ=TWv8koa_Z!?6~14g+4(;-O-6VM7#Pu&36Q zRE^L@WJhiUcKu@iqe{9Dw|=*E*jlJ>4)KYIxSY47Dw{XZu*hGoo*aduPwed0d}3)j zXI2DMJ^d3^*ablDuMh@o<>Gz5_CG~gov)H^OaPUGPbnX;Ey&w2jkkWj*Q52M?IP26 zcIN!&UGT@d59#?I{pQlDDf2R*=5t zJUc-IbUue!>D9VR7H*zLfn{#|D&oTwh67n^SWApWTeTo-V7EHFelihP4+ zf#`eGD+G3DY*RIX>CiILoL zdaPIc9+nB9X>!{9e1Cm35=p=WP@k_J#($N!Kka~O1-+e;j{(N{fZkzvY!s>&IW6t_Kz2G< zqGj-Dxr&U12jTu|4?AW>kpldUk1K8P$Yd~GQ@LT|B&=4C6+5eMmPQ0;{^v9Lq3j6S zf-eKl?O%m<-)Hqc@x+rt>1}Obzp#haWzNhrPgp!eIxZh5`_9oLC!NabdCAJ5*MbIBVKM}VeiT}2hg>VugPTra`ru9K@y4$`OJCz zSAGnO?5tGn+jewVRsM;DT?Uo}IpNV&LWE36&2Iyf{9eAe=!kQ{A73PWM8pR*U*5GB z;cZ_j@qF8;89s7e$fB13Lk2202_XTgWmsC;j|e-IPu(>v`MgHCJg1k5kaorswqN|m zu#aAUO4R)b+ePI5sUi~6;yj2U{`XY={sZr1d8||dSR|j<=aHZw!W0U(ol-=`3faSv z`4|2!x_oiJww*cJ9X$NWMS_9tqYNxbKq3@fwfC#LYx52>NV^PMhs29=Fypmwjn$=G zUH-A+gk^t>m<7{q)LFp^zxz06+2@%^U-+S2J9oR{e0v=MAX+qmjm+Qa_IH`GEF~$F zHedw|R-7@u28n5r+(k+FDBNFs{y+#Pmn|afU6nW@tJ^zT*IO+J0n+zyDL{dTWrCm4 zK6*0!qOAf8vP=pw0axRqM+X)%&-)Eu2gA!nh$Xx%!mxBHo6>>y{ZJFzs&ryHa4>jc-q> z7V)knzMABBwDY%P$3Hu{q`s?oOG}G&POvFd|DqRiA9Mzo{m#lRGBFhkQ7r3_NFfn~ z4>nBA9CILU=dyVq=^8&J*br*R{HB^s;-~@uLdwOx((%dC%0E;7{Kk$U*1xX{_1M9N zZd%&c={!Kt0(qXW73O$MX&s9eNY+wYq9v>BqMoT4XoyOX$kDY08O_yI;Lq zPsr^#*N(Ww$`ao5o&A(*6)nWF^G|Z3=IFz0)3ccH3|of1TNb7*a$0&S2UArFs*5}O zW2A-UqfS0My5T*R@C>PoZ`j6U8P2PI+1>}oIrU8P=w8%Hw3%>grk(s#uREmk%Esf&jja{?eA8$vk(ce5lpB(zb_27_TU7lJ(3LK9k#eL{S|NG zmO!fwoEKzbwgvN=wH4@eVj`3Glij2U74g=bH_<*L+Z%vrx7!RhA;szxwoIFy?KIV- zo#`rEq^&klzY9k&5`2`3aY7hibtiBB)grcEZ;53NaI|t7^ zW{&?mMZXeeEWQ9>z{?DP5am)uIOx^xp_yf5f#NeLf8z25gEYt=nNTZYqh*3mNlC4> z%pbnY?HktQGJO4&uvw24(7BBta(GPrtZY#&03=IAX18Zlt1)r9tv>``NcbDvTj$R# z5FvDB?MKOYpB$?*#U09wY-eg0h>aR;6#-tmFpKpSsM%6D|7sYJu7-W78f-tgaQZ^B>9NaiUE%L+v8^=*0CiLE#`F2z=swr9D4ssw zx@OM!JcHP9wdy8{xeIOv5R>k4JD)ePX6Y?ceC9QS+3Z{*PLwDUwHjy*Mfk##LvLtg zbm0KjAbnmnj#T9f=(-eI0Wo>}EUC^M!Kt^E`Dz(u{Hw^d_48}s&;96T$j zw)mS66n1f@FrMs%EN$Bw0#hn))4%nULrK-NYFpt&wM;C@5cq@{RpMs!7QX(oLciQY z2lh*DVs;iFo}V9#LK11fkAeQfz+D;<>v;gk7)zya!;4uF%R)IiQgtf&P2s#fEfz?9%lp0h&-f341JY{+6a1reh*NhqMd`1Xil&~k#O zr%b>cqv=l)vT%FN%6DUHu#aU)S@dS&vYi%B0OQroM(jD&B3A$1&JK$?N0w@gYDO5F zA0xhY7?M!UG0$x=^k8Q z!|NEFh(t{w1!~nM4tmYPbY{v%ft~)!Kbi@zJa0Cy zVUdw_9=5=O27P-^mDanILp^oq{_)n-HJC!{J(w0cnl$F&NFfH$~&Sk1gH)v{|(CX`q8Zm*4JqHy_m&%z9@t$ z=A7zg*A*wlb$6)BYhy{ft?2z?(JyIzrsLlW_{c6ebj!CSuriFkMu+4>k!UPEwgPo zPe!gs#?qnqRe8+c0;SB!o(XKE{6)i47QiGp-AFmJkH2fWRcLaH=ICPztsp}LW??=m zvv!WI+;VvY4UPL1aBOrC_;xzR>i0gOYMBkbcW)fj#pFg=)S>utckTLaz;l0=w%c3H zQY9lyjE?{Svt&lnWIoav930%YHs7E;XQNy1ue9PNLSzmKs(3l?m&V*NZ$wYa^@A2x zs5}S*RU-fy(&f}5e%fs1uLVqIefBp3hBTj7bLkRG9|JWJTSec{;{C?x4U6-53Hj^{ zbIfMrKe<)3__J(AnOQwtx!#EP=GJt{0SYK`L0aJDz!qQ{gd@Nq`8eNv#q*&GB`c-D7PAv~He5)^XE1L}8tue0*e&a;$e?GXLp`D-7N^LdgJKwe&&UQc+U^z zjM%vN^M|6R4dL?oeIA?pVZ>!#ZyE{Fr5%5~+xg1w7_`|z9llcn$3%*tehHu3!?&#AGrcV7D{RFBnG+ibB<)?4wzU7gBd;A7%!Xe)iiWfLgY2Gim+tRK&gG?tw zF_CEEQFl7s)r~kNM`OB8+U-SsbI>(2bpaXn;riJ|Ol2ffAztO)FihDF0q7c>6By%L znBrS(Oia{w$W;+cX&mleb3`5LJ@O%D24b`!3u{yx+GZn;qS)RQlOMTV99JvotrcWZ z^e&8VR|GJ%0_T#!AqX3>aZ&#SXln;f36O?ciGWj@nFjA&`di8CH;2(UFz5cVoREc3 zr@ybtY;ec)%u~v+Z6mq;RoNnJPh=YAx;2YVw#cF9*diQgA+GEcxCJFcY}Ka*kP;}D z)%60_M+V;vW7{4PZHGLbW|6$|UmOa*N!q+vYLs=rX;!{T)kn;dD~@Rtdm(JP8*rn) zny~9&6UDTFwc7@MdMT_7i^h7K_uKMGW}IyPb@ZYMWknb#?w4i2TG%=pau+rRRcIB? zV@Tjh6guKuwVwpPlhFiPZvX_+nFUc?F}j&l1Whc6>_vQR>1jt@w%HBvYnwG)?%2g6 zBltFgVGP}d`!zwgH3X??jVD0tF}6Wu@HL3u06yUZiKstG_UMw^4jXHxM<9(mwl`<4 zo@!peNx-T*mbdYN_-oUfA>IPbb_qXE$Z1gVh z9@MD+cj6bz#-`zq5^aX0>*%sYo^s$ghu35BJHRUQC)oK2tVcr&pfqhLq7+32Omm1k zAo(N8+eUP-enjNzWQxfT?Gs0rp+r9!C?i`cs?kGdMtt=;5=@B#;lo z0UitD@Lc+=emn6UOOW~vFhW)PS|I3QO?&*0UD$tSN}{^xvL9p7!jM2YgzQ1@_l=gk zL|BiHSAyf7CSJ1^ew)R>!Nrw5NAqjHAA4;8w|*7U|DnvVItCip)zO`n^RtHm0aT3O zi|vXwizIKOxzVCKu^x%l5X2J_9xk49l616r7OPPw!hdoftAnH`9j^G0EdvbK;CvzF zMs4OziP!UWr=3_^O`5%8LUAF*#YJ^VzcIh)lPpVZG=WqX-GiG6eqmmVGZ5ILf{?IY z#~_EIxcqn%o8Fzwz4QA(N2M;Z^*SOvf$?GL!fQP$x?RjisJ}DkhME{t7-N2xaUKg8 z8zR4=K1IWsp7nD2O?kYR+DA9{4i|vc11xi*^Tnog5?i4Kwdu(N$%RudNl^d=07X=OUWEjf$ixW8(Ek` zfF{i(Mhdtdv)}Bu0pC;W%xMWCtEXVJWq)Nl`>tYKOuUVc0u4ZCLdjW%_0`Uy*+xd@ zp$Pf;6(7;980<(%(N^Op0|-y70T5h%{rz7j-J9-CKy+3fsU?pr&g2>A zxg!H39L9s)qP zF4}E6dd>>+tqoE+KNfML!sls$K)Or+lhSey;?kfny6Chm`taKZxBQb!koe?Tt(gWPyh%}6=>CE{CH|}ME1T1pZ+6Xr= z1cDgY_F#g@0P5ZalfIHd)-=2U1EG!+l%D@;4(4__~4kf8Prb8K4h!2Wwt7 z;=bu>`}=Fcss@{u0W^M&Q~W_G3|bb11h&M8fzN-+NjH9stEvjdL&illlz4v~M`ek- zSGY@8?UwDm^^m`Ijq7PyW#a{`=>I(a#{&PC1)kR^$-e_%RRMZ=|J+KI`|pb`{+|yU Z1Z>0{{n*U1S|jm literal 0 HcmV?d00001 diff --git a/raid-survival/client/systems/camera-follow.system.ts b/raid-survival/client/systems/camera-follow.system.ts new file mode 100644 index 0000000..3af127e --- /dev/null +++ b/raid-survival/client/systems/camera-follow.system.ts @@ -0,0 +1,26 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { Position } from "../components/position.component"; +import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d"; +import { MoveController } from "../components/move-controller.component"; + +const CAMERA_SMOOTHING = 0.1; + +export const cameraFollowSystem = (registry: Registry, ctx: Context) => { + const graphic2D = ctx.libs.getGraphics(); + const entities = registry.getZipper([MoveController, Position]); + + for (const entity of entities) { + const viewWidth = graphic2D.baseLayer.width(); + const viewHeight = graphic2D.baseLayer.height(); + + const targetX = viewWidth / 2 - entity.Position.x; + const targetY = viewHeight / 2 - entity.Position.y; + + const current = graphic2D.baseLayer.position(); + graphic2D.baseLayer.position({ + x: current.x + (targetX - current.x) * CAMERA_SMOOTHING, + y: current.y + (targetY - current.y) * CAMERA_SMOOTHING + }); + } +} diff --git a/raid-survival/client/systems/clickable.system.ts b/raid-survival/client/systems/clickable.system.ts new file mode 100644 index 0000000..56a6685 --- /dev/null +++ b/raid-survival/client/systems/clickable.system.ts @@ -0,0 +1,28 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; + +import { Position } from "../components/position.component"; +import { Clickable } from "../components/clickable.component"; +import { InputEnum, InputLibrary } from "@nanoforge-dev/input"; + +export function clickableSystem(registry: Registry, ctx: Context) { + const entities = registry.getZipper([Position, Clickable]); + const input = ctx.libs.getInput(); + const p = input.getMousePosition(); + + if (!p) return; + + entities.forEach(({ Position, Clickable }) => { + if ( + p.x > Position.x && + p.y > Position.y && + p.x < Position.x + Clickable.size.x && + p.y < Position.y + Clickable.size.y && + input.isKeyPressed(InputEnum.MouseLeft) + ) { + Clickable.onClick(); + } + }); +} +// * Required to generate code +export default clickableSystem.name; diff --git a/raid-survival/client/systems/move-control.client.system.ts b/raid-survival/client/systems/move-control.client.system.ts new file mode 100644 index 0000000..b2b70d9 --- /dev/null +++ b/raid-survival/client/systems/move-control.client.system.ts @@ -0,0 +1,19 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { type InputLibrary } from "@nanoforge-dev/input"; + +import { MoveController } from "../components/move-controller.component"; + +export function moveControl(registry: Registry, ctx: Context) { + const entities = registry.getZipper([MoveController]); + const input = ctx.libs.getInput(); + + entities.forEach(({ MoveController }) => { + MoveController.movingUp = input.isKeyPressed(MoveController.keyUp); + MoveController.movingDown = input.isKeyPressed(MoveController.keyDown); + MoveController.movingLeft = input.isKeyPressed(MoveController.keyLeft); + MoveController.movingRight = input.isKeyPressed(MoveController.keyRight); + }); +} +// * Required to generate code +export default moveControl.name; diff --git a/raid-survival/client/systems/move.system.ts b/raid-survival/client/systems/move.system.ts new file mode 100644 index 0000000..536d1be --- /dev/null +++ b/raid-survival/client/systems/move.system.ts @@ -0,0 +1,16 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; + +import { Position } from "../components/position.component"; +import { Velocity } from "../components/velocity.component"; + +export function moveSystem(registry: Registry, ctx: Context) { + const entities = registry.getZipper([Position, Velocity]); + + entities.forEach(({ Position, Velocity }) => { + Position.x += (Velocity.x * ctx.app.delta) / 1000; + Position.y += (Velocity.y * ctx.app.delta) / 1000; + }); +} +// * Required to generate code +export default moveSystem.name; diff --git a/raid-survival/client/systems/movement.system.ts b/raid-survival/client/systems/movement.system.ts deleted file mode 100644 index d9b7139..0000000 --- a/raid-survival/client/systems/movement.system.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { type Context } from "@nanoforge-dev/common"; -import { type Registry } from "@nanoforge-dev/ecs-client"; -import { PositionComponent } from "../components/position.component"; -import { VelocityComponent } from "../components/velocity.component"; - -export const movementSystem = (registry: Registry, ctx: Context) => { - const entities: { PositionComponent: PositionComponent; VelocityComponent: VelocityComponent }[] = - registry.getZipper([PositionComponent, VelocityComponent]); - - const dt = ctx.app.delta / 1000; - - for (const entity of entities) { - entity.PositionComponent.x += entity.VelocityComponent.x * dt; - entity.PositionComponent.y += entity.VelocityComponent.y * dt; - } -}; - -// * Required to generate code -export default movementSystem.name; \ No newline at end of file diff --git a/raid-survival/client/systems/packet-handler.system.ts b/raid-survival/client/systems/packet-handler.system.ts new file mode 100644 index 0000000..8443871 --- /dev/null +++ b/raid-survival/client/systems/packet-handler.system.ts @@ -0,0 +1,32 @@ +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; +import { Context } from "@nanoforge-dev/common"; +import { movePacketHandler } from "./packet-handlers/move-packet.handler"; +import { spawnPacketHandler } from "./packet-handlers/spawn-packet.handler"; +import { directionPacketHandler } from "./packet-handlers/direction-packet.handler"; +import { killPacketHandler } from "./packet-handlers/kill-packet.handler"; +import { joinLobbyPacketHandler } from "./packet-handlers/join-lobby-packet.handler"; + +export type PacketHandler = (packet: unknown, registry: Registry, ctx: Context) => unknown; + +export const packetHandlers: Map = new Map([ + ["move", movePacketHandler], + ["spawn", spawnPacketHandler], + ["direction", directionPacketHandler], + ["kill", killPacketHandler], + ["joinLobby", joinLobbyPacketHandler], +]); + +export function packetHandler(registry: Registry, ctx: Context) { + const network = ctx.libs.getNetwork(); + const jsonPackets = network.tcp + .getReceivedPackets() + .map((packet: AllowSharedBufferSource | undefined) => { + return JSON.parse(new TextDecoder().decode(packet)); + }); + + if (!jsonPackets || jsonPackets.length === 0) return; + jsonPackets.forEach((packet) => { + packetHandlers.get(packet.type)?.(packet, registry, ctx); + }); +} diff --git a/raid-survival/client/systems/packet-handlers/direction-packet.handler.ts b/raid-survival/client/systems/packet-handlers/direction-packet.handler.ts new file mode 100644 index 0000000..c92da57 --- /dev/null +++ b/raid-survival/client/systems/packet-handlers/direction-packet.handler.ts @@ -0,0 +1,13 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { NetworkId } from "../../components/network-id.component"; +import { Direction } from "../../components/direction.component"; + +export function directionPacketHandler(packet: any, registry: Registry): void { + const zipper = registry.getZipper([NetworkId, Direction]); + const it = zipper.find((entity) => { + return entity.NetworkId.id === packet.id; + }); + if (!it) return; + it.Direction.x = packet.direction.x; + it.Direction.y = packet.direction.y; +} diff --git a/raid-survival/client/systems/packet-handlers/join-lobby-packet.handler.ts b/raid-survival/client/systems/packet-handlers/join-lobby-packet.handler.ts new file mode 100644 index 0000000..7dbcdd9 --- /dev/null +++ b/raid-survival/client/systems/packet-handlers/join-lobby-packet.handler.ts @@ -0,0 +1,31 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { Position } from "../../components/position.component"; +import { RenderableComponent } from "../../components/renderable.component"; +import { Context } from "@nanoforge-dev/common"; +import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d"; +import { Clickable } from "../../components/clickable.component"; +import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; + +export function joinLobbyPacketHandler(packet: any, registry: Registry, ctx: Context): void { + if (packet.result === "success") { + const startEnt = registry.spawnEntity(); + registry.addComponent(startEnt, new Position(500, 500)); + const renderableComponent = new RenderableComponent( + "start_button.png", + ctx.libs.getGraphics().baseLayer, + ); + registry.addComponent(startEnt, renderableComponent); + registry.addComponent( + startEnt, + new Clickable({ x: 500, y: 500 }, () => { + renderableComponent.sprite?.destroy(); + registry.killEntity(startEnt); + ctx.libs + .getNetwork() + .tcp.sendData(new TextEncoder().encode(JSON.stringify({ type: "startGame" }))); + }), + ); + } else if (packet.result === "full") { + console.error("lobby is full") + } +} diff --git a/raid-survival/client/systems/packet-handlers/kill-packet.handler.ts b/raid-survival/client/systems/packet-handlers/kill-packet.handler.ts new file mode 100644 index 0000000..288bbb9 --- /dev/null +++ b/raid-survival/client/systems/packet-handlers/kill-packet.handler.ts @@ -0,0 +1,11 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { NetworkId } from "../../components/network-id.component"; + +export function killPacketHandler(packet: any, registry: Registry): void { + const zipper = registry.getIndexedZipper([NetworkId]); + const it = zipper.find((entity) => { + return entity.NetworkId.id === packet.id; + }); + if (!it) return; + registry.killEntity(it.id) +} diff --git a/raid-survival/client/systems/packet-handlers/move-packet.handler.ts b/raid-survival/client/systems/packet-handlers/move-packet.handler.ts new file mode 100644 index 0000000..0e6c814 --- /dev/null +++ b/raid-survival/client/systems/packet-handlers/move-packet.handler.ts @@ -0,0 +1,19 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { NetworkId } from "../../components/network-id.component"; +import { Position } from "../../components/position.component"; +import { Velocity } from "../../components/velocity.component"; + +export function movePacketHandler(packet: any, registry: Registry): void { + const zipper = registry.getZipper([NetworkId, Position, Velocity]); + console.log(packet, zipper); + const it = zipper.find((entity) => { + console.log(entity.NetworkId.id, packet.id); + return entity.NetworkId.id === packet.id; + }); + if (!it) return; + console.log("Hey"); + it.Position.x = packet.position.x; + it.Position.y = packet.position.y; + it.Velocity.x = packet.velocity.x; + it.Velocity.y = packet.velocity.y; +} diff --git a/raid-survival/client/systems/packet-handlers/spawn-packet.handler.ts b/raid-survival/client/systems/packet-handlers/spawn-packet.handler.ts new file mode 100644 index 0000000..a5ff8ee --- /dev/null +++ b/raid-survival/client/systems/packet-handlers/spawn-packet.handler.ts @@ -0,0 +1,53 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { NetworkId } from "../../components/network-id.component"; +import { Position } from "../../components/position.component"; +import { Velocity } from "../../components/velocity.component"; +import { RenderableComponent } from "../../components/renderable.component"; +import { Context } from "@nanoforge-dev/common"; +import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d"; +import { Direction } from "../../components/direction.component"; +import { clientConfig } from "../../main"; +import { ShootController } from "../../components/shoot.controller"; +import { MoveController } from "../../components/move-controller.component"; + +export function spawnPacketHandler(packet: any, registry: Registry, ctx: Context): void { + const zipper = registry.getZipper([NetworkId]); + const graphicsLibrary = ctx.libs.getGraphics(); + const it = zipper.find(({ NetworkId }) => { + return NetworkId.id === packet.id; + }); + if (it) console.error("entity with networkId already exist: ", packet.networkId); + const newEnt = registry.spawnEntity(); + registry.addComponent(newEnt, new Position(packet.position.x, packet.position.y)); + if (packet.id !== undefined) { + registry.addComponent(newEnt, new NetworkId(packet.id)); + } + switch (packet.entityType) { + case "player": + registry.addComponent(newEnt, new Direction(packet.direction.x, packet.direction.y)); + registry.addComponent(newEnt, new Velocity(packet.velocity.x, packet.velocity.y)); + registry.addComponent( + newEnt, + new RenderableComponent("player.png", graphicsLibrary.baseLayer, { + animationsKey: "player-animations.txt", + scale: { x: 3, y: 3 }, + }), + ); + if (packet.login === clientConfig.login) { + registry.addComponent(newEnt, new MoveController(clientConfig)); + registry.addComponent(newEnt, new ShootController(clientConfig)); + } + break; + case "zombie": + registry.addComponent(newEnt, new Velocity(packet.velocity.x, packet.velocity.y)); + registry.addComponent(newEnt, new Direction(packet.direction.x, packet.direction.y)); + break; + case "map": + registry.addComponent(newEnt, new RenderableComponent("map.png", graphicsLibrary.baseLayer)); + break; + case "nexus": + break; + default: + console.error("entity type unknow: ", packet.entityType); + } +} diff --git a/raid-survival/client/systems/player-control.system.ts b/raid-survival/client/systems/player-control.system.ts deleted file mode 100644 index 5944864..0000000 --- a/raid-survival/client/systems/player-control.system.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { type Context } from "@nanoforge-dev/common"; -import { type Registry } from "@nanoforge-dev/ecs-client"; -import { LocalPlayerComponent, PlayerComponent } from "../components/player.component"; -import { VelocityComponent } from "../components/velocity.component"; -import { InputEnum, InputLibrary } from "@nanoforge-dev/input"; -import { RenderableComponent } from "../components/renderable.component"; -import { PositionComponent } from "../components/position.component"; -import { WorldLayer } from "../main"; -import { PointerComponent } from "../components/pointer.component"; - -const SPEED = 200; -const CAMERA_SMOOTHING = 0.1; - -export const playerControlSystem = (registry: Registry, ctx: Context) => { - const entities: { - LocalPlayerComponent: LocalPlayerComponent; - PlayerComponent: PlayerComponent; - VelocityComponent: VelocityComponent; - }[] = registry.getZipper([LocalPlayerComponent, PlayerComponent, VelocityComponent]); - const pointer: { PointerComponent: PointerComponent } = registry.getZipper([PointerComponent])[0]; - const input = ctx.libs.getInput() - - for (const entity of entities) { - let dx = 0; - let dy = 0; - - if (input.isKeyPressed(InputEnum.KeyW) || input.isKeyPressed(InputEnum.ArrowUp)) dy -= 1; - if (input.isKeyPressed(InputEnum.KeyS) || input.isKeyPressed(InputEnum.ArrowDown)) dy += 1; - if (input.isKeyPressed(InputEnum.KeyA) || input.isKeyPressed(InputEnum.ArrowLeft)) dx -= 1; - if (input.isKeyPressed(InputEnum.KeyD) || input.isKeyPressed(InputEnum.ArrowRight)) dx += 1; - - const len = Math.hypot(dx, dy) || 1; - entity.VelocityComponent.x = (dx / len) * SPEED; - entity.VelocityComponent.y = (dy / len) * SPEED; - - if (!pointer) continue; - if (entity.PlayerComponent) entity.PlayerComponent.target = pointer.PointerComponent.position; - console.log(pointer.PointerComponent.position); - } -}; - -export const cameraFollowSystem = (registry: Registry) => { - const worldLayer = WorldLayer; - - const entities: {LocalPlayerComponent: LocalPlayerComponent, PositionComponent: PositionComponent}[] = registry.getZipper([LocalPlayerComponent, PositionComponent]); - - for (const entity of entities) { - const viewWidth = worldLayer.width(); - const viewHeight = worldLayer.height(); - - const targetX = viewWidth / 2 - entity.PositionComponent.x; - const targetY = viewHeight / 2 - entity.PositionComponent.y; - - const current = worldLayer.position(); - worldLayer.position({ - x: current.x + (targetX - current.x) * CAMERA_SMOOTHING, - y: current.y + (targetY - current.y) * CAMERA_SMOOTHING - }); - } -} - -export const playerAnimationSystem = (registry: Registry) => { - const entities: { - PlayerComponent: PlayerComponent; - RenderableComponent: RenderableComponent; - VelocityComponent: VelocityComponent; - PositionComponent: PositionComponent; - }[] = registry.getZipper([ - PlayerComponent, - RenderableComponent, - VelocityComponent, - PositionComponent, - ]); - - for (const entity of entities) { - if (!entity.RenderableComponent.sprite) continue; - if ( - entity.VelocityComponent.y != 0 || - (entity.VelocityComponent.x != 0 && entity.RenderableComponent.getAnimation() != "walk") - ) { - entity.RenderableComponent.setAnimation("walk"); - } else if (entity.VelocityComponent.x == 0 && entity.RenderableComponent.getAnimation() != "idle") { - entity.RenderableComponent.setAnimation("idle"); - } - - if (entity.PlayerComponent.target.x < entity.PositionComponent.x && !entity.RenderableComponent.isFlipped()) { - entity.RenderableComponent.flip(); - } else if ( - entity.PlayerComponent.target.x > entity.PositionComponent.x && - entity.RenderableComponent.isFlipped() - ) { - entity.RenderableComponent.unflip(); - } - } -} - -// * Required to generate code -export default playerControlSystem.name; diff --git a/raid-survival/client/systems/pointer.system.ts b/raid-survival/client/systems/pointer.system.ts deleted file mode 100644 index e0a56e6..0000000 --- a/raid-survival/client/systems/pointer.system.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { type Registry } from "@nanoforge-dev/ecs-client"; -import { PointerComponent } from "../components/pointer.component"; -import { WorldLayer } from "../main"; - -export const pointerSystem = (registry: Registry) => { - const entities: {PointerComponent: PointerComponent}[] = registry.getZipper([PointerComponent]); - - for (const entity of entities) { - const pointerPosition = WorldLayer.getRelativePointerPosition(); - - if (!pointerPosition) continue; - - entity.PointerComponent.position.x = pointerPosition.x; - entity.PointerComponent.position.y = pointerPosition.y; - } -}; - -// * Required to generate code -export default pointerSystem.name; diff --git a/raid-survival/client/systems/render.system.ts b/raid-survival/client/systems/render.system.ts index 5787aa3..5fa96bc 100644 --- a/raid-survival/client/systems/render.system.ts +++ b/raid-survival/client/systems/render.system.ts @@ -2,7 +2,7 @@ import { type Context, NfFile } from "@nanoforge-dev/common"; import { type Registry } from "@nanoforge-dev/ecs-client"; import { Graphics2DLibrary, Sprite } from "@nanoforge-dev/graphics-2d"; -import { PositionComponent } from "../components/position.component"; +import { Position } from "../components/position.component"; import { RenderableComponent } from "../components/renderable.component"; import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; @@ -63,12 +63,11 @@ function loadAnimations(file: NfFile): Promise { return promise; } - const spriteCache = new Map(); const pendingIds = new Set(); export const renderSystem = async (registry: Registry, ctx: Context) => { - const entities = registry.getIndexedZipper([PositionComponent, RenderableComponent]); + const entities = registry.getIndexedZipper([Position, RenderableComponent]); const graphics = ctx.libs.getGraphics(); const assetManager = ctx.libs.getAssetManager(); const seenIds = new Set(); @@ -93,18 +92,22 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { pendingIds.delete(entity.id); - const [, , frameWidth, frameHeight] = animations && animations["idle"] ? animations["idle"] : [0, 0, 16, 16]; + const [, , frameWidth, frameHeight] = + animations && animations["idle"] ? animations["idle"] : [0, 0, 16, 16]; const newSprite = new Sprite({ - x: entity.PositionComponent.x, - y: entity.PositionComponent.y, + x: entity.Position.x, + y: entity.Position.y, image, animation: "idle", animations, frameRate: 7, width: frameWidth || 16, height: frameHeight || 16, - scale: { x: entity.RenderableComponent.getScale().x, y: entity.RenderableComponent.getScale().y }, + scale: { + x: entity.RenderableComponent.getScale().x, + y: entity.RenderableComponent.getScale().y, + }, }); newSprite.offsetX(newSprite.width() / 2); @@ -117,8 +120,8 @@ export const renderSystem = async (registry: Registry, ctx: Context) => { } sprite?.position({ - x: entity.PositionComponent.x + sprite.offsetX(), - y: entity.PositionComponent.y + sprite.offsetY(), + x: entity.Position.x + sprite.offsetX(), + y: entity.Position.y + sprite.offsetY(), }); } diff --git a/raid-survival/client/systems/send-move-control.client.system.ts b/raid-survival/client/systems/send-move-control.client.system.ts new file mode 100644 index 0000000..3f4c6c5 --- /dev/null +++ b/raid-survival/client/systems/send-move-control.client.system.ts @@ -0,0 +1,30 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; + +import { MoveController } from "../components/move-controller.component"; +import { Velocity } from "../components/velocity.component"; +import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; + +function compareStringArrays(array1: string[], array2: string[]) { + if (array1.length !== array2.length) return false; + for (let i = 0; i < array1.length; i++) if (array1[i] !== array2[i]) return false; + return true; +} + +export function sendMoveControl(registry: Registry, ctx: Context) { + const entities = registry.getZipper([MoveController, Velocity]); + const network = ctx.libs.getNetwork(); + + entities.forEach(({ MoveController }) => { + const keys: { type: string; moveKeys: string[] } = { type: "input", moveKeys: [] }; + if (MoveController.movingUp) keys.moveKeys.push("up"); + if (MoveController.movingDown) keys.moveKeys.push("down"); + if (MoveController.movingLeft) keys.moveKeys.push("left"); + if (MoveController.movingRight) keys.moveKeys.push("right"); + if (!compareStringArrays(keys.moveKeys, MoveController.lastMoveKeys)) + network.tcp.sendData(new TextEncoder().encode(JSON.stringify(keys))); + MoveController.lastMoveKeys = keys.moveKeys; + }); +} +// * Required to generate code +export default sendMoveControl.name; diff --git a/raid-survival/client/systems/send-shoot-control.client.system.ts b/raid-survival/client/systems/send-shoot-control.client.system.ts new file mode 100644 index 0000000..4bb4562 --- /dev/null +++ b/raid-survival/client/systems/send-shoot-control.client.system.ts @@ -0,0 +1,26 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; + +import { Velocity } from "../components/velocity.component"; +import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; +import { ShootController } from "../components/shoot.controller"; + +export function sendShootControl(registry: Registry, ctx: Context) { + const entities = registry.getZipper([ShootController, Velocity]); + const network = ctx.libs.getNetwork() + + entities.forEach(({ ShootController }) => { + if (ShootController.mainWeaponShooting) network.tcp.sendData(new TextEncoder().encode(JSON.stringify({ type: "input", key: "mainWeaponShooting" }))); + if (ShootController.secondWeaponShooting) network.tcp.sendData(new TextEncoder().encode(JSON.stringify({ type: "input", key: "secondWeaponShooting" }))); + network.tcp.sendData( + new TextEncoder().encode( + JSON.stringify({ + type: "input", + shootDirection: { x: ShootController.position.x, y: ShootController.position.y }, + }), + ), + ); + }); +} +// * Required to generate code +export default sendShootControl.name; diff --git a/raid-survival/client/systems/shoot-control.client.system.ts b/raid-survival/client/systems/shoot-control.client.system.ts new file mode 100644 index 0000000..8bbac9b --- /dev/null +++ b/raid-survival/client/systems/shoot-control.client.system.ts @@ -0,0 +1,26 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { type InputLibrary } from "@nanoforge-dev/input"; + +import { ShootController } from "../components/shoot.controller"; +import { Direction } from "../components/direction.component"; +import { Graphics2DLibrary, Vector2d } from "@nanoforge-dev/graphics-2d"; + +export function shootControl(registry: Registry, ctx: Context) { + const entities = registry.getZipper([ShootController, Direction]); + const input = ctx.libs.getInput(); + const graphics = ctx.libs.getGraphics(); + let pointerPosition: Vector2d | null = null; + + graphics.stage.on("pointermove", () => { + pointerPosition = graphics.baseLayer.getRelativePointerPosition(); + }); + entities.forEach(({ ShootController }) => { + ShootController.mainWeaponShooting = input.isKeyPressed(ShootController.keyShootMainWeapon); + ShootController.secondWeaponShooting = input.isKeyPressed(ShootController.keyShootSecondWeapon); + ShootController.position.x = pointerPosition?.x || 0; + ShootController.position.y = pointerPosition?.y || 0; + }); +} +// * Required to generate code +export default shootControl.name; diff --git a/raid-survival/client/systems/sprite-animator.system.ts b/raid-survival/client/systems/sprite-animator.system.ts new file mode 100644 index 0000000..17ceb5c --- /dev/null +++ b/raid-survival/client/systems/sprite-animator.system.ts @@ -0,0 +1,23 @@ +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { Velocity } from "../components/velocity.component"; +import { RenderableComponent } from "../components/renderable.component"; +import { Direction } from "../components/direction.component"; + +export const spriteAnimator = (registry: Registry) => { + const entities = registry.getZipper([Direction, RenderableComponent, Velocity]); + + entities.forEach(({ Direction, RenderableComponent, Velocity }) => { + if (!RenderableComponent.sprite) return; + if (Velocity.y != 0 || (Velocity.x != 0 && RenderableComponent.getAnimation() != "walk")) { + RenderableComponent.setAnimation("walk"); + } else if (Velocity.x == 0 && RenderableComponent.getAnimation() != "idle") { + RenderableComponent.setAnimation("idle"); + } + + if (Direction.x < 0 && !RenderableComponent.isFlipped()) { + RenderableComponent.flip(); + } else if (Direction.x > 0 && RenderableComponent.isFlipped()) { + RenderableComponent.unflip(); + } + }); +}; diff --git a/raid-survival/eslint.config.js b/raid-survival/eslint.config.js index 2f3639d..79b3980 100644 --- a/raid-survival/eslint.config.js +++ b/raid-survival/eslint.config.js @@ -12,4 +12,10 @@ export default [ ...tseslint.configs.strict, eslintConfigPrettier, { ignores: ["**/*.js", "**/*.d.ts"] }, + { + files: ["**/packet-handlers/**/*.ts"], + rules: { + "@typescript-eslint/no-explicit-any": "off", + }, + }, ]; diff --git a/raid-survival/server/components/clientId.component.ts b/raid-survival/server/components/clientId.component.ts new file mode 100644 index 0000000..55e9309 --- /dev/null +++ b/raid-survival/server/components/clientId.component.ts @@ -0,0 +1,8 @@ +export class Login { + name = this.constructor.name; + + constructor(public id: string) {} +} + +// * Required to generate code +export default Login.name; diff --git a/raid-survival/server/components/direction.component.ts b/raid-survival/server/components/direction.component.ts new file mode 100644 index 0000000..2c14047 --- /dev/null +++ b/raid-survival/server/components/direction.component.ts @@ -0,0 +1,11 @@ +export class Direction { + name = this.constructor.name; + + constructor( + public x: number, + public y: number, + ) {} +} + +// * Required to generate code +export default Direction.name; diff --git a/raid-survival/server/components/example.component.ts b/raid-survival/server/components/example.component.ts deleted file mode 100644 index b803aa5..0000000 --- a/raid-survival/server/components/example.component.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { type EditorComponentManifest } from "@nanoforge-dev/ecs-server"; - -export class ExampleComponent { - name = this.constructor.name; - - constructor( - public paramA: string, - public paramB: number, - public paramC: boolean = false, - ) {} - - get foo() { - return "bar"; - } - - get paramAOrDefault() { - return this.paramC ? this.paramA : "default"; - } - - addOne() { - this.paramB += 1; - } -} - -// * Required to generate code -export default ExampleComponent.name; - -// * Required for the editor to display the component and generate code -export const EDITOR_COMPONENT_MANIFEST: EditorComponentManifest = { - name: "Example", - description: "Example component description", - params: [ - { - type: "string", - name: "paramA", - description: "Param A description", - example: "Example value", - }, - { - type: "number", - name: "paramB", - description: "Param B description", - example: 3, - }, - { - type: "boolean", - name: "paramC", - description: "Param C description", - example: true, - default: false, - // Not required because it has a default value - optional: true, - }, - ], -}; diff --git a/raid-survival/server/components/position.component.ts b/raid-survival/server/components/position.component.ts new file mode 100644 index 0000000..23a606a --- /dev/null +++ b/raid-survival/server/components/position.component.ts @@ -0,0 +1,11 @@ +export class Position { + name = this.constructor.name; + + constructor( + public x: number, + public y: number, + ) {} +} + +// * Required to generate code +export default Position.name; diff --git a/raid-survival/server/components/velocity.component.ts b/raid-survival/server/components/velocity.component.ts new file mode 100644 index 0000000..d9afbfb --- /dev/null +++ b/raid-survival/server/components/velocity.component.ts @@ -0,0 +1,11 @@ +export class Velocity { + name = this.constructor.name; + + constructor( + public x: number, + public y: number, + ) {} +} + +// * Required to generate code +export default Velocity.name; diff --git a/raid-survival/server/main.ts b/raid-survival/server/main.ts index 60ae143..645976e 100644 --- a/raid-survival/server/main.ts +++ b/raid-survival/server/main.ts @@ -4,30 +4,43 @@ import { NanoforgeFactory } from "@nanoforge-dev/core"; import { AssetManagerLibrary } from "@nanoforge-dev/asset-manager"; import { ECSServerLibrary } from "@nanoforge-dev/ecs-server"; import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; +import { moveSystem } from "./systems/move.system"; +import { packetHandler } from "./systems/packet-handler.system"; -import { ExampleComponent } from "./components/example.component"; +export const PLAYER_SPEED = 200; -import { exampleSystem } from "./systems/example.system"; +export enum GameStatusEnum { + Lobby, + InGame, + EndScreen, +} + +export const gameStatus = { status: GameStatusEnum.Lobby }; + +export const clients: { clientId: number; entityId: number; clientLogin: string }[] = [ + { clientId: -1, entityId: -1, clientLogin: "" }, + { clientId: -1, entityId: -1, clientLogin: "" }, + { clientId: -1, entityId: -1, clientLogin: "" }, + { clientId: -1, entityId: -1, clientLogin: "" }, +]; export async function main(options: IRunOptions) { const app = NanoforgeFactory.createServer(); - + const assetManagerLibrary = new AssetManagerLibrary(); const ecsLibrary = new ECSServerLibrary(); const networkLibrary = new NetworkServerLibrary(); - + app.useAssetManager(assetManagerLibrary); app.useComponentSystem(ecsLibrary); app.useNetwork(networkLibrary); - + await app.init(options); - + const registry = ecsLibrary.registry; - - const exampleEntity = registry.spawnEntity(); - registry.addComponent(exampleEntity, new ExampleComponent("example", 10, undefined)); - - registry.addSystem(exampleSystem); - + + registry.addSystem(packetHandler); + registry.addSystem(moveSystem); + await app.run(); } diff --git a/raid-survival/server/network-utils.ts b/raid-survival/server/network-utils.ts new file mode 100644 index 0000000..64bec1f --- /dev/null +++ b/raid-survival/server/network-utils.ts @@ -0,0 +1,9 @@ +import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; +import { clients } from "./main"; + +export function sendToInGamePlayers(network: NetworkServerLibrary, packet: unknown) { + clients.forEach(({ clientId }) => { + if (clientId !== -1) + network.tcp.sendToClient(clientId, new TextEncoder().encode(JSON.stringify(packet))); + }); +} diff --git a/raid-survival/server/systems/example.system.ts b/raid-survival/server/systems/example.system.ts deleted file mode 100644 index 7400df4..0000000 --- a/raid-survival/server/systems/example.system.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { type Context } from "@nanoforge-dev/common"; -import { type EditorSystemManifest, type Registry } from "@nanoforge-dev/ecs-server"; - -import { ExampleComponent } from "../components/example.component"; - -export const exampleSystem = (registry: Registry, ctx: Context) => { - const entities = registry.getZipper([ExampleComponent]); - - entities.forEach((entity) => { - if (entity.ExampleComponent.paramA === "end") { - ctx.app.setIsRunning(false); - return; - } - - if (entity.ExampleComponent.paramB === 0) entity.ExampleComponent.paramA = "end"; - - if (entity.ExampleComponent.paramB >= 0) - entity.ExampleComponent.paramB = entity.ExampleComponent.paramB - 1; - }); -}; - -// * Required to generate code -export default exampleSystem.name; - -// * Required for the editor to display the system and generate code -export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = { - name: "Example", - description: - "This system end the game when paramB reaches 0 for any entity with ExampleComponent", - dependencies: ["ExampleComponent"], -}; diff --git a/raid-survival/server/systems/move.system.ts b/raid-survival/server/systems/move.system.ts new file mode 100644 index 0000000..536d1be --- /dev/null +++ b/raid-survival/server/systems/move.system.ts @@ -0,0 +1,16 @@ +import { type Context } from "@nanoforge-dev/common"; +import { type Registry } from "@nanoforge-dev/ecs-client"; + +import { Position } from "../components/position.component"; +import { Velocity } from "../components/velocity.component"; + +export function moveSystem(registry: Registry, ctx: Context) { + const entities = registry.getZipper([Position, Velocity]); + + entities.forEach(({ Position, Velocity }) => { + Position.x += (Velocity.x * ctx.app.delta) / 1000; + Position.y += (Velocity.y * ctx.app.delta) / 1000; + }); +} +// * Required to generate code +export default moveSystem.name; diff --git a/raid-survival/server/systems/packet-handler.system.ts b/raid-survival/server/systems/packet-handler.system.ts new file mode 100644 index 0000000..4172446 --- /dev/null +++ b/raid-survival/server/systems/packet-handler.system.ts @@ -0,0 +1,40 @@ +import { type Registry } from "@nanoforge-dev/ecs-client"; +import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; +import { Context } from "@nanoforge-dev/common"; +import { inputPacketHandler } from "./packet-handlers/input-packet.handler"; +import { clients } from "../main"; +import { joinLobbyPacketHandler } from "./packet-handlers/join-lobby-packet.handler"; +import { startGamePacketHandler } from "./packet-handlers/start-game-packet.handler"; + +export type PacketHandler = ( + client: number, + packet: unknown, + registry: Registry, + ctx: Context, +) => unknown; + +export const packetHandlers: Map = new Map([ + ["input", inputPacketHandler], + ["joinLobby", joinLobbyPacketHandler], + ["startGame", startGamePacketHandler], +]); + +export function packetHandler(registry: Registry, ctx: Context) { + const network = ctx.libs.getNetwork(); + const connectedClients = network.tcp.getConnectedClients(); + clients.forEach((client) => { + if (client.clientId === -1) return; + if (connectedClients.findIndex((id) => id === client.clientId) === -1) { + client.clientId = -1; + } + }); + network.tcp.getReceivedPackets().forEach((packets, client) => { + const jsonPackets = packets.map((packet: AllowSharedBufferSource | undefined) => { + return JSON.parse(new TextDecoder().decode(packet)); + }); + if (!jsonPackets || jsonPackets.length === 0) return; + jsonPackets.forEach((packet) => { + packetHandlers.get(packet.type)?.(client, packet, registry, ctx); + }); + }); +} diff --git a/raid-survival/server/systems/packet-handlers/input-packet.handler.ts b/raid-survival/server/systems/packet-handlers/input-packet.handler.ts new file mode 100644 index 0000000..51d70cb --- /dev/null +++ b/raid-survival/server/systems/packet-handlers/input-packet.handler.ts @@ -0,0 +1,56 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { Velocity } from "../../components/velocity.component"; +import { Position } from "../../components/position.component"; +import { clients, PLAYER_SPEED } from "../../main"; +import { Context } from "@nanoforge-dev/common"; +import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; +import { sendToInGamePlayers } from "../../network-utils"; +import { Direction } from "../../components/direction.component"; +import { Login } from "../../components/clientId.component"; + +export function inputPacketHandler( + clientId: number, + packet: any, + registry: Registry, + ctx: Context, +): void { + const network = ctx.libs.getNetwork(); + const zipper = registry.getIndexedZipper([Login, Velocity, Position, Direction]); + const log = clients.find((client) => client.clientId === clientId)?.clientLogin; + const it = zipper.find(({ Login }) => { + return Login.id === log; + }); + if (!it) return; + + if (packet.shootDirection) { + it.Direction.x = packet.shootDirection.x - it.Position.x; + it.Direction.y = packet.shootDirection.y - it.Position.y; + sendToInGamePlayers(network, { + type: "direction", + id: it.id, + direction: { x: it.Direction.x, y: it.Direction.y }, + }); + } + + if (packet.moveKeys) { + let dx = 0; + let dy = 0; + + if (packet.moveKeys.findIndex((key: string) => key === "up") !== -1) dy -= 1; + if (packet.moveKeys.findIndex((key: string) => key === "down") !== -1) dy += 1; + if (packet.moveKeys.findIndex((key: string) => key === "left") !== -1) dx -= 1; + if (packet.moveKeys.findIndex((key: string) => key === "right") !== -1) dx += 1; + + const len = Math.hypot(dx, dy) || 1; + it.Velocity.x = (dx / len) * PLAYER_SPEED; + it.Velocity.y = (dy / len) * PLAYER_SPEED; + + console.log(it, zipper) + sendToInGamePlayers(network, { + type: "move", + id: it.id, + velocity: { x: it.Velocity.x, y: it.Velocity.y }, + position: { x: it.Position.x, y: it.Position.y }, + }); + } +} diff --git a/raid-survival/server/systems/packet-handlers/join-lobby-packet.handler.ts b/raid-survival/server/systems/packet-handlers/join-lobby-packet.handler.ts new file mode 100644 index 0000000..5698fd9 --- /dev/null +++ b/raid-survival/server/systems/packet-handlers/join-lobby-packet.handler.ts @@ -0,0 +1,47 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { clients } from "../../main"; +import { Context } from "@nanoforge-dev/common"; +import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; +import { sendToInGamePlayers } from "../../network-utils"; + +export function joinLobbyPacketHandler( + clientId: number, + packet: any, + _registry: Registry, + ctx: Context, +): void { + const network = ctx.libs.getNetwork(); + let connected = false; + for (const client of clients) { + if (client.clientLogin === packet.login) { + client.clientId = clientId; + connected = true; + break; + } + if (client.clientId !== -1) continue; + client.clientLogin = packet.login; + client.clientId = clientId; + connected = true; + break; + } + if (!connected) { + network.tcp.sendToClient( + clientId, + new TextEncoder().encode(JSON.stringify({ type: "joinLobby", result: "full" })), + ); + } + network.tcp.sendToClient( + clientId, + new TextEncoder().encode( + JSON.stringify({ + type: "joinLobby", + result: "success", + playerNumber: clients.filter(({ clientId }) => clientId !== -1).length, + }), + ), + ); + sendToInGamePlayers(network, { + type: "lobbyInfo", + playerNumber: clients.filter(({ clientId }) => clientId !== -1).length, + }); +} diff --git a/raid-survival/server/systems/packet-handlers/start-game-packet.handler.ts b/raid-survival/server/systems/packet-handlers/start-game-packet.handler.ts new file mode 100644 index 0000000..875fea3 --- /dev/null +++ b/raid-survival/server/systems/packet-handlers/start-game-packet.handler.ts @@ -0,0 +1,46 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { clients, gameStatus, GameStatusEnum } from "../../main"; +import { Context } from "@nanoforge-dev/common"; +import { NetworkServerLibrary } from "@nanoforge-dev/network-server"; +import { sendToInGamePlayers } from "../../network-utils"; +import { Position } from "../../components/position.component"; +import { Direction } from "../../components/direction.component"; +import { Velocity } from "../../components/velocity.component"; +import { Login } from "../../components/clientId.component"; + +export function startGamePacketHandler( + _clientId: number, + _packet: any, + registry: Registry, + ctx: Context, +): void { + const network = ctx.libs.getNetwork(); + if (gameStatus.status === GameStatusEnum.InGame) return; + gameStatus.status = GameStatusEnum.InGame; + + sendToInGamePlayers(network, { + type: "spawn", + entityType: "map", + position: { x: 0, y: 0 }, + }); + + clients.forEach((client, index) => { + if (client.clientId === -1) return; + const player = registry.spawnEntity(); + + client.entityId = player.getId(); + registry.addComponent(player, new Direction(1, 0)); + registry.addComponent(player, new Login(client.clientLogin)); + registry.addComponent(player, new Position(500 + 100 * index, 100)); + registry.addComponent(player, new Velocity(0, 0)); + sendToInGamePlayers(network, { + type: "spawn", + entityType: "player", + position: { x: 500 + 100 * index, y: 100 }, + velocity: { x: 0, y: 0 }, + direction: { x: 1, y: 0 }, + login: client.clientLogin, + id: player.getId(), + }); + }); +} From 21acc3a0d53290163bb8b2addab5c219ca4769c7 Mon Sep 17 00:00:00 2001 From: Harper Date: Sun, 23 Aug 2026 08:21:12 +0200 Subject: [PATCH 05/15] feat(raid-survival): create lobby system and menu UI --- .idea/codeStyles/codeStyleConfig.xml | 5 + .../client/components/lobby/lobby-status.ts | 24 ++ .../components/move-controller.component.ts | 4 +- .../client/components/player.component.ts | 13 + .../components/renderable/group.component.ts | 15 + .../components/renderable/rect.component.ts | 15 + .../sprite.component.ts} | 13 +- .../components/renderable/text.component.ts | 14 + .../renderable/textarea.component.ts | 134 +++++++ raid-survival/client/main.ts | 43 ++- raid-survival/client/scenes/GameScene.ts | 28 ++ raid-survival/client/scenes/MenuScene.ts | 329 ++++++++++++++++++ raid-survival/client/scenes/Scene.ts | 12 + raid-survival/client/scenes/SceneManager.ts | 25 ++ .../client/static/client-config.json | 2 +- raid-survival/client/static/map.png | Bin 69398 -> 290244 bytes raid-survival/client/static/player1.png | Bin 0 -> 2660 bytes raid-survival/client/static/player2.png | Bin 0 -> 2870 bytes raid-survival/client/static/player3.png | Bin 0 -> 2708 bytes .../client/static/{player.png => player4.png} | Bin .../client/systems/clickable.system.ts | 28 -- .../client/systems/packet-handler.system.ts | 4 + .../join-lobby-packet.handler.ts | 44 +-- .../lobby-info-packet.handler.ts | 17 + .../packet-handlers/move-packet.handler.ts | 8 +- .../packet-handlers/spawn-packet.handler.ts | 9 +- .../systems/packet-handlers/start-game.ts | 38 ++ .../systems/packet-senders/lobby-action.ts | 30 ++ .../send-move-control.client.system.ts | 4 +- .../send-shoot-control.client.system.ts | 4 +- .../shoot-control.client.system.ts | 4 +- .../sprite-animator.system.ts | 8 +- .../sprite.system.ts} | 22 +- .../client/systems/renderable/textarea.ts | 10 + raid-survival/client/systems/scene.ts | 8 + raid-survival/server/main.ts | 7 +- .../packet-handlers/input-packet.handler.ts | 2 +- .../join-lobby-packet.handler.ts | 41 ++- .../start-game-packet.handler.ts | 47 +-- 39 files changed, 868 insertions(+), 143 deletions(-) create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 raid-survival/client/components/lobby/lobby-status.ts create mode 100644 raid-survival/client/components/player.component.ts create mode 100644 raid-survival/client/components/renderable/group.component.ts create mode 100644 raid-survival/client/components/renderable/rect.component.ts rename raid-survival/client/components/{renderable.component.ts => renderable/sprite.component.ts} (84%) create mode 100644 raid-survival/client/components/renderable/text.component.ts create mode 100644 raid-survival/client/components/renderable/textarea.component.ts create mode 100644 raid-survival/client/scenes/GameScene.ts create mode 100644 raid-survival/client/scenes/MenuScene.ts create mode 100644 raid-survival/client/scenes/Scene.ts create mode 100644 raid-survival/client/scenes/SceneManager.ts create mode 100644 raid-survival/client/static/player1.png create mode 100644 raid-survival/client/static/player2.png create mode 100644 raid-survival/client/static/player3.png rename raid-survival/client/static/{player.png => player4.png} (100%) delete mode 100644 raid-survival/client/systems/clickable.system.ts create mode 100644 raid-survival/client/systems/packet-handlers/lobby-info-packet.handler.ts create mode 100644 raid-survival/client/systems/packet-handlers/start-game.ts create mode 100644 raid-survival/client/systems/packet-senders/lobby-action.ts rename raid-survival/client/systems/{ => packet-senders}/send-move-control.client.system.ts (89%) rename raid-survival/client/systems/{ => packet-senders}/send-shoot-control.client.system.ts (88%) rename raid-survival/client/systems/{ => packet-senders}/shoot-control.client.system.ts (89%) rename raid-survival/client/systems/{ => renderable}/sprite-animator.system.ts (71%) rename raid-survival/client/systems/{render.system.ts => renderable/sprite.system.ts} (83%) create mode 100644 raid-survival/client/systems/renderable/textarea.ts create mode 100644 raid-survival/client/systems/scene.ts diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/raid-survival/client/components/lobby/lobby-status.ts b/raid-survival/client/components/lobby/lobby-status.ts new file mode 100644 index 0000000..48814a2 --- /dev/null +++ b/raid-survival/client/components/lobby/lobby-status.ts @@ -0,0 +1,24 @@ +export interface LobbyPlayer { + id: string; + username: string; +} + +export enum LobbyState { + UNJOINED, + LOADING, + JOINED, +} + +export enum LobbyAction { + EMPTY, + JOIN_LOBBY, + START_GAME +} + +export class LobbyStatusComponent { + name = this.constructor.name; + username = ""; + state: LobbyState = LobbyState.UNJOINED; + action: LobbyAction = LobbyAction.EMPTY; + players: LobbyPlayer[] = []; +} \ No newline at end of file diff --git a/raid-survival/client/components/move-controller.component.ts b/raid-survival/client/components/move-controller.component.ts index 6e37ac4..f42aef5 100644 --- a/raid-survival/client/components/move-controller.component.ts +++ b/raid-survival/client/components/move-controller.component.ts @@ -1,4 +1,4 @@ -import { type InputEnum } from "@nanoforge-dev/input"; +import { InputEnum } from "@nanoforge-dev/input"; export class MoveController { name = this.constructor.name; @@ -14,7 +14,7 @@ export class MoveController { constructor(clientConfig: { keybinds: { up: InputEnum; left: InputEnum; down: InputEnum; right: InputEnum }; - }) { + } = { keybinds: { up: InputEnum.KeyW, left: InputEnum.KeyA, down: InputEnum.KeyS, right: InputEnum.KeyD } }) { this.keyUp = clientConfig.keybinds.up; this.keyDown = clientConfig.keybinds.down; this.keyLeft = clientConfig.keybinds.left; diff --git a/raid-survival/client/components/player.component.ts b/raid-survival/client/components/player.component.ts new file mode 100644 index 0000000..805a586 --- /dev/null +++ b/raid-survival/client/components/player.component.ts @@ -0,0 +1,13 @@ +export class PlayerComponent { + name = this.constructor.name; + id: number; + username: string; + + constructor(id: number, username: string) { + this.id = id; + this.username = username; + } +} + +// * Required to generate code +export default PlayerComponent.name; diff --git a/raid-survival/client/components/renderable/group.component.ts b/raid-survival/client/components/renderable/group.component.ts new file mode 100644 index 0000000..8b1c934 --- /dev/null +++ b/raid-survival/client/components/renderable/group.component.ts @@ -0,0 +1,15 @@ +import { GroupConfig, Group, Container } from "@nanoforge-dev/graphics-2d"; +import { SpriteComponent } from "./sprite.component"; + +export class GroupComponent { + name = this.constructor.name; + group: Group; + + constructor(parent: Container, options: GroupConfig) { + this.group = new Group(options); + parent.add(this.group); + } +} + +// * Required to generate code +export default SpriteComponent.name; diff --git a/raid-survival/client/components/renderable/rect.component.ts b/raid-survival/client/components/renderable/rect.component.ts new file mode 100644 index 0000000..28a84fa --- /dev/null +++ b/raid-survival/client/components/renderable/rect.component.ts @@ -0,0 +1,15 @@ +import { Container, Rect, RectConfig } from "@nanoforge-dev/graphics-2d"; +import { SpriteComponent } from "./sprite.component"; + +export class RectComponent { + name = this.constructor.name; + rect: Rect; + + constructor(parent: Container, options: RectConfig) { + this.rect = new Rect(options); + parent.add(this.rect); + } +} + +// * Required to generate code +export default SpriteComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/renderable.component.ts b/raid-survival/client/components/renderable/sprite.component.ts similarity index 84% rename from raid-survival/client/components/renderable.component.ts rename to raid-survival/client/components/renderable/sprite.component.ts index 0841034..a504261 100644 --- a/raid-survival/client/components/renderable.component.ts +++ b/raid-survival/client/components/renderable/sprite.component.ts @@ -1,30 +1,29 @@ import { Layer, Sprite, Vector2d } from "@nanoforge-dev/graphics-2d"; -interface RenderableComponentOptions { +interface SpriteComponentOptions { animationsKey?: string; layer?: Layer; scale?: Vector2d; currentAnimation?: string; } -export class RenderableComponent { +export class SpriteComponent { name = this.constructor.name; spriteKey: string; sprite: Sprite | undefined; animationsKey?: string; - layer: Layer; + layer: Layer | undefined; private _scale: Vector2d = { x: 1, y: 1 }; private _currentAnimation: string = "idle"; private _flipped: boolean = false; - constructor(spriteKey: string, layer: Layer, options?: RenderableComponentOptions) { + constructor(spriteKey: string, options?: SpriteComponentOptions) { this.spriteKey = spriteKey; if (options?.animationsKey) this.animationsKey = options.animationsKey; - if (options?.layer) this.layer = options.layer; if (options?.scale) this._scale = options.scale; if (options?.currentAnimation) this._currentAnimation = options.currentAnimation; - this.layer = layer; + if (options?.layer) this.layer = options.layer; } getAnimation(): string { @@ -62,4 +61,4 @@ export class RenderableComponent { } // * Required to generate code -export default RenderableComponent.name; \ No newline at end of file +export default SpriteComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/renderable/text.component.ts b/raid-survival/client/components/renderable/text.component.ts new file mode 100644 index 0000000..986ce2a --- /dev/null +++ b/raid-survival/client/components/renderable/text.component.ts @@ -0,0 +1,14 @@ +import { Container, Text, TextConfig } from "@nanoforge-dev/graphics-2d"; + +export class TextComponent { + name = this.constructor.name; + text: Text; + + constructor(parent: Container, options: TextConfig) { + this.text = new Text(options); + parent.add(this.text); + } +} + +// * Required to generate code +export default TextComponent.name; \ No newline at end of file diff --git a/raid-survival/client/components/renderable/textarea.component.ts b/raid-survival/client/components/renderable/textarea.component.ts new file mode 100644 index 0000000..a170413 --- /dev/null +++ b/raid-survival/client/components/renderable/textarea.component.ts @@ -0,0 +1,134 @@ +import { + Container, + document, + Group, + Layer, + Stage, + Text, + TextConfig, +} from "@nanoforge-dev/graphics-2d"; + +export class TextAreaComponent { + name = this.constructor.name; + text: Text; + wrapper: HTMLDivElement; + textarea: HTMLTextAreaElement; + value: string = ""; + private readonly clipAncestor: Group | Layer | Stage | null; + + constructor(parent: Container, options: TextConfig) { + this.text = new Text(options); + parent.add(this.text); + this.text.hide(); + + this.clipAncestor = this.findClipAncestor(parent); + + this.wrapper = document.createElement("div"); + this.wrapper.style.position = "absolute"; + this.wrapper.style.overflow = "hidden"; + this.wrapper.style.pointerEvents = "none"; + document.body.appendChild(this.wrapper); + + this.textarea = document.createElement("textarea"); + this.textarea.value = this.text.text(); + this.textarea.style.position = "absolute"; + this.textarea.style.border = "none"; + this.textarea.style.padding = "0px"; + this.textarea.style.margin = "0px"; + this.textarea.style.overflow = "hidden"; + this.textarea.style.background = "none"; + this.textarea.style.outline = "none"; + this.textarea.style.resize = "none"; + this.textarea.style.transformOrigin = "left top"; + this.textarea.style.pointerEvents = "auto"; + this.applyTextStyle(); + this.wrapper.appendChild(this.textarea); + + this.textarea.addEventListener("input", () => { + this.text.text(this.textarea.value); + }); + + this.sync(); + } + + private applyTextStyle(): void { + this.textarea.style.fontSize = this.text.fontSize() + "px"; + this.textarea.style.lineHeight = this.text.lineHeight().toString(); + this.textarea.style.fontFamily = this.text.fontFamily(); + this.textarea.style.textAlign = this.text.align(); + this.textarea.style.color = (this.text.fill() as string) ?? "#000"; + this.textarea.style.width = this.text.width() - this.text.padding() * 2 + "px"; + this.textarea.style.height = this.text.height() - this.text.padding() * 2 + 5 + "px"; + } + + private findClipAncestor(node: Container): Group | Layer | Stage | null { + let current: Container | null = node; + while (current) { + const clipWidth = current.clipWidth?.(); + if (clipWidth) return current as Group | Layer | Stage; + current = current.getParent(); + } + return null; + } + + sync(): void { + const stage = this.text.getStage(); + if (!stage) return; + + const containerRect = stage.container().getBoundingClientRect(); + const textAbs = this.text.getAbsolutePosition(); + const scale = stage.getAbsoluteScale(); + + const pageX = containerRect.left + textAbs.x * scale.x; + const pageY = containerRect.top + textAbs.y * scale.y; + + if (this.clipAncestor) { + const clipRect = this.getAbsoluteClipRect(this.clipAncestor, containerRect, scale); + + this.wrapper.style.left = clipRect.x + "px"; + this.wrapper.style.top = clipRect.y + "px"; + this.wrapper.style.width = clipRect.width + "px"; + this.wrapper.style.height = clipRect.height + "px"; + + this.textarea.style.left = pageX - clipRect.x + "px"; + this.textarea.style.top = pageY - clipRect.y + "px"; + } else { + this.wrapper.style.left = "0px"; + this.wrapper.style.top = "0px"; + this.wrapper.style.width = "100vw"; + this.wrapper.style.height = "100vh"; + this.textarea.style.left = pageX + "px"; + this.textarea.style.top = pageY + "px"; + } + + this.value = this.textarea.value; + } + + private getAbsoluteClipRect( + node: Group | Layer | Stage, + containerRect: DOMRect, + scale: { x: number; y: number }, + ): { x: number; y: number; width: number; height: number } { + const n = node; + const cx = n.clipX?.() ?? 0; + const cy = n.clipY?.() ?? 0; + const cw = n.clipWidth?.() ?? node.width(); + const ch = n.clipHeight?.() ?? node.height(); + + const topLeft = node.getAbsoluteTransform().point({ x: cx, y: cy }); + const nodeScale = node.getAbsoluteScale(); + + return { + x: containerRect.left + topLeft.x * scale.x, + y: containerRect.top + topLeft.y * scale.y, + width: cw * nodeScale.x, + height: ch * nodeScale.y, + }; + } + + destroy(): void { + this.text.destroy(); + this.textarea.remove(); + this.wrapper.remove(); + } +} diff --git a/raid-survival/client/main.ts b/raid-survival/client/main.ts index 00594c5..bc2e936 100644 --- a/raid-survival/client/main.ts +++ b/raid-survival/client/main.ts @@ -9,15 +9,19 @@ import { MusicLibrary } from "@nanoforge-dev/music"; import { NetworkClientLibrary } from "@nanoforge-dev/network-client"; import { SoundLibrary } from "@nanoforge-dev/sound"; import { moveSystem } from "./systems/move.system"; -import { spriteAnimator } from "./systems/sprite-animator.system"; -import { renderSystem } from "./systems/render.system"; +import { spriteAnimator } from "./systems/renderable/sprite-animator.system"; +import { spriteSystem } from "./systems/renderable/sprite.system"; import { cameraFollowSystem } from "./systems/camera-follow.system"; import { moveControl } from "./systems/move-control.client.system"; -import { shootControl } from "./systems/shoot-control.client.system"; -import { sendMoveControl } from "./systems/send-move-control.client.system"; -import { sendShootControl } from "./systems/send-shoot-control.client.system"; -import { clickableSystem } from "./systems/clickable.system"; +import { shootControl } from "./systems/packet-senders/shoot-control.client.system"; +import { sendMoveControl } from "./systems/packet-senders/send-move-control.client.system"; +import { sendShootControl } from "./systems/packet-senders/send-shoot-control.client.system"; import { packetHandler } from "./systems/packet-handler.system"; +import {SceneManager} from "./scenes/SceneManager"; +import {MenuScene} from "./scenes/MenuScene"; +import {textareaSystem} from "./systems/renderable/textarea"; +import { sceneSystem } from "./systems/scene"; +import { sendLobbyAction } from "./systems/packet-senders/lobby-action"; export let clientConfig: { keybinds: { @@ -32,6 +36,13 @@ export let clientConfig: { login: string; }; +export let sceneManager: SceneManager; +export let playerId: number; + +export function setPlayerId(id: number) { + playerId = id; +} + export async function main(options: IRunOptions) { const app = NanoforgeFactory.createClient(); @@ -58,16 +69,20 @@ export async function main(options: IRunOptions) { clientConfig = await assetManagerLibrary.getAsset("client-config.json").json(); const registry = ecsLibrary.registry; + registry.addSystem(sceneSystem); registry.addSystem(moveControl); + registry.addSystem(textareaSystem); registry.addSystem(shootControl); - registry.addSystem(sendMoveControl); - registry.addSystem(sendShootControl); registry.addSystem(spriteAnimator); registry.addSystem(cameraFollowSystem); - registry.addSystem(clickableSystem); - registry.addSystem(packetHandler); registry.addSystem(moveSystem); - registry.addSystem(renderSystem); + registry.addSystem(spriteSystem); + + registry.addSystem(packetHandler); + + registry.addSystem(sendMoveControl); + registry.addSystem(sendShootControl); + registry.addSystem(sendLobbyAction); async function waitForConnection(): Promise { if (networkLibrary.tcp?.isConnected()) return; @@ -86,8 +101,8 @@ export async function main(options: IRunOptions) { await waitForConnection(); - networkLibrary.tcp.sendData( - new TextEncoder().encode(JSON.stringify({ type: "joinLobby", login: clientConfig.login })), - ); + sceneManager = new SceneManager(registry, graphicsLibrary.stage); + sceneManager.switchTo(new MenuScene()); + await app.run(); } diff --git a/raid-survival/client/scenes/GameScene.ts b/raid-survival/client/scenes/GameScene.ts new file mode 100644 index 0000000..ff87e87 --- /dev/null +++ b/raid-survival/client/scenes/GameScene.ts @@ -0,0 +1,28 @@ +import { Scene } from "./Scene"; +import { Registry } from "@nanoforge-dev/ecs-client"; +import { Layer, Stage } from "@nanoforge-dev/graphics-2d"; +import { Position } from "../components/position.component"; +import { SpriteComponent } from "../components/renderable/sprite.component"; + +export class GameScene implements Scene { + readonly name = "GameScene"; + layer: Layer | undefined; + + private stage!: Stage; + + load(registry: Registry, stage: Stage): void { + this.stage = stage; + + this.layer = new Layer(); + this.stage.add(this.layer); + + const map = registry.spawnEntity(); + registry.addComponent(map, new Position(0, 0)); + registry.addComponent( + map, + new SpriteComponent("map.png", { layer: this.layer, scale: { x: 3, y: 3 } }), + ); + } + + tick(): void {} +} \ No newline at end of file diff --git a/raid-survival/client/scenes/MenuScene.ts b/raid-survival/client/scenes/MenuScene.ts new file mode 100644 index 0000000..f4b90f0 --- /dev/null +++ b/raid-survival/client/scenes/MenuScene.ts @@ -0,0 +1,329 @@ +import { Scene } from "./Scene"; +import { Container, Easings, Group, Layer, Stage, Tween } from "@nanoforge-dev/graphics-2d"; +import { Registry } from "@nanoforge-dev/ecs-client"; + +import { RectComponent } from "../components/renderable/rect.component"; +import { TextAreaComponent } from "../components/renderable/textarea.component"; +import { GroupComponent } from "../components/renderable/group.component"; +import { TextComponent } from "../components/renderable/text.component"; +import { LobbyAction, LobbyState, LobbyStatusComponent } from "../components/lobby/lobby-status"; + +export class MenuScene implements Scene { + readonly name = "menu"; + layer: Layer | undefined; + private stage!: Stage; + + private lobbyStatusComponent: LobbyStatusComponent | undefined; + + private joinLobbyGroup: Group | undefined; + private lobbyGroup: Group | undefined; + + private menu: "User" | "Lobby" = "User"; + private playerCases: TextComponent[] = []; + + load(registry: Registry, stage: Stage): void { + const lobbyStatus = registry.spawnEntity(); + this.lobbyStatusComponent = new LobbyStatusComponent(); + registry.addComponent(lobbyStatus, this.lobbyStatusComponent); + + this.stage = stage; + + this.layer = new Layer(); + this.stage.add(this.layer); + + const background = registry.spawnEntity(); + registry.addComponent( + background, + new RectComponent(this.layer, { + x: 0, + y: 0, + width: window.innerWidth, + height: window.innerHeight, + fill: "#0B2E1A", + }), + ); + + const mainWidgetSize = { width: 500, height: 600 }; + const mainWidgetGroup = registry.spawnEntity(); + const mainWidgetGroupComponent = new GroupComponent(this.layer, { + x: window.innerWidth / 2 - mainWidgetSize.width / 2, + y: window.innerHeight / 2 - mainWidgetSize.height / 2, + width: mainWidgetSize.width, + height: mainWidgetSize.height, + clip: { + x: 0, + y: 0, + width: mainWidgetSize.width, + height: mainWidgetSize.height, + }, + }); + registry.addComponent(mainWidgetGroup, mainWidgetGroupComponent); + + const mainWidgetBackground = registry.spawnEntity(); + registry.addComponent( + mainWidgetBackground, + new RectComponent(mainWidgetGroupComponent.group, { + x: 0, + y: 0, + width: mainWidgetGroupComponent.group.width(), + height: mainWidgetGroupComponent.group.height(), + fill: "#104522", + cornerRadius: 5, + }), + ); + + this.joinLobbyGroup = this.buildJoinLobbyWidget(registry, mainWidgetGroupComponent.group).group; + this.lobbyGroup = this.buildLobbyWidget(registry, mainWidgetGroupComponent.group).group; + } + + unload(): void { + + } + + tick(registry: Registry) { + const entities: { LobbyStatusComponent: LobbyStatusComponent }[] = registry.getZipper([ + LobbyStatusComponent, + ]); + const firstLobbyStatus = entities[0]; + + if (!firstLobbyStatus) return; + + if ( + firstLobbyStatus.LobbyStatusComponent.state === LobbyState.JOINED && + this.menu !== "Lobby" + ) { + this.menu = "Lobby"; + if (this.joinLobbyGroup && this.lobbyGroup) { + new Tween({ + node: this.joinLobbyGroup, + duration: 0.4, + x: -this.joinLobbyGroup.width(), + easing: Easings.EaseInOut, + }).play(); + new Tween({ + node: this.lobbyGroup, + duration: 0.4, + x: 0, + easing: Easings.EaseInOut, + }).play(); + } + } + + for (let i = 0; i < firstLobbyStatus.LobbyStatusComponent.players.length; i += 1) { + const textPlayerCase = this.playerCases[i]; + const player = firstLobbyStatus.LobbyStatusComponent.players[i]; + if (!textPlayerCase || !player) return; + + textPlayerCase.text.text(player.username); + } + } + + private buildJoinLobbyWidget(registry: Registry, parent: Container): GroupComponent { + const joinLobbyGroup = registry.spawnEntity(); + const joinLobbyGroupComponent = new GroupComponent(parent, { + x: 0, + y: 0, + width: parent.width(), + height: parent.height(), + }); + registry.addComponent(joinLobbyGroup, joinLobbyGroupComponent); + + const pseudoTextSize = { width: 300, height: 30 }; + const pseudoTextBackground = registry.spawnEntity(); + registry.addComponent( + pseudoTextBackground, + new RectComponent(joinLobbyGroupComponent.group, { + x: joinLobbyGroupComponent.group.width() / 2 - pseudoTextSize.width / 2, + y: joinLobbyGroupComponent.group.height() / 2 - pseudoTextSize.height / 2, + width: pseudoTextSize.width, + height: pseudoTextSize.height, + fill: "#FFFFFF", + }), + ); + const pseudoText = registry.spawnEntity(); + const pseudoTextComponent = new TextAreaComponent(joinLobbyGroupComponent.group, { + text: "Player" + Math.floor(Math.random() * 10000).toString(), + x: joinLobbyGroupComponent.group.width() / 2 - pseudoTextSize.width / 2, + y: joinLobbyGroupComponent.group.height() / 2 - pseudoTextSize.height / 2, + width: pseudoTextSize.width, + height: pseudoTextSize.height, + fontSize: 24, + verticalAlign: "middle", + padding: 2, + }); + registry.addComponent(pseudoText, pseudoTextComponent); + + const joinLobbyButtonSize = { width: 300, height: 50 }; + const joinLobbyButton = registry.spawnEntity(); + const joinLobbyButtonComponent = new RectComponent(joinLobbyGroupComponent.group, { + x: joinLobbyGroupComponent.group.width() / 2 - joinLobbyButtonSize.width / 2, + y: + joinLobbyGroupComponent.group.height() / 2 - + joinLobbyButtonSize.height / 2 + + pseudoTextSize.height + + 20, + width: joinLobbyButtonSize.width, + height: joinLobbyButtonSize.height, + cornerRadius: 10, + fill: "#1F6B45", + stroke: "#134e2c", + strokeWidth: 2, + shadowEnabled: false, + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowBlur: 2, + }); + registry.addComponent(joinLobbyButton, joinLobbyButtonComponent); + joinLobbyButtonComponent.rect.on("mouseover", () => { + joinLobbyButtonComponent.rect.shadowEnabled(true); + if (this.stage) this.stage.container().style.cursor = "pointer"; + }); + joinLobbyButtonComponent.rect.on("mouseout", () => { + joinLobbyButtonComponent.rect.shadowEnabled(false); + if (this.stage) this.stage.container().style.cursor = "default"; + }); + joinLobbyButtonComponent.rect.on("click", () => { + if (this.lobbyStatusComponent) { + this.lobbyStatusComponent.username = pseudoTextComponent.value; + this.lobbyStatusComponent.action = LobbyAction.JOIN_LOBBY; + } + }); + + const textJoinLobbyButton = registry.spawnEntity(); + const textJoinLobbyButtonComponent = new TextComponent(joinLobbyGroupComponent.group, { + text: "Join Lobby", + x: joinLobbyGroupComponent.group.width() / 2 - joinLobbyButtonSize.width / 2, + y: + joinLobbyGroupComponent.group.height() / 2 - + joinLobbyButtonSize.height / 2 + + pseudoTextSize.height + + 20, + width: joinLobbyButtonSize.width, + height: joinLobbyButtonSize.height, + fontSize: 24, + verticalAlign: "middle", + align: "center", + fill: "#F5F2E9", + fontStyle: "bold", + listening: false, + }); + registry.addComponent(textJoinLobbyButton, textJoinLobbyButtonComponent); + + return joinLobbyGroupComponent; + } + + private buildLobbyWidget(registry: Registry, parent: Container): GroupComponent { + const lobbyGroup = registry.spawnEntity(); + const lobbyGroupComponent = new GroupComponent(parent, { + x: parent.width(), + y: 0, + width: parent.width(), + height: parent.height(), + }); + registry.addComponent(lobbyGroup, lobbyGroupComponent); + + const lobbyGroupPadding = 10; + const playerPadding = 10; + const GRID_COLS = 2; + const GRID_ROWS = 2; + + const availableWidth = lobbyGroupComponent.group.width() - lobbyGroupPadding * 2; + + const cellSize = (availableWidth - playerPadding * (GRID_COLS + 1)) / GRID_COLS; + + const gridWidth = cellSize * GRID_COLS + playerPadding * (GRID_COLS + 1); + const gridHeight = cellSize * GRID_ROWS + playerPadding * (GRID_ROWS + 1); + + const gridX = lobbyGroupPadding; + const gridY = lobbyGroupPadding; + + const playersBackground = registry.spawnEntity(); + const playersBackgroundComponent = new RectComponent(lobbyGroupComponent.group, { + x: gridX, + y: gridY, + width: gridWidth, + height: gridHeight, + fill: "#1F6B45", + cornerRadius: 5, + }); + registry.addComponent(playersBackground, playersBackgroundComponent); + + for (let i = 0; i < GRID_COLS * GRID_ROWS; i++) { + const col = i % GRID_COLS; + const row = Math.floor(i / GRID_COLS); + + const newPlayer = registry.spawnEntity(); + const newPlayerBackground = new RectComponent(lobbyGroupComponent.group, { + x: gridX + playerPadding + col * (cellSize + playerPadding), + y: gridY + playerPadding + row * (cellSize + playerPadding), + width: cellSize, + height: cellSize, + fill: "#000000", + cornerRadius: 5, + }); + registry.addComponent(newPlayer, newPlayerBackground); + + const newPlayerUsername = registry.spawnEntity(); + const newPlayerUsernameTextComponent = new TextComponent(lobbyGroupComponent.group, { + x: gridX + playerPadding + col * (cellSize + playerPadding), + y: gridY + playerPadding + row * (cellSize + playerPadding) + (cellSize * 3) / 4, + width: cellSize, + height: cellSize / 4, + fill: "#FFFFFF", + align: "center", + }); + this.playerCases.push(newPlayerUsernameTextComponent); + registry.addComponent(newPlayerUsername, newPlayerUsernameTextComponent); + } + + const buttonSize = { width: gridWidth, height: 50 }; + const buttonGap = 20; + const buttonY = gridY + gridHeight + buttonGap; + + const startButton = registry.spawnEntity(); + const startButtonComponent = new RectComponent(lobbyGroupComponent.group, { + x: gridX, + y: buttonY, + width: buttonSize.width, + height: buttonSize.height, + cornerRadius: 10, + fill: "#1F6B45", + stroke: "#5E8C61", + strokeWidth: 2, + shadowEnabled: false, + shadowOffsetX: 2, + shadowOffsetY: 2, + }); + registry.addComponent(startButton, startButtonComponent); + + startButtonComponent.rect.on("mouseover", () => { + startButtonComponent.rect.shadowEnabled(true); + this.stage.container().style.cursor = "pointer"; + }); + startButtonComponent.rect.on("mouseout", () => { + startButtonComponent.rect.shadowEnabled(false); + this.stage.container().style.cursor = "default"; + }); + startButtonComponent.rect.on("click", () => { + if (this.lobbyStatusComponent) this.lobbyStatusComponent.action = LobbyAction.START_GAME; + }); + + const startButtonText = registry.spawnEntity(); + const startButtonTextComponent = new TextComponent(lobbyGroupComponent.group, { + text: "Start", + x: gridX, + y: buttonY, + width: buttonSize.width, + height: buttonSize.height, + fontSize: 24, + verticalAlign: "middle", + align: "center", + fill: "#F5F2E9", + fontStyle: "bold", + listening: false, + }); + registry.addComponent(startButtonText, startButtonTextComponent); + + return lobbyGroupComponent; + } +} \ No newline at end of file diff --git a/raid-survival/client/scenes/Scene.ts b/raid-survival/client/scenes/Scene.ts new file mode 100644 index 0000000..2eb7d2d --- /dev/null +++ b/raid-survival/client/scenes/Scene.ts @@ -0,0 +1,12 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { Layer, Stage } from "@nanoforge-dev/graphics-2d"; +import {Context} from "@nanoforge-dev/common"; + +export interface Scene { + readonly name: string; + layer: Layer | undefined; + + load(registry: Registry, stage: Stage): void; + unload?(registry: Registry, stage: Stage): void; + tick(registry: Registry, ctx: Context): void; +} diff --git a/raid-survival/client/scenes/SceneManager.ts b/raid-survival/client/scenes/SceneManager.ts new file mode 100644 index 0000000..7e4c3fe --- /dev/null +++ b/raid-survival/client/scenes/SceneManager.ts @@ -0,0 +1,25 @@ +import { Registry } from "@nanoforge-dev/ecs-client"; +import { Scene } from "./Scene"; +import { Stage } from "@nanoforge-dev/graphics-2d"; + +export class SceneManager { + private current: Scene | null = null; + + constructor( + private registry: Registry, + private stage: Stage, + ) {} + + switchTo(scene: Scene) { + this.current?.unload?.(this.registry, this.stage); + this.registry.clearEntities(); + this.stage.clear(); + + this.current = scene; + scene.load(this.registry, this.stage); + } + + getScene(): Scene | null { + return this.current; + } +} diff --git a/raid-survival/client/static/client-config.json b/raid-survival/client/static/client-config.json index d4ab5b2..7a8e66b 100644 --- a/raid-survival/client/static/client-config.json +++ b/raid-survival/client/static/client-config.json @@ -1,6 +1,6 @@ { "keybinds": { - "up": "KeyZ", + "up": "KeyW", "left": "KeyA", "down": "KeyS", "right": "KeyD", diff --git a/raid-survival/client/static/map.png b/raid-survival/client/static/map.png index 930151b3404c5fd8fb6f3abab1e9d4ece058524a..3e824eaa6f5ec6af568680aeaaec6f98be8d7503 100644 GIT binary patch literal 290244 zcmaHT2|Seh`}QCdp`uh`+RmYzqGSp6P&ryohA3s5v?x23D9mH2RFu}E5<`-un3R1R z5h|fz{c+hgev@^q}i z)n8-i@85;jx1GM}u&2}Sz~V-aVK6 zwtgVX<6bpUzE6*|*72O3o#oUczVID~90R6n7>}NKt)y&%K3@>qs1Hr-RJ$2{^ytwl zSkwwzk@~gJA?)b;`k{CnE}1k{SC+QJ$86`0TVHn{`%B5c8?{OAs^*`)*gSI!DV`ob z@qN|%rPy;0y&_Z{A1*Xb<&<^Wnm&@pwYeF^ksm4#=CyuEar6J)l+>MC8{v(VbT0A` zXK`bm&>J^52`RCtZ4O-9d>B)MySNz%zMk>09%%we2t`XMa5i5%9o2JjsivbNyBVVA zIdCsC-U%*dg3onyB#nyg!52%h$7Cb0AuMU1D|RcENJH1vV_(^nCd$HjdEUf3#=1IR zSLzh1W-U8^^rOsiu`jM_nXQf*ZtTh@Vshg9UO}Rc8X?h*`+LWc2V2dGMP)uTCi2YO z_(me9C{AhWoI!lnyFcq$7u1@MC~Fi*Jv9%MrVaVeYqDC!CTzvpS)^+Ah^GrOq0OLG z|CEn#>04iSO=+Cw&}vIny|}QLhF=su_qs|wT(T3KNrS4Kv509VL9e?-3pTbD5qjY) zME)!XFHdb^;!|!>C%EvB{w22w1V(l33~PNL!gPV#gu5FFu9$_8>v(4Ny=8`4T<}{a1-idH9KXtW9k5VH#cPZ@ZvU*h|o9K6owJ{JguG%8;qz#uFq;NFQH{ zpjBA~PWQ@Yw*(q~6h*ZmmS0!2-ke9kklJ0vN0edmTIwmU`COh8^p8}sC`*z49;$39!NTQ(S zH-k1-*d>8wW?tYfrzyG$HdeBNfw}kcnkh;a7q;9H#x~1&A*qAGGLDF2N(xD5LgVqN~`k&}5BL=y6RNb;ScVEf1xZi&I`=*f@FTUt>b> z>rBZl^NCSyIVb*2eEA%+3Lm3H;x>P|RSRMEgfOj2RoJ+`AWf zFMLEJt}?P^su)r=ikVOex`+Zt6roZhG`yq!b*gSLk2oQSk0dg=DqVd0p*|;!=ter; zje)DZA3SNPu} z+4{>7)k?G@=RQ1ptN)4@WlzCxDhMe0yY_1Afv!LJ+tT=#8?GZGDsD2@(Lo?)h4RgcL+exm72VAuD$cLQS8->A7Fd_*%FGNfv5 zwZ!;GQ`PQmKm)@ruOuQ&>OJ;(`5aXkCLSawEn6pL!ZwKpR5YR+~rP-vx?h= zycR5NUeNe?*LGjI-G&^X@*w{4Hv%V6!yjcEXV%_Nj>YF#O;Ds9yKRpkim|l4&PW6f3EuX_et=LuG7y6l&@UzDX^S%h_u$4$7t$)3j3jQAS*(CS(Dw z-4jW`>7P|;Y>GW%zY4Z}pL`j!%7J>g^aX*M@G(ox=wdGYM&guMF++I14SL2QJm8*@ zn|;}U?P$gX)n>j!;7g9~qsKR9R5xGb^Zd1f%+0koAJtC!gqbY+GAdT^fS}0BmADjF z69WSS{?wEVBY0!`OgLT3aE4)b62hf)&L=u#_EQuw5ml2bF0(U#|3NtU+T?gH#H`U> zTHJ=W5=ZVpete=-**Y(i)>UxQsNO_@{BQz%bNM675;RK$S!lquh$J8KG%+V8UH6#@nsT$krk)eA*}-FQ8#|)|e;c$-gtp+Z{>|ea9&#AknD)Jc zAMwU)bnVPm&vcU;9)m{efiBl|(bCC8j%e(wBF>^D|JFIrGR6<9BYzlk?tVMT#m3ZG z*42!Mkl%0}{;+s_y8bq_(UxNtnTRr9Knf0sb*)9`BI8UZ(Nc3yT^2M*)8Xy((9rR+ z4YXbXYuk3PK zlBwM!isvupv8lc7My0E;5nI@kj(uQLlZ{SApcD6B>_oO4S{e6V-`FjvGo^a0WZ3An zP3uktjJ%`oo$X0QP=O;rwAEB5Ha&@HmY-x=bpL&ZFd8!R{5CP!`0KYGrS@yZ42leu zd*22UH>lD=70<-{8HW*+jPyl<8()n0HYhf!N0^+xe^$>ibS6ZePO3QDfDH`DzhdfT z^SejlHDL$&J8j}40d27Bv~>)cHd#Y8AGrz1BQi6i?^a<+9!5rp9eJk#r(WtXjEh^j zZ3w!>Hr|~ewD)cvgWD=)gg@~qU-7b|TtX+dREI%5=T-GLv@tV`C>*`^70$X1MTF3( z$|60`2Y%#YxN$aRh08SkcH$IYA@Sj-${UO4;cME7}~s)=%0!g zA;$;Wa7S#EzK>}8gVQlSy4~=2m~?BLiC8{@Y3z3)kh}v{fJm&$5(ODGHt4L0g?Las z+a?Pcp-$YOQ{a^KxXCFqcJ=rOU93XHTQ~4x20+(WyySr@e^4eiOcS*csk5SZ>2_2m zr5&p37r#zh=_DHqnfjb-sLk5jns)AE$=KNq>& z?A5zTDT*6$UNRmpopy4&nu2WH?EzfA;`lqHTY`3*tTZtbLGRA-;}!MC)4O(okC&CV zkA!Q&mxQ`UyhSxd`&#+*GMG3@;M+IjwJ)^c&E9vynU*=Q%NCO{^v2pO>IEA4Cs8F} zl-jm;KQ@GOosM~l>Rv~`M1_h=$nZ0{AY>m}wz!^6-HbTCE57Oo8e~v*`tb_h*}z~` zdscb%<(w7WY9z0aGG@zflo@&10&LLpXJqQZRY*!?W5TAB3YiLH^{nozs#a{?5U z;VEi#F2aSBg>6dOPH>w*{wz1f6jg8mNS5k{fPS0ynW`+5nQVt;bA>fK&>k^}v3vqYrE~zF zvIC{1V^7={+6o^(TN-Sweabqc%j)ILqe}^oQf`A*y|ke*j5e+QTHP?{BXNeU5v*{viy0 zkkVTor2C*e;0AS4k$PLKV8^893T3{`;ANXc@osE_8I;09b@%T@3M?N3h&I8Me-2^$ zCa}QOIe@Y9Bb`xXb)%3a>)DQO(@Avm8QWa|McX6C|K?B^!b9?ijANaGg+(Th9@zR_UQ_;(M5% zEe|%>io2t^a*LbfG-f!*-xaz!sj5kU2N*5*oY&(jH(w*X+8xW#c@IoM;SfD8bOV)t zd?0L)Ru`MNTyKV&SyD^nUnOdjsPnV2(vf)lp099NcU1^xsR<6tVutvXsglwN8A3dv z%snzZf=T)A4MB7Ewg^>`#Ylqi08O9`?cEIy?l;1;(=9TU#VV%@;XlU zZ7L_zPT}m|2IVem2RvX~TOl!|C~0%i+6vAEoh5#crtpRQ4gVNJe`sZqRq$PVoBY5hV`bnVfWxZgnn}&E`OByLHX8l zA`T4Vr6+F|no^@cnU}*YG%UlnZM9u)fWqsEH6_g?{3o>lFk*r$yTx#9mA>9gjJy0* z?51c;V2_K4?!1*tK65@)_Po!t+Xlp^$`2E_g4p}%E8YlFcy;As_G{Ja(OvKlbyAbq z!z^_t>~3^S-h4Oj{MLm4EP=CLP8StG zIywmSsCV+hjR&rGVl3N>i)v0jcDK$&%pQKeXJVXNcxTcai(;i=rJn4o!lvx&DG=5Fgw0~&xCpy&5iI^_)LHawptKe7+H#St>FNKWCG|kMfHR@b!(Lp!sA!Gq9_@*NLq0R=VSQOP`me8Z~+iv0hiwFTx}{p6&WleE&w z%usxq`y0t^{I>lfZ~>#}to)#`ZQfyrvp1dW4=wuJkkqGVQYQ(cI!U+x3!F4vzwjoQ zHir-}Ph|(0_6wgka@Ou3afu26(WWp8*j^P^q!rKYfSf z$x0{fhpC%|X}hr><(Q=1LEti&1!O@HBm{J@b>m3F6C$_^CWBOUlM$+B@vsVLT3q5Z zUDFc+=S`2kji}?cZWN5t2Xa;!dC8bu>fd8sMe{yb-gzl{onYndpWeB!!}k2*;^iTu zhXEN0Fo3>cPbK!4yLIEQCiYtJ=4#~N=GzC`0)3uMG$Dm4HT^GcLrba3tw$pKXY25H z$Lr2m(AWP@9VSWY@B%-9;}`dTqGyiHn~akjDpeK4ZovwUF<_|zMiN0$^*d2sykbKj z6R9t*LE7(nHm~>t7%cT{KQyz<* z6a52((<2V+ueQLoITNuoZ};9yTd$9EBir8Z^qV&GMaKO}C(GTk3R!0S%shPjN|6+< z@tWw6a}x0#IR1~1EmBtWx52%VaiiwaToZV!^ai_$H{}y5&~)_dyA4i@P!^I^fnhBQGzaJ}*51piN+Ffe5f#%ml| zoHhflBH4hdsl$c5rdRgY^}=ISzaH~fuc8sNpgxdU(Ehy`EtXjHPvaaC-(T9(PiVv& zOGbxG5p~7me&(jQ_(H`W02)hKG_O57AsylVa@UD5f@vlLF9YB4WCHNco)qA;cH*lj zGUM{gcZ43Qf2$oNo+`glH<-JQ@&qm28F$lCl12ps@lsA;RMyXgBJ1u5Rc&{T>Ydw* zshdQJgp65oi7XOmd)Z2$@$u-mg4G~Gbu#DGjtn{Ki$?0}(ha;?P9{lbHJp8Mq7?hl zHhIy}vbz(n_5hWzqM#ksoj7!VCsWOK)2ov#Q z7vpHx6u0~Mj2E9fhW~Rw)-zrL%9OE>ysRLBKg@dwnv69VRZEhDvgvj@4vOXyuU zR`U3E!*C`7l7Hwk#Ucx{dl!r1@)7Gu4jOF=x@^Q46<5iX|H7oS;aQ+H;ANj<%w|f> zEbx$jj+!LH(jlOHLHpOQ!4$wHRDQg_zzk<0YFY0Z;QL$5AAj7>>mofk(7iVb*$1jM zqhG~a60F^+wpAcrxB#S1$-EfW0E{TzNGhyf0vgxBE?*AA#nA_l1=CmB$Pr5p!E6g5 zwMw~%h7ZQF-hnBg8M2EmMb~4}+85%#^i^N>Y-uy2#9@vd2Ck}FL6;gqt{-S$6K3M1 z;;V4s_#e^E1;!>$Q>fN#@uZe&YkhJ1t78G#DWLxM(W5SXF^{uosWwts47@S*QkU1# zE#5AT)RT4J14Q>q@YLXCo0%2z?TDJX7OMtO-7Zgv^8oyllzp}gdz9)Y+}#V~`sM(x z%p0uV1;+WJS%NGE!4<|)!~osOWr&?EE6_|1VH{d5L6AJLY7syi2hcLhUM%T#^MeY&VL-nb=8>Q?r1A9tdak+{kRkY#FjdfPypnjf$G5bxmP(OR%mXGuMO4l)=s}}}t zN(r0UhLx}VLjp;L)v#h_{IBEw{QU^fJcJ3tZkc*;;B=MeScU<%ic4SUH#>kKEOpNo z*g%rOtfiixs5S^K?sj6#>Hp9w3m9%^(`BNIId3?PeyYjf1x(J*@LYL^II;gB8H)n~ zKXUud`OS2{i}!UvWh~eMan~ zy!4i;*uS~Boou1E7g?aQhO4gk98>)Ky%K0m1f>af0*8<<1UYjLAbh{!xfiN zV~10+p;2_MP^mWqvCK9X&VqK%0tVRFWPrZlDHs3!mM2oEL{}o%S`G!q6kYwO+ndcI?nj(T-8kHKiJ9pe`oIw$v2F$b{_Bd z^b1}VwRD!WeLS+_!b7NTob{t#Tz{mMe77a#%t>pN(|J9gLw9ER6q&S5n*cnkR&*-sR!q#&4g)~IX7`rieu%G1yZNQjPEK!&zQXG zHQgIt2X&R2Qu{^j4uO2SA}EtC0tNu>-1;!Q!_8Sh(~HfbcBwEh))KKp@Cb|ACT_u! z-mSqZs*Yg~p;cVa`AYczc0RM+F{pRUL`HpiE&uGY28}8JGHn6YOcHc2Hx2Ka)))^> zd#GG^|7d8ZKIxF@qk5Zl(U&WvjCB|lrgq_9tA|rxF~f(Sj;ToR#~RMxFE)c!ubwat zW(O$aUJJrlOWyYXSas3({I@Qj(sM8Sx%TfJ*tDy3#X5x;98T47Ylv{)(5Vo>s>gC- zT`$f=U0%MlKr&9P5(JIFZi~`U^Op;$;lK5vX$Qm`M&nC?K&7j33afo989AB6QHoM7 zxHYq-)EIN&5+l>lfOsevL)P9BQY<7hzTV!GXwV4t;_8yC2_tySoX zvhKfNE;-|ld*_dOEVHCJ8EWTjEqz@qx&as^i%EjnPwj~n7`gafUQ*$VNIx4)HddoR z`T?ar=%9$f&B(FA%~y1;)RSHu8O?zyXkcp~wca3!kCY2&6px z1nz{ttviV7n(e{T(R&xs8~d>=CSj^M4NHsf4hdRl`?)pq-)p)m`r%&ENFLAG4l`r9{9<8~gWeT|#GW-DoCi1ORm_37eK5KM;QThDkamQ>)2n z_~dH-6aWML-=n~T7MEQxX!{6Y9;2UHc0sjyV@+KGTNHC%2RKAHg43#EzFng{cZWHwbz5v?b$N$rp<3V2zmWvUaMPB|jPJ9$( z70_~BEWSq z`Y~r&%YPVEx_uQ8D>SH@$;PCr`!RZxY{5F<<#@%&KkT}1$xnBOHdK*1dA>jX02aM^ zGm<(CJ>}us5Q(V2T143qkPV%d833J|xyMPQ7lcMz2;nJ?o=C<2`*TT=?u99P-=fa5 zoRS$BL$^#&!(6ZSGncs?(H={Q<3;sP{9b3>WkU|5xSHF!e#+cT-Z&>!e${i!xZ{A% zx)9ix-+?ENi!V?Vq}h-6$4?!~*6+uwW7XABEP|Ps{dTLD|GCVHkC)zP57%Uh*Y2C` zD|eyI2q7EY(>sfPMWBejv78|yYeu*kJ}EAs1R(47%{CTEeXCS2Z1cl4a~c6?k~*jCT1-h}-lsm)7BZ@M)O8MuHCs zo||r7_pBOzgbE7afcdj7u6U;55G?^JMru0}tXK};R;hfWo_@u6P zD$1->Fr329nLQafxB&I4uMq3|1nbSUiVjaE|L8JD%0R%3c!P^@bR{}Nz;_9~t_j>7 zR?QKf)LlJ7%6-&!25%rwo8u>z#(*o{JSWUgQ=S!r;yte1C7QD)$fnT6j~-{52R-%_UVIFefoz%Y+yIIjZ7DL=56$HyUnAXl&IgH}af|rwC0geDOlNvX zC{}7Nw@CqB4@t^{K~x@;*OGrZpViv|Ie=HXcMp4=IyajDQgl#|@tg@sWR6xEX23{0 zmZ`^CKkk<^?n2qn)oE}h?9qhMMH{K{7*?kIc;}X;<4h4;Z(#em<{sc~COY2m*`n^q3>%L)^l)gk zQ8N9aILZ3fy>TWmRPaNll$^f3?Tke{rdQ6FvIx{I-Eedf7X56}PZYIomdyRYJ|hVa zFIMM8&aqRS64ngb2h1FSqf}+`jQ+Z_*aDgVHG~n40BZ!V`zRm?|6!G91R1OMUIq*s zves9iBIC~VuiKPrePGj5LCrpz=j74UpPmZ&rqpK>o35pL@MK)%6i(J*@jtyyc%7`W z5S6&o0WUiQm2NXKRe;qvdG2fs5U@H^7c&l2)HkS^+hEZF5)lsb|;>UM~}q_6+aQ(sYFQF+qv}8(d%nbQwg7H=#zK-O{uy5 z!db}$^kCB&DsYbgefXp}Y0<@5G)JcZ(q_LSA}CmM6OgMznx10-=Ulvl`m1af1n*kO zrK_~On5)d%KrV!Up-J8>;1iUNdbEXik4ayUcrVI#biRKW$Hs*3&(XX+GXFOMIBuT< zXs3^*?f3l%LW!3n(T|KD$fFJbN2Q9#~zA3rKK3#th01i|qBZo8^ z?=8Ux+nInMl=(7E*7w=lFgNxiU7(>{Xd{AvKKvEXhJONTnge~se}!eUAh#hhE*T`- zP%@_PGi(iiWo&%#xn@YF&iJ91sL~hkTI|fP$x((HGk;cK-F8J(rUG+E9VitJ9R}Ze zooXgJRwnNd$r5O0c+y*mIM7T;N!D9lC~cu9k~%(ZyR4zn{O?4;W@o@n;ea?0_@n<& zJ&OlkDWU3sNj9uU@z`Q_Qp>gys zEa(e9;sti}-5gPcrhuIBR@wK8nqoBX*LWB*C?P_N2Z$N}&{Yzh#{jS(I2IV+d$FZs z8SAtrfpg+1(jVRvS`eYl%Qg|!ijw<`k0=b}x>wqUf0cex1}Mi1E;~+X0MV>@OR{zPPk8n~GH1ZrwDnB_Y_u$ZBFsNIE z-kbsK8A)@wj|T7gZQzdJ4_s2cbx@>x^oY&)!M=0Ro5r@i4H4epRMh^tKRUz(U(FEO z(wfI6_8A>oId*xxlcBlLurQ8=jgv&-elul1=8Q@+(>G*vb;PWMvJm}PGeS)13pgU& zPF+!N{!j}lbA4j7%F>_Kr?Jl4%Wui2BqHLN)GpD{ki3u4XLGt z(W70;ZQeCkR~Z#vbV>T4RQMV=EZReGM=6GEk0B*MP@CMNl%Toi&ISg4eRLVXIQDnc z*TE>ZE+Hxr!34&bykB1_@XE~~&94&dvic8WoBan~+i6sNRMmE2y<1j~`Ns~XmCr_z)!sB?!Dq)mf%WRVB9$MZ^jkCe z?WAM3;!oQh^A1AL!G;;{(aPwKn1j79mEHAOn-{s=&7V!T&-em4<|~OttLZZtt$Nz*rr%a`hg9}4X9u)iOJ5m7D)IS2Fu5F*;ImZ{e5St7Od<@)7braj z;6KdZA9hb9wUOrEQxz>LlA$Z+0xF`m)=C1CEqJ?KBAOb`{%sultt%|LHG>d*FjYP# zI8F~Yc>*%5o~9E0f{5jA33hX|xs(Lv)n=0%k>FQYErj^}esGzQuMmxP^-Z6X6W=8y;IDj7HxP26g{u-XgAcBex==nd z!I$gPqz?-k@JOLu>( zxeo}K&m`d%EyJyvt>jOaUocu$aIviZ7vonx_|W4yO;%&==uC9DsbZ<{+0|BjdEIXW z_?<@e3|)`c$;k*98nLLKro8DGJ^I%uR^R9U?9Cu*4A@dYxoqs~kT-oyG$1&&r^BO` z4x3 z|H^a5YcF>~hUG}%(MX_k0ug&97$BBu1w%gd=CTVl+=VQ4882zCja{Fd8fMOIWJbM} zk?4_GmgADPa|R^=LcI;-};I3?)Fog?pLtV?i8Hv&i^m<>S>6zrhC+^9GUGGNR9S~*Xl7Hmp zl$U6Ld;$=%7R(7*{gFV((){;e|FrnzB=yBXLnC+chLEF_OoAVk^1{AED$UVfDy1f;y>zwB*_zhL5xoTV)%i>Z}OS%SxXC5(iEiTrfdc+3%g`> zRHB@I1s+}+{=cPWA%Js5^0&dnO2vcwat7T#N?p+-k!wmsplm+JJS0XEx^Bw@Y_5dU z8*x=ff7t$XOnsodu)nFHiPrPGIsSG>;NTc5&y?E2@h|I?Y;qJ4_4=#)RDsZ2(&xO{ zY}*Mj?DaYl0Hct8UX%{Py4wF^VeY2jj>zsS{vM--J0Bw-42&gD);NEwF9Ie9O`@CZ zm0xZMw?zr4{qX-cU1(ZdKJ(h5(lq<7bSW6+-|yIa^%({Ci8HQitjzG zfA+{X=*{eOO(t9HAP$Fs<()&dIgN{6{iP?71^i>KGNbDd<;K<{S3#st_GiDyfqA@O z+%#$V!=-c49i%M|990RPqrtUPfXqX>gEq_mtMHf#oA+UolHf0IBcMtBS;$f4#i`e5 zJ$nGU_y0Ip&8ovYv54CfkhPg{34sZ|5A`hTQ*P@5$#frBNI^VStstvTx5`Hv=&xE$|lw=~@CmF<< zg|A+ndF`NCotCrMyvs|SaK2kGbCLjEie_M*&zV7HBH(r%5$<5_7z8>k_yGP!APw*v zT8Vj1-K?*>gZD_@3s__R49fU6c**&7gUZ3H`5o2$Q#=328O+P?x_#i~kDYtc0Cx?m zO`g}-F{=P==ZK`zQIVxu5j!p$;}=9S=lbR+09Jyc4j>yebhwVA@xj2@##0!C})N$%mLZ&8VckYDe1;aE^%UajTpFb3*-$--_ zd7gi8`QX6R2220hyK%EPBj=x7P%;hcidOxvCZx9)8UJ8^(sva*>LkI4P5GJY_O1W50@Pox3=t4#oWw-ioJZtL=upK2BW=C)Y0AYi(A zQ}ax`)~6FCCCxKu01x1hos&zaR1R-0B`qq%NVefU@7o+&`Dl!;uZ^MXA6kC(tbyk7 zP=$@>V8y>p;4CDWoS7ny<{%7QnC{hM3e`D+ChAN9uy@Nw!@#w@kWh}rwnFxoH_EO9@0OZjm_Fb5?)Aw?aVpZ~wf&?Xoc6#)sv29y3X&M1hrGI^j zM*#eY)B04}7h~fdwk>u*>HA=gb0j`f^(saxW;N0Gq<(A6Q3&P;`hN4Mt=T^2H~6}s z^NNP#>f)DvR!KWo_E2k<-hL`TB7jy>{SpnaazN@SN-lHUizC46v1fiI$bYzP?RD6` zWAHPu8KD3u{q5M#rJlDy#yRZWKX(N@aLYfc2w%TSVX@RJZW=d9|C~Q-3A6+8KkL`Z z?=$yxB|Wk{ofb~4Nq}hVsUcIZ=Ayi}1;#7Jx%wN;YykwA5N<#-5{Z%7*kj97s0V1O z7b2Cp&5KLh@H{cFt$>EN7t5H(>Y{s4CBs43Jn@0aIDe%^D|-CZhpqDMK0{|P7smzaNVLEi3sFF#yv+&lHp z_T1Y1x;-P9MPNPu%{ld7TU_7gwzw7s{Q&%%vc%si+39-w=`}mu7Vz3YYe;Mkj=SLv z{^x3c%6NYJgu8=f)f)7HxMG?h9%@wCL%~d$DnXc32n%|48>R?{l3_0_iyPksukI2v zQ!qc^-zh+)^4amxAZ^S{C_tP7g0h7(>iur;J?zvBjLRk5W3AjGyW&}K zh2;7Hx;l9It5tTkbYe-E=0M5Ez1qQmd&>=Nk{S;2Eib;o?)RXvre)^z5wLVu#{;>M zc4uiDPogGIeUo9=6OBn`#XI6Q`q+xdM@STK6r6rq4%P{l<|HceGR%YqKV=uageL^F zcd%}M8>A_Y*TqZ$^~5fUYGo%Vi`{^B?;)qM0oo>t53+^p};? z;PE?yVo^IWUtT-6M)mtR&gvk+T7|2=jlwE2b(e29Z<)Uz%dzs2KU^MleE3Y4u)g_| zgl{ITerSQ8*WUa*x(j{bu;49pBM{L&p-3tEU9`Nin0kPhMlB}wjB8hagl{L13LD3V>>?$`h>yeAz^f&C~*E_8@BA~fqL5vRIs1vSyfRbG_?iHdXOe$E1%jYIc^X092 zM8t_9@+)AExQE%SufSyd@oQD`)v5bCB&%$b!Mc!-X1AFsXpw z0ILP|Uo<4`PyI^#!Y|2j$FyBRg+J-kp=j9$9nq;Zx?%e7?px(A|KIb2IyP9AB>Rl0 z__Al$-_nbpZvvY?q3sZxY)sYcZ#k|xU9a$|&)Qw)G?usfXeG}X>zTqE6>UbyKz*Jj zUq+aRU`q?vXvrnf4#HCJs3Ek**@Rnykrwk%V_z_aMmZyPQwPwryfyX`vwa{h&Gz!a zy!HWaq>>(&w<``w7qFV$vZ~er~i92^jNU zj}l|PX$N9fy%@+XCoJd~=J~DLmbTguhEj5=`gh-hVRhRG_(c=M;{&rT;!oXs02^?F zds26!(ckVIn|06k25z{!qL${I3#ZU|1eYxnTGwW&Q@0<7EkHr%&oHf4ee=EeEqlW3 z%o(g=bdem#U;2Fa8b1)OwChy7#psWBBnu|+ z>c_LGl+9O7#-xYip$)*q#Dc+Uo-Id|w+}qULrV=%(e>%3p+(~`P zeDAI<75GU%E5S^GM6vz#QkinRG~|Ksq}*v%+8ay2UiY24C;G<=u;?1g&D|06`~WXP z^^1dsF}FJ%;!rC!Auu5ZWkI8cdtG6Y?;RAMs|5apgLhl}5S97J#i!&@^WT%F#0idj z0>%5n(S4m3?V+L{1cpF88>Q<}rLUrUPVau<(lrqhatmxzuD^Tv*JrR+;wuM_Sz&Y~ajGW%R$(&9q&s_bSo z;}-OX(!@hplPh82qm?Wd1&eE5!I~%VG-2#bvkA0WQu{#z{XHDpSAy33WSs`b6X5g3 z7fD=PkM4Fvs6xMAx?fj~@AkH`9RsJyQ_cxhMz?Wp`Twze9su_g;@* zhNsfFU%j9n@(Ra*Y*f0+WqX0~r3S!5wtns((Vj@qeVqD&urA%QnRN+lnC-q*abP7N zQxjP~I8x?eJ0pnlT`;rrzG?D~EJni6!EHumlu^5$+GqrCZp#NZl8DvZq;_5_=1^W> z9>u*wTgM1y`~l;2N^Ilv^~Ye#+3JS(z&Q7TGuj$Jqdo4?6G*)>DZGf(qJ0+8-ho*P zqR-h+!%YH}G8CC|_DyZ0uV+DxKzX$kG#X7$0YNfA9)6B}y7pYC@}+~g zgn^f%O4p+5d+P<-r)AnvDPI!9sxv~}&?LfQ&w z!}IH6Zsllxv)q)Nl2}|UR!QupVD9z!lt!xKBkiORSqbkxwoL~4Sb3+AZ{J3=MM49> zw(w_vt3^sPPr!a&{Y~JcQZrhgikYP1={2vg=R=SVY>OegRD~@B5y2GYSvp#!Rqt7623qTK+hHdfSU@MG~(u;5p-eEw}L_Mn@*Vsu{QO;0S!Q$5PCacMyO}8q|4;&0Plm9x$w&6RTBy%945og4asu zlkC97VfD3m*_M2?eCS&;GXEtlvZI;*Qr0-L@KV+_`UHM&KLP@18O%} zUx6tpjB*H{G~lzFC&|=s0GvfC7J7($h@ctx zM7hvSzP2X@@GzFP6WiP9UkI-C`Jtj`-VyzW)&5Sr1XfU7Dcu!B*K^B^!0Rl>dlGM7 zn5rlY;V%s|%j^%Tne%8M!eNK9VMgVHmw2pZ7Zr_J3a{=HziiNM_~j8!2JEaK$NGY9 z^lSe8m9TCmlR}(@q%l{EMJfg8vAb<(Vw+^MUzjlnu>SdGxCgbTz`dg?dk5KsN7q~7 zQQ_Mt;2jmpf6;<(VEF*G$mFwG3D6(!!^Inf8p^O!6BU=w)f4-U84yVx*SMY9*~h`+ z*bm9EOt%|~!MA!C+o!+tN$r$e0H-6zR?q6m<)OngZ?G3Yp=z>G;~<(`Hn z;0DEAP#73&Shmx&AR2!;Am-|7RNl%Ki>||`G+bg1gKc-XY7b`PBPlTa;4a0AGDKBnd3|0DhTHs7*)R<6vhM66E@{H7hrplRzO{=N$^?FBwhCu_Bf6~UTtK{2R_^}tn?L}jl}Q?OkgUI z=AsGvvCMb~S$#{WAq(GYq8{~48O3_QY&85%4;DyK9xQdN!6)Cr+xmj7x(4q z<$nwvGaPdNgolp#MgAqjc-|)^hYqJg2+~*6EQ;b27_ek_JPUNvj6Y8oX|+^Sswoq5x`#m4M@Y8tRd9d7=>0lOX*<0Drkl#3g;7r{#BsQ$&Wc$&|vu=SipF1au z>&LEcvf*O(Y_vm?2K|6-0%_nUNrNsPIrW_OYiwFN2oYGWq*00Udg1G{$t^ECzy`(e2*`u3 z&YFENV~{p3K5$%PJ`d{Qmy!QGRo$20SgGItsPNbpq2u@hW(cX99js-z|89VKpKnZq z@7IvB%8F>Nsh=-c|uPO@D;XZn@V*$igE<-$RV;t-N-gjP!BTF1`x*5TsBHco9kU#VLCjmy(hj$A23GTOemD zO*B952uYiwD+WJ6c{izVBG+QTp)1+`%5oo)?arpG13Yz@6fk*=*!D}l0TA1;G6px2V}xtBv&EWH2MiP^(6Z&L0MF=Y#LG!Sq*9la2W$m zz@-T`u@uKQgHHt%(I{25-vm`d(jm+etWBi6f+xf_!^Jm_rgv?>HsnI=<(ygr@M|R8bX19y1ePUW7{X?Up|iZ z*lxXNK%))*hKAmvcFNrpC;n)gpO%a1@b52yZwf_x@nYQ9QOWd9*S#2mk^9hpjIUgtGhFCr?x=l_XiF zdMc!%6lEKQwAr$y#iX)l%Nm(m$sW@#iLoSmRJLqWh{~FMA4}N=V~jCox$paTMm^u> z`@Zk*Fa8)c=bX>^tk-p&meVM|HF6gI0b1a+F7N*ni+puXM$`cHnd^7i2}PMq0>Msw z&pTgdtI=_r&;EoD-~9yvwA-h+Grz1b)V>-2xs5R!hK-{ED*sW0c(T-5(bi{fL3Dhz zWmo&{|HA}qR4-STx<3q&R@I~UQIQ%V3Us@8F|Q2*Oy}RKQfV<{5mA#lS$V{+#soSh z6@Gd7nBaTM_gcbnl2ppXWI};UqqArVE z74AE5`7(fa9LoQEeRtRRAg784+63*W|I()dz`<8v>Y|cPMk~S0C_n_3go5^>mQ1w{*;8CNTNTClU zbgv8rnIJf2ugqGU1DNNE01GtY^7nGp|DZx*yhbo$(Bly!bI9bk?TG-}^8v&RuQ}p% z^bxx&n7rDA$?L{_fn>iTAEI~3fbMu2YIrID?Q(=or~ic8M$m~nKY?M;>=j>M`5kP< zl`}Y4U%c#5t#_gRy$)aeb0bvM-P{3%7!YL`zUJEE;^NZj`BR57%SiRxVhxU6Q7imk z#6uNV*M4~WO@RMjgTgf+Vc={C6>}vR|nxrSH7LlP?V_u6_wrL zTiR*NYV472ZQ$`h5xAT*yYVQFytZw(-N{m~h0qhu%&Cj_T15EV!(%n>-~BHFqt zflX*94ThKUVjJKvf)s~ITtNj5m5gK#o3NsvffEPWjdwWqh!++Ch=}t+K*@@=68>AD zK=ud;Zgk^Yz`B@Hg?dli0uoNCwRjDuX(7JDk}=|Cd=61{VAOVLBN$6u^YGXRL?c$T zz#Alz=!X)2HSR1@A@gMW?#AC6v0&;=@6Pc}Tzf4baQkN0>~$j$7ZLXBAiA>a8c|H; z$J&=fH9%$*LXR;(110YgY)Y?N2aKc<;?INAC31aV&(MHlzGiM1XMEDFn1^mdD zrKrcaYTqXtc=9V%kZEqfr?~UhE}V{SMV}YlIZW7F>OhI`RqRm}6MfssPYpGx27?CRT4z25qTfEE6B|&uWDbjvu>+w5a`{`p zR26$>q7%(c>cq{0QWEwYSN%KnjV*JQT;~SS<15o$c)tP!o!`yd%(#l}2a|LoeXeloi*kpgwB}Dy`Hnj5I>mAn< zpGU|1Qo~R9_Nx4U8I9Yn1#W#T!P_@@;reK+^byDRhRN-=8m2o2Q8xg%wr?gLsxf1^ zMn`SxTxLkB^leAlmZ+h;Vky)j@W&yUrDt34ZyD*qh{qxk$WnwMYCG1$KR!cmVf`s$ zB6;0oR1=6oFz$hyT?p|5vHApX=Y-jbnH@89J=!mnbGq~N^&(%r&ZZghb~ zSYypiZ{nrdOjvdtN!8(|YM*a{bXU@_5_K3ppp?i;)!xL$0`N{hi=WK~DP7q5F${?$ z{k^~iK!yNF>hh0U{~6r|Q&#-IT&xj;20BSefa|N#(g7NhX=CCo_s$~TS5S}R+^%|%cDT0eN7r0lu-txX z+adsfmHkzv;qoCe+`H6{iRarY<%)a1ILd6QvZ-JaONr#F(ZFRi89k~tAbs$*ZF%1N z#L1URne_nxIme?OR{!vKFqQK*(oK>Ua$fs%NG3jm2b{2bV;zRd>(Zd+&=)Y4*MaVp zl-hqAA~0IN@1hHoPZ`O=0!wU&Mii%|qm<&Ctju}0m4%2gM`Uga3(A!%Q=lZCZ~lPF zgCSS!OUzIqS|E_lO&%ltZ<6TFijdfN zzYD_)O1r$}`=UEE4#oK-XMK91IB@K7-tehPLB1vTf|#@^&;_`>#&)XGJ+S2kUv`Mi zmPP=nusj^d|c||4@t!Q!XjeX!$mC$mUg?f3%Suc1_5o}KClLQB(Z1m77)A+@A%y^{$_3ma@y;UA zaHth9x&vVW+AkcpiLT>ynHSX$m|0Da2`Lz`eoF2 zwazP@JFW&GEq~CwUgfjDK#kM+hC&6IsmOF0`lsWyM~@GXVe=|1|1ASf<*y4NxKVOx#F(!A*YLP09qp#=NGuO zwV2G6NR69`srTVA5$YoYNY9l@pkh@>gr7GvpSSE%(kdU=@%mZebHJQjhI~*1(Ia^y zK(Sym8o{+(o(m8YXP3-E#d6td?{)sJ6%R@@`0gy4`g7b2DxCt<<}a1(Es*D>AMb&Q!M^QFr72 zqar1JyHP}hvXVzq7#B17v%)c88eU)k#UWU}eusExU;#u33z`kz?0<(eKq4AtiC{ON zZ2{cl62Sk^BM&cvAHSON@Ue7u)JqJ1sGJ17VEO|cwa;l&nF`yn_kP8rGi!?1t4z%P z(I%VqYixc~yL!2k50Y8!SauYrO;BwDcODeL7%~6ciUJB@fmlIGqqBLVS&$ieG(+dP zv9Ntfi!FM3rMx__(I)pU3OsoTDYs^ks+!vbrI&t;Z`ds`ZBSo{ zj6p&#i=xHW_ZZsbK6wMMi)0ZU_96vyaKXRY53VbY?a@SR#R*W49>XA@w{&q@tTVCV zL~iNbu|;S7^|o!N99w9yCohrsg8@zPLB{i*8KfklO89xSfq8d) z0{sG2*1g2WaG5KfA*WEszo(Wc<%m25h+hfpLf1%fFxxrJ1yt<7C(zYCzKGIZq2M;~ z#)84~T*(atWbzfX9R~K*lr#%EJP9rELQ2q91*sK4XAPfi677_ACC67b?+*u5{Qd+|#0i?0_`d|n@qY=D zoCP16pOr4}V{xSDgbK&_Oc5Y(~$$m$}zz(Yrsar*h!7mL|)zqgw2lwQ=wyA(ceg8$?&Rk3k4mn{%p#G*- zp8AJc>4FFXJ>l4AW#FFxnZ>zX;#;=3`%ck-Gwed(>xyl1EmaK{9ZV%lh?zm!7&*|&p^HWgj@W%0{w<4 zS8$rGhgtwf9NN?gB-_MM#v;I2pMe_sU(tznu(yCO9;j&vlQa*FxdA5Qs)f4$!)G)w zI3KLBHq%SV?XUC41EF8@-T>F<5^P_=wEB??x zKR$aXv$eMdG%>sH^vo~F*8prw6#5s^X9J*;X9_vV*Zv4=`QY&CN6H7xIiTD&inTjW z^UT94f>M+h0C8d5I?!a}DY;ev>C&!bB?8OBLfq=m2-_w%D1I2KC62l|-TH%<7BSHWdb*q3WMZ4%-nI>>wnj zp(r=&dhO0@>4hiM!Y|d7J-zFlXnud_lf2fvdJ|s!k#r5}z!h2J&APFij1CZF=GpQZ zXYlJ8LKC@=>(CH53{~A+((w&u&};OsVB(VEzI_g5$iN0$;GRj_A98(nX2N+mP)tjz z&0^EgmPJUL%E0J@(GUbGJ`l8wF0<1;0aN7sf@K%13b>bdtJ$ezVT2vuwe)Gk7$B}RP>R1&Am$E4e!ueR=eiU0mE&>0+Vwd|TJhS>S(cYQ>3N)J(` zbn`yP|Bqh%0f;kIPTx8IJ#ZmdFv!rP|4vVpe!5Q!Wn0pG|LY~AA(S`5Zf?B#@mR}2 zIM3{ow1E)}W#tD)HhR7W!iGSyFZFz(+jDR~ixzne;|x+Zc`_S%1zW0k{7P@fNrPKy z#HI0C1>?j~_UH@f3Wqq2y*&;5V=nsQGZ4RC_K!4N*r-U*EH|FbxlC`?gF?syf`$|$ zRlI_l>u}l@pbHHSOX1ZU7tqvUDS3;G)q6&M*%|pI1vKfOW*Gd3Xz9IX%Y66pev_tyS9?STrp6XTm26RF8#`fQ3wP!YRs0JJ85vd`vVeu8nl5plcT_$HD0UKISePfL5y> zHJ2Ocx)t}}!S&vv{)X#7m5Sz>9=78Oku)6Fwa%!^^TpPlKIt&c@{_q^-Ir^Fj1yzE|T2ggRLt>`RnV1i?FiqCzqLBjG9 z`|cIv>!U?hX750K*jK4_q})Zr;p`PPN8}K+X$WvM!<;N!qZR)pW8Rd_2h_P!p77*b z=rRZ)c^it6sW%`MONl1ErQq(Wp^i9cxgGl+oz{KHB;HVQXodXm@_KyVLG9?z2D!Rm z8gjBR?>cg9GH*__C+Qpe>Jm6C@u;m*N z9eL!g5RSqe2nc(|>fWm$PjT;QTzm3_oe-t}nuY9iK%Tq> zUvnfH>RqmPFl!wrAgdd;s081uMWWA8JCt*(nhivkC^&BHsEC3bL)8^2V4z7!vk)jB zttpD@@m&hW4dMR1b_rEkAzJ1WcY>aXT@QII+XrNe+AA8B+NbeB4cayhODNF20s0z& z&GI=IS8unDf28wPtE-sQfrfJc^4D`--$SVOP>DI^4)KzX+C`_X1<=D8eInoklsX;( z9mC4@0I$(vf&Y{WSXa2i09Z(kI4?Q(MvmoTm%Dd8kk7q(M0u^`<9<*rc)*u7S|VQ{ zO*nlly`2nn*}q{eVKD@7FmJ;qbJf+J#yiVaq!AtCH*L(8%cyUArDQRub#R+g<-Au! z%$0}1w=fN^ex@06n5xNcHLwECDzIEx;h~NopdAw!Q(C z7~K1?mZATR%3AYOF5Lx)2oH6v6%e&tJeOy*&$q&^&=E*IK$;^OAp?M=$lKTzJeA=- z`3u;Y3{qVHwn`ZxO=J6piqN&yp}UwEWq|7pDWNMOlwW`^o`#&CqdbP* zg8c5Y%c*%l3)ClM8*7Ld2RWp>SYtw8&mnI5ntj(o7&7*t;SQ>wY1dpEAi>w12;WPm z42VE$g3Fwz$~#X0ureS@g6RSBp1ld1Hx__M)3DYks3(9F^6GYa$YQ`?=QwCS1wiS& zmDHcVTYUz!-&!HpKlaRY0YcLdz&3#Ta%w41A%m4WbO9=z_+1(O1ai8M5FJtIN+&Rq zk8gQK@)?lFi#~gx63^G2o&nVDF477;I0|Ji0UTT=36ST05BXt$7EDG@Hbuo??I>?ARg8^a?qR!n!8gOz5`1i+levkx(*cOpz7aV5_h6D z+i&u^P6uH9bVlA;&~M~~{6uHS27YKfU}L&*fU4ljM+LBbx5}lU-iN6xDZfq)*-rvEA1g2rY!?&xgf|frS+sWGwMMZ4<-y6d&uK7ez>V}@ zI3WNa`iH{V))Drbl+@cMJL@$B=z#EK25^li4u#d6@n9U39JO3d#4J$?kWAnr+t{Ot zPy&|(_?SIV{kG)_wtZpq+Fki{EF*6)rp4Fe`8piWQ(>% z+PsdIx*CM6p-T%61Zf2aNi^thJ!h?{D6?HraMi=$q>Z~`+6;M*#uyY`D*E;H(66(n ztTxG?dD;|p=2_&ItZP?%I(l;|@O(BADJ-({jCuCrTk|p%3ulArn=?ZfibAjVyrkHB zhcz`e9<#849r8$y$$1~6L{q(AZOtunMyFI&XSTasGjWm&|n9w+*775iv;Is<5y6qLmz-CU$Ed5VbD5?wRgk&QM1k7FQZ zj|KFny?!@7VmiH3RVNON1Y>hi^LkPa^}(7tOrchgR&jGtuD#Vut7(Th>ok40tHjB1 z!vd#x_)y%V;lq0sa$}nFNIwSKh!p$4!I5C6^{`cdf#>eMu5yL84#884LdpGP-e@3E z)6s5f8AEKony>S!)|0c$NhO5Y-VG2dM@gJvS9g%lkGHPZNG=JeDVjK9eFR8Th z-3nVryN$ASb!CH$w&DLT$eQnA^LR9A-8y^l^Wfne z7i}+k=Y9>)t_@%JenRMY+R~H#Xr>)$ify6Ggz|o2w9py~`nnEVsKq2DIR~#9$0(duM}jxlb3ecuX#NSX|D8r`7Fn@<9NWQYbTJ-Y63rF4+BH+A{yrsq zXXLb0eW$V2jK+=^Wc62hqwa&6{DQ+Z4i%|u)+NnU`097g&3=99?jl`;eF3LU9^@{; zgR31Kj$VKD)oXza?(W-nFP*1G?!WVDy$pB78f+<2HJ0htWq1plip$P*bm$k&yy+AV znWE`OOf6;`zCeslAdhw+0SxYwzcM&D#wcOi6e1!_z*eUM;O{RwVJ(s#dI+)A_U2?J zFJcSvTaTje@fR{iv8UPcSKSz=A2xCu?q?Qh`YpA1E5EKSb>0zfbM3QQM1J+1`9ls) zH0LXcR^5Y2gX#fZl6-dzu8nruzcSH8P5Sam@lx(cvYs89y#Z}^N9)f@ErJ$np_Yy? zlcf9#?ZziU8BuG-p-`JeC7Dk9fpe$+@-J*GO@7SM^h`6r`M+_y|C-cwx&Eq4YDMc* zSX!LkxxicNjkaYLO_|yr=_vBjM?YS^P@HSLvLmtFOOW}T)0;)GAWdM2M_YAm^}@X_ zNp|Bs7GvMk&5b^wpU&wUGg9lVwVtUv33kh#;5r&v4`{v2s4SYS4r1Da?_k_@V3T6! zMTpR=h+gz`G~^UG3sHB`xcUQNw1GGA<~q6tM~-8*$JLQ=86(7*ah4EZ7s@l9_#;dK z2Fu7huwva_8OUQIeW63v?#%(iUGoR6)i1paZZOQwd2=(t7J0CWy|5;KGAT2s;AX6+ zmFQc!KVR{IsQH0-y#w(_28++jbaNRuR^CB=X&A;3QqB5nrrVktYa4v|zvci2!YE-= z$Bd=)518!C(hprSYGtK&fn=_OfOP@~e7GGp$_1aQBkm2`6;vAZ98-|WAlY}wbl%|5HBXShJ(ao6{~)n99(zpQP2eg-}7f<5!a zz$`0a_2!o67JKw?VrI=y`(pN6MTJ+8Lqt6)h2E-yF(U7KLBl1JA#u@c60#zoC09AO zk>o?~*|=xidL@q!&82ZIUyZkYFk;&9oJT{$N;QYZ4i)E3?<~3+hzGA1OPt>dZt)R( z(SZT}Alc}hd@jLpET{FDwH+bmpBL}_%n?v6lz*x+V`23!d$#aG?)KSDQ*^t?U^S!fp6=!dkTrwMCVwt)@b$?aFG4z z>@N8CnOYk=avj6Y@a`}csrVmv*m8zTUN=Q2PO*b7*5O{UYquSs*qsn|o;23myfOUD zAfLOle3Y_2JO9In@vR^JCfGXH+GDq7U9WsuU6`#JGSNIZU8kRZ$-#y?bP#h&_9Ug& zUiN$6i%Z>M6f(T4oq7|S09%~Vb2*mQciJgAPVDX3%shYY%Hw8;=>RZATMAkNF6Sbh zRfjzt0W49WA9W(48609A@eab@u7(Qjknh6Yt6G%3j_|i|h!?S|P9H-}$8jADK(nBl z2l55FlH*qt*#EQ=c{4?MPV3jeN@07I_PY8%e1T&=_dNN<#r1eLdE)NEDATvkdZ$2! zUlN8nSU?)Luwh@#h!K8*5$+Lw<9;+mQg{X)vaoq2=Qhf14?Dq3w&A3HfQ~||o`~;p zK`nqIE{5W&!DK)Sy*0?_c|6&lMDzSex|>;_?tg+ToK-`7z%ts+G4Cq=d-*7IZArwU z-7N0)lV6t7JI4`U*~xLBlb7DfJh7S8<=mG+7fEVj)y2HVpw{8e$d^Srw|f0|7W9g} zHxcO51tO+bFvjD5+-iWSwTkHc^_uBM{OIj~F{k*Zh##dU9&On!D1*%8^CGW}u(@$< zp?7f0iE5UPG?l-1m-E!TeESDh5wl|7qkT7X&gM3IrT8PMML2KxsL3&OU*o=!pGzez z$KT>^ERfF7jMgzpcWNB5-l!?Xbf*rIe)1RMdykIkYo?2Mn@n<>m9m~}s)#dgak}*M zDR4G`KU!_JqQ;xAJx0|`Y15xjf~L~^Em`>@!N=XUkR)erk0Sy)`Gt^Ym%{e09E z8GuOkDGuT(5qs6ypJ;ACiV-*Fe(O%Zx4C6@Wu%vDiyy!HtJfwJ&VPrdlqpDJo)BBU z*_#{ijbM@hAxNX>sIS#LX)nzvSFxIAA2tPJVqu;?$QxxyZRl9~aEX%w9$ewr0{zEb zj3uVdE4pG4aU5eIHx9Vd*|!kpne%nzij=(KX$Z=ROFU1`9h5iedZ`P-nTZu6vVDoezp=QP4m@?R)x&h~O?OFf7~_S5C& zW<7+%Q8iLJ_~WA#u9i!EW*rHx&eW*ln#bKJe(w76844gx{5$D+L@vgbYtkd~^#^Kw zY6|#}@2pr%H}bO)%jXYHIv_2!3AIjcB4tr1F2<~-sPkC!y-pnBQL!`Jn|pTY6h_;O zjP#6lEmf!QF2BhQvM1n1`_rzMpe7s-GjJt9GT1jLYX0dv()G@C_BWnk<-j?)n}v-o%CGawFI(%l1~e|gbvQ6>2rP_B&+{=E_>q;Xpg4H# z*OyD}S$N;~(uoQ1p`XyR5#mK$Eu91mGX1wfj(_@m4YItVeHj4*`P6V= zl-?N}vdC!-1m0A~jpD6T^eG)JSuj^aIXfaosn)GR?MD&01?IP+xQDlucTvt4B!SE3 z?lyMdmVNWf!Hz{Ad71Xdr)LbRm(BwD@=MX1rx=1&=fO$9aeZIK)e42f3SSo^x7;GG z47&@KQ6z5WsOmV!_kCK7D#Q^QIhZsLuG=N)XOMbU-leT-PkjQ{r!|4NCG7lZM&0+O z>SmBC1W(b%g?@lI4}2LR3(cextTiSqbU}WV`W3R^RMf07N0>T!H6Y1h(8R?~Qy`LG zA+Z!hUjD6Lf?f6QzmCDm&%`F96%X4-$s$i_RPiFL6jo%m9P0$WPx|&I zZaVq4v)z1a+=ZAx$_J`&pQN0~%@lU&FGsP+43(uq@P=UCHK6CMi72H46Yn+}0N1|n z*QZRQCcQ++_ABbIE;kK;CdiFH-ff#%0_ur86Ob4oM8pOPH}3lm2RwUz#{80x%02T@ z-@N$M5jjO-rh{2o_^&UBM@smA(r@$i2KaZJMjNK5_wjjrOV7L7`}JE(=U^M01f47> zGJLv7c@ov9yeLL_-A9gYUD)c{-2a(`)C=(yRD?9tNrOE8md)S6g%>e~M75B3<>Jz! z)OcQ+cA|CEXpEbF56+^L9S8Xao#4O$D?Ay{EHhABb#WU=f8A~EnrJ8pEUC`!-1^LB zn8>B$ii=Ffa87~RHxWiWnn{4bC3b*UE|Yq^7`Y^48Q2@#s zKT5nvUOx*Jf_x0dn2}4F`Zm7OzkCO;6?S@ozr4krR7Im6U?rx-kH4bT)sgPNZbE&a zR1?xxM+v6bwWl>fra(T*u&qFJrO}EvBDwA(7d7~Au94fRB08mTQ$kTYZ^2>ndR~PT z9XSooa<-XVi_zMDdvLA1oP}&}vaj{#-m&1X>*1k@$c*XY11`R;hFNgCAC0s&V-s{} z4Et=_@(Ovq#C+bV^*=ig9?FrXViJFFr_;l)g~h}EG4f)n2RUB2I&!m2hsrC@fTvMk zx#L~P(cz_7Bdnnr6_S`S+8Hw7{a~%rlfgEs;}>D9-e2kfirmcwucCc%gz~EEpgVB$ zKe@qEw#5wwb~m_IatzxtZl$#u)Uu$TI@SvYps>Q_o%{^1YdnNb1FKfR-#?dqkPdxF%ph1_KV z7b{#`5#TFu$D8rUxvYE%dnS;yOB1=#1nuQHLPxiY=j~O&U3e%-!+3$7JH?4R6Xz}hgp_ph=?R)wip(ohBVB$@BCIripvQ6#9RM5kQ;4g`;ZmmQS3!~jK1yJT6eY>@x>ebLcTkF=Y6!w_3$y{P_9TzPqUvsV|3XQe9uQE_OM>Ry%VVL zzVUvBf`Rpma`)q>T{gPpYjN`OEAGyJ+5=+473zvr+501p_JO+lu*%DJ%oBTj9QCgf zT-%)~6)QRg`oZ3L>K6A~BKp`B?A$=OI$HY(nvPs!=vPQC)$Kc@rs}}GJnME9WTDLg zkHTjKR5_zfykct76D@wSKqrb#(Qud9K6)!<%WJgFSXjX6bRo%Qj5bF))sdu4*g?Q= z>GSr@hEcWyoOwOTgi?=(zX`XyOnAemWQMh~^$Q|Q$-Emg2(#62*f1B?EMDD1yCy7-hf1?!EYYY=OHG8^Z6rPJQ*)cEm)v$1NiQPDl+fK? zaFuUQuH_rL>YqF6IoU9{G8HuEE-y{z$ddiu;Yjsg_s14YWuF=sj27p6C4~|172LR} z?~Tw_0O+p}V<|N@hLoQ%h#u+&ujkn?V(qpZWPCfur~Q^yH2NWsWivW{y=NQ9d*40e zO4=e!QE&mH?yDg=3+yGLKceSCS~U_00TuK2XmAs%HyLnT5Y2uCrM7gLFxaw`OBP8r z6>$ao){alkcCXIL6`9ssmvV0^HZuN2U}+vmYO?d6R*JL5c=Cu5VdA~Qp`*iHc#85YM}nq#5Q=W{)SaT{I2tMDDk zF(7B`utAwyK8{^7B4jN8g{+|NI7Fi9yFjfI9W>HDdfu)Fq=18nIg|92f~n|6PlM4` zXon^5+d98KaK~p0?n>b1CE;>G_s!4VC(2*94LPo>`dte2|3}s zM_bXHpu^d|oo#z&p-*M#*|zITi;A8{^ZRbnpK0-bpp%yyiOg@0Em8fnJOHk|Mm@|F z23wzs=|~W)7=fHPjo}ZVyx!yVW?bH2O-;>TF&LMlcwgu2P_H)*<$PDKRox!i){ak? zJbmv0vAoE}(at0sHu(kR8Iv7voV>whMrtupna#iyK#o;CWdyQmqF@4bqJQARaU8ze zZxYr2c}&|3VP@wN1u|xeontL`#-kgWH2HdI>6kzTfcZ&%PqG}-1~rl<`tHOrR6Gs* zGRjr>%(Wb*5Zl={y;swr+17VgNaQE2RExFm;~r||(>*tB48gf5=nrCcwuvXZ43^8S zvgsQVD=XQUY|w)q=aP8AqdwiZd5nKr^AMF*uQjUtENijmv zY6n(*uU8Qe+|>}>9&$EV2~NNL-FThQaXLYaB7=GMY|CDS{RKr%4lW&YcP7{2t-tpo zIBC+N$Z|S9Q^MKWav%|emAY|UQ*mIWpvoBFIz34vX~ z4vF`K?s|ZN(Z$LR!r$mO4WX1-Xo^MPRUg~ghQ^I(`BdHA2A1X1%9~w8FMk@l_!OMv zvLTH)IWzTq(kz~%ZN?tSb$}4xSYvA8{d~!@xC2yA5B~Deho2!T(8b(8-(l32IviN)f zW+cC1F4AwxZGAF6LGjfY%VWA;nooV@ZGZOSg~gyzCwG z;k@GNdKUTIL#_Z{NU&r7r6%v3O1|l+H3MwD`!L@eE0%tjdVju6&}1>{D~eCHp0Nqb zK&VGR*E9MktoQ`p3@e_2^1BJ?45`FUms?4ViQ5O7&hEUn-2o9v+5ZGSUPs(Hs`zzD zCq1?f-AvC@Vw?OTDZwJ)@d950;j@BhT_CKtzy)GRrU7ze5T4PP@dDDDsP}@u^(R_a zAkr4(e!)j9luAA}|6TGQEP%$OCrh#DerbZ9TY3D(u`?orE1nRgKU*k2$O;|2ZKLin zeUf5n&z95(>kvuZzlP-U;>C+k{SBA<0t}y7Du+ZfT6(3)r~6U7ya8eON5hr1KaJuB zI}Gh~s(Wv7roKO?#e(_FOJ|83m+1=ePLv=M+9qzGSVy!3!xs-}$fSoV=7gH|QSXN@ zF>fJVt6!pgS78HTu!CKJ+FmC^+m?RGE2*lEm#(PE=C$bi6F&w+aI6TQgYV`z>WQMk z)rI+wK3~igNjFNUYK*&dqIY{0e&aZC`>tb10Jx8&1ZynH3CRNSBCqr1)_seqTtjB# z4}C%3{5gw;W81U1fH#&g?OR1%QjT1rDuTJD z22T_R%F?(5y4%rvyp4@uvtUoy*J|g)betl%Z;?FeYyRq-$6ihrQLO)cot>||!jYXjT*%fnZY*GDTC@*{tx?n~iZC|W^g#s#_ZZA2CXMxe%c@{`v;q2~p z<7VA>4`umc;^Rt>-c=y?*DlvXoYV2)Dhr!Z2-ru)oWzUR^&s<)o3ZEC1%2g$9u{yk z>moB~`gzf){20!L0m|&1b;Oi0ZI8?7(a-N=^eyA@=dGLY1^65PqAv5bz*|!%bRD!Oay{+l^ z(M&S8d8sYRJ(s=rBEwt*hpaq%gtP8$KwJ{?e+Ea<>MMA%uKFU>YxAuV2BtyaDEbDz zyzvLc3AQa_3RI9BcnqU0Nu0=5EY+-?8vKC2`F3%5y5~bHr%D*uP4Z&Ycl4ZF6`ZHS ztKuM6*QN`BHUqlS4$y;+Dt~@Sih6{)(5}ybqbRzPv2@luu*2jVdZ-Bv5Njgw7aT>l z3f-~P%W0NTn0}keZMu}x`SKAt#3@%$=42FCs`C`eQy~@g=P~BE;>+17 z$KA731}i;4Of;8u2z`I%BnD#mX?^+KZ^c-0Po~BFB||pY%t19SpePgj2s`sD~(j?rY?`8IFSLno_XwsJlL)( z2GU)?{$dD8f2YMxv3cD~kql+@kqfdMnX{9p80pr)T3nJIV3p-z*DpdM81~?~jQld! ze%39v=6=7?LnGR*110qNYUSSJm~p+F5(eX!bK1xrJED*46;bAuRluwp!{olhraaK+UPT)5X86%Bn)=ml=v zFQ-X?POkdBmUi~t)29$|y%rkbD?*^N1(pv=T`mv%B^T6Vnd8K)E6}Di5G>b9K?Q8S zKtw1ga7y{ctMN}RJ+3s%69l~gReuHTT04mmQkn4n&@N3UWQ1uYf)D-W#* zP%`agki>b722#niZ!n!$io|}#Z|`T3jSw&kt^t?6q`1GUh@JAj)hWR18A6Zv+rZ4? z&elyUW@6Ht)RUWJ2DYdOMphw8EaGHf3EB}_io#QhpzAvI#M7_!RAFuB)`-I_=;UPqDF z9YPayQVi9k6Qq78g^Jzj<4xnGdR8l21=tnm1-jgBs39`mVh=8o6-@RicxI{KkzeKR z`(+=GLG<~rmsO%Jt2mdt?Oua&elT^;k2Wiq?5DiuCBb>SI#BC~TUPI81vc_*HQk6L z&~0`&1I*ko_PiO~cY*lYdG|p2RYl(u5xNDuobrw8&~kwzl0y2BCbp_UFBnvcMHj9j z=Pum%it;7EK}$5FhluzwBz#R)-J0wq&^&8rTb~-?>W8wh4B&wCR3H1p@{Tm|H|q|4 zA-eE?aa7)s@T+4jSeX>{mi+Wv{T8!mV(fdry!QMGcRq*DGP|F$!SSBan_)qQ5ml~M zR$D;=>~;B}71VY}rEsR`fy;k7VY_!_^q^jdJ!iC-yk;E8%_#=Md^0TKJzjOU-?x8y zV6`nq$YUVl8z_)>#IglBJ(Ip4&4X&(wlq~x16lZw71-7FW*xUOA-4|p@`JC&oHy9Z+Q&3sO zb3PMaCZX&~u?{dW;8cHNDT3D7ZVo>>j=HkOmwtpEyxM`eVv8TR)HFPJYdxP*angX; zzW12*Yt!A+$Eav{xhQC=m$8VaRes+m>xFtS3zX?g!j^vL`nSrBoK9WE_ae{fqj9^& zQ#DkeV3D)q>upOfuHHL#=q;Xo;lN$fOD3O1#1GCscR{FO)~_H>WTt&|iDD24bx)Be$bXd^4%v~B^dU6&69-LB;zuLS5i-(G5 zYzG>=!9C;)y8OXYAhwd5PouxPxlSAlU$`K4nS4r&Z~dDtH6*cV`q*@hgEW}RC~()W z1*q#dJx~U#CVqC-|7W)J=^Ksqm3qPLWD_1C3cCbj;|M?A7)~Ax%{2 zTM!550vh~Lc$zkLw!#r=o-wQz37slYlEAOutAhwlObev|lKv!=MGv;Q+pqV!*_Q~cBK7(KYd=R$V0|D~Mpi%p4#QG#_}Kq%QAG42Zh zk4qVlS3esS32(-$XMlz)#<&mV%Y}ow>ENwIQPs1`Q7=mGtYO@&oC%y#Kd9FtjM%3H zFE5jLkt}?=38kq&_K&~l?IJ$j0v!jciwYo+>8UQ*SHW#b zo?`BxHsiG(R`Q98iY8}kmlh#w-PJE%I`UdsZ*=#WOM-#QhC(B}z}mLzyvycHx30up zAcm!UkI_=XYxz!Y4RU~~Z>V0I%nu?BH8#IZST!{TZ8Yu{(FOhEm(ZEE>m_W)x(91- z7P(xuv~mPPN?-JmzM8_~u?#X|8}rjJBV$_RF&g*t({gsQoDPJ#kyw(U=i^-@!z?UJ z!Spg17db&DDdbd`fhkoXHj73eBI)JG)lesJFSU5%Qc8x>e?oUzSR`2RHt2XSc#_Je zKw929*5eZK;2V(eB7g({%ex zM%enacP$OQT9(Z0Yyy~&N&zDyFS7ENa#dp1rbWko+ysbOD#(F*ua_VecfBFvlRpYy za}t)23hzf<+4bXnij|o%(B?(;&#XLYF)k=^f?m)`UEB|#VizVR=y_)+Il>o}F8JLn zeOS<1)nBF6plEv#&8A*j=ONCI)0nv&D&3V}3`zu9RQcQQ(CN z*8*EW>M4-i`BgmZNYDG!x5SUmV1twx$skS*Domrql?UUDm z?>@jO`^+*jKSAy^eRP0Xx0{d{ast_Bfk3 z@+ad_e%eLMSg@r*?R1RQI9kixa}zA17%b!C@-lX>oF2%XD2i*j`VM16Ii`_2u7=n# z&%OVAjg)_K%lbDSZpT1(eZ{nTp}X--eN&1$4OFK`k7>#DNDHN8Mb|~`zq|xbeyY!W zJc0gjmLI)g-uEr3sLkqNG|&oPC`&%WJ+`qBR%-{dZ|eQMz&#w`@YBX2EGwN|5Ru$4 zNdF0yycxJ%Hg_}x%stII3)BP2+{<?1on;DtRzGCKEAXPFyvfskGTramYbZo4sMaA?N6x4~x)nf4+ zP^1Nmdc=^-y3%>WT=mCV=p)d6|Y3@Ki@{ zyr7fYw%UM?m$xuV17a41^?-AqAzb5*f|~X%)|db`q$|1nw`-Rl!@h4o@7`!40af;D znk+#}n}{ZyvZ7l2Y~1zh&2Q9URvr&YHS}Gz_~7{qb*F3wh9&z~o4Opva+(`>Ek+p` zQE^5nc4v4MI%fN1Gt$MVSi&)uqI&VQ(j72Smtz}nGwNA}kWKs7S!mD2-+62%qwLWF z*C=`#b_-ojk*0PHpzoW}C#%NEnxL}6zJ4`paoBASZ<7Bn%1{_gC++@48G0E{^s+rC zOII#dfQQE~&xoe%561WZm8(*TmXRf>mRY@?XyW0;(bGDYE)Gt=&zu2%0wB74mma{> zb5aOFvSX$gfU(-y?HR6E?Es`}k~ewd`#MgqC9ern20!JbI-e&uH#LnQT$g0=%F=<= zD+{o-dJ73b?TgB5tBoIjo879Iq$#vT#O_h^xQRx_uU|bqR{dqZmKWB)ZbJE@;X@Cg z8(SeIFJm6^Znp;pecuS?)|kS|kL&i5cqZ1 zzzkQcunN$Kyk>C;0z`nRz}!+FCZ(cy zxQuB0QYNb0FNwU`_6s*LL!IBYfM~OI&jDVn@?pH81<7=!F(9^Fz@M)Dm?U^OQwiwc^@i??xEn@Fn904Bo z4QLoNmRi|>DTyC-+Qg;pQ_|^O=L%_`tHb=b??ni>#o<^j7XhMp^OPSgC&p4S-XTZb z%_-Xwm#I=szdr>M@gwl68T-q|188KQ+y0&1$>Ji9!>7QZq^fl8yeI8X+a3W9Rem{_ zG1uou&uXIf4kj>L^zYrAh0mRVe06A%ZQ1+{fN?b?zN&t5GAox2&_ad#6MjGk#5-LS zbdO*7w@9;qvvLZ0?^&U&nn!!~Dx7$o*5a#k$#8HG*U`2Am1b$Q!iq{p1pM!*44a6cigJjuNbKZov;|LKkF)J6x2L6ZYrc9Xn}hVOkV@ z1UmUwp#RF&cE@MWp3mIcS=Na6w<2leJ8A@2k~K1yv5$e$#3PnA0sIwgCjdXztvjT$ z2p#sLVf&2Su>Y1qxH_)G;}gle2O`Tc!YaNej=9JK{eKm>@s*RhNx z(IiRej~|kOvbI4%QgzVgg(`-u!~%ceD0c5rq+BNfoe57rSABn^_L`vM*);FvO8m{t zC+U{wMJ(IA-V7daQnK+ycC^phbddwdp)0%k|WVOmwHOQ1o;vVNAeY{vmVPnc1Ouf++t-b z@wAZF0qGTsiRQl73SvHn1ip}S6VAP7LRp@Yxd_!o4WdRb%7_geCjp$Y7nHVf2*1m> zUIJNNc0J_-x-c%$q%{zh86{eBNLeTd7HMG$3x5p?A#V5#ZFaRZ#W(RRtd&;e4li0OL_`(=5T1B(SNh4|@7lZvyC+&Mdz26GERtkLY z$AJ8yKQB#mTp-kDtC-0VlxMY$+~WYJY_g2cY0S_lGHi{Mq$p(Cl?Ln*MmsHN%JT|kk9;W)}f!k`$L@TMH{^Hwj-@lZzG!bWAI)lK&xujv42Y|eN z2mC1E9euYq{Af7W=y|1-8L8UQ|Fadl;LWoxt*Qn6;2?o5p7>>UtJ^fHW#dj+uB&=a zdx$(a3hQcTZ1ra$pV8mgK};mu1Q1J$sv@%B-sJa~BsFC4sJEjYLA|VvVkrRjirhrV zxgwj2cd8lVZS%V}u})i|+y2n!cy5~p1aA8waS_6<48e$Le)TL?tiBQ)q_K`Gc38r<%{Rf zyI!?*`(99x;Usu09;b5qd;ZrbX_+RO*&5cR?F+hQYxBDAC^m-{^D(%7jZT@=`}Ekc zru=E30}Sfa39`t;v;n-foLe~4u9-E#WK)5OW zm~L9VvxrnZhO>^DfNYGT(j!el@9!+=cZ(wUZ?u_ang&oe2$aZ#TzpfRGN%dZ$AO?Y zUR*h0LpM`g{9$!*w~MKWO&?zfd!B^chK?;6ex&O;A(F%Rj}Tv#=kJ|plgGcLz;h`n ztaoIJZs>|e5sLqgAt_eCdfM7NV{go4Di zEw%Snjg9@@d3VsEZXOGlHBAAe4id7^=?IfKb1%wvz=%vSxvFvR-XMj!INf?JpP21V zy|qmvu5zNEedj`f+jke<4UvW!?`{n^<8#T)t!`bGPS+i3`Z1unmsG+XWrnkx1gya3 zcN3vy?vmP^ODSdhXRGXRKrb#fzU)xsa?7@T*;apig6lm(UIsg_l6_Hs0s{!0#%$-} zpig+eC6==drD-I7-``Eb$Z>-Mww9{Hr*reISa5I9%W-n7FN#Eni?@m^JWc9D?c6H7 z`_EXbb@5u6XP}j(s8u1NQo1nDXc2CaCb?cN3@cTS%bMXRES|9FkxdIw!;GF>6V^Bw ziop6P!LO%=D(eD4dH84Zkmk?XE1l&7C*OPOZ%7$<6-bF4tv*z|^8o77kgPb;9E|?4 z)*-E`w#=(auUBz_l)!w{Sm|~3Pw#aiGZ#!9D;LV#b{AE}P0wr(+>~||wAbb3p4ENY z2{caexgt9s-vI1zza>@689)5>>#Og{-xHgg4XoPH725ETFrSCSgBPA|L#!o3^s~qx zWRUo}DcWAJ$92kiOr299zVeBHFC_`xLGm6)pI~jgO&6-$^0xDI$5bi_?`%mbeO^7F zHSzo2mj5^CX&;9vgX?zGVL%#cOy%rUZLn2^o&q$uvQ@v+be&lJr+%-O?JTJ0d#ipz zsPU4x%G_67yX)p!0%veWtN+FJ(b7D2yXYw3Wz)PC%^Hdagk9w``uqFy4qrp|d_X|v zU9+Tp6TlFkQ9zrdLQiLV2X~FKoU1mNY8sUQ{90t7#*^g)ZDvJaGtl)34gAe8+|1rf zCl0c-$LT;KBpIbYqf&G#kjA3~rv#dTeiZF ziC7;a^XX#%q%Ti6lQnHVdd4{(5^cH09(!)!0{%e)H(8RSu-(vHYi&=?z@&$~)DjlF z!U5l$^H7dL_c8lJ1ojGB&k+TVu>tS{8S>gf=CzxbL%G=zKR76;<_F!+N?1$Ns2S-( zov^`03tzg50mV(AVsjBi0EnELK(as=>-cCQ8886Jt$($yeFipN?$yd$EKAiF$NAdZ zA)-5VKe!)?!%NhC-sP1?{8n+!H*-)n+4ZmVVUOD)i2yAdnmVdI;s4R&!n(-~nkc!( zM?lgI$d^FB@@i+?O4T}Vgc65xDm(IlAR;}@#p&O~?ScG(4ANJOE0{4+&4rG+#v~U4 zp1J2q=P3US3Ut?Adw$k-fK|?6-Q4xCCH9n;7eksPNl?MoD|A~y3h-M`8usGSY9<#gd zPu#!@d)vU=Ysv?&2GXI92~yT)h+qkg(zb1bei@vh6h5wqLzk#oN#uJG1+Y!sD@x29 zMgc?d!|3nfUc1*S?b%C|)Qwzor%K_s0sO7Ezw^W*+Q5DlPD7$@CrGI%N- zv1oBlzFrX7`nSetiO0dpClwfo@8J4*DK+2qZ!SQ$7S{*H*q!7kxKeQ?^5Znb^XKDX+e>(sL1;JkF#!tJR`}JEJ?mnYormH%r!@ zwXJxg0GXdtepBuu>luS8uQPlPPxZBxM z+)zqDUrHcsdAQBr-u2D~MQDUX@gR7tden|5bbX|X#2cT+8Xr05d#q^m1^ruZ;w!s- zU$!1)BWp4hroYyN7#2|g=JhR!Wb>2f1vps(=`XayU<$fPOWcJM(3K-hiP+}dvCTW@ zLE3WUt7bO~vp6KHA@V3}C4l&^0Pds6svq%yo&&hcnuW5Mi(ub4{SQXD|ebUw)ls@uspy`2y>p&MHEoHle(_>AX$#&Bsm*hCj zQeyj(M|yLTQ_B#qn!X*vvy8+zJ6la(XUdDQKQ8%{fCLH2oPl=CqPYVYB416$U)}$1 zG*z@hH(n#l3^b*BFaqu$;?1NUp3il-Bta=#0ASZM1;zSy2)-)5klv7jLur)C9kID_ zxbbtd?3YVwjOt1E?~3svL!FZxmLw2*)Ln9{_)X3E`07+XGWQt0Jnk={Jxwz>wi&%o zWj6pVQsyi45N=Mgha*SPPxcyI11RvE1Lc7%0mvjJ0r{eYD5e5G(P9Oit%xY}Q-4Og zXB~!)T@sW+`$PB9{!pvxErC7lEyV1&nVz$N3mJ7Yw2hemqPjF+tT1nR2)iK9)g04E zuHF8#w?j-s-1|z8N#AC}wa=0VZU(YR7dIp6QMOE<&%piz@g77fIi(%bc1H~XK;XteFdz$`yyY--BS1AfvJ@$d)3TN~xbNMp_!4U6GagQ!QlY&w; z^py02Z5>T1@a>~NUdD@jSR4xqPXwLx545TJtJ&Z1g;YCf@$&>XmRfxOy*^O40d&3| z!?o&8Z0?!^Lzy65c)mG8sOaGMSBgvO-GBN&Q%L<#U`BR$&%t+2rYA^M52AN0K}rv4 ziE}}76SJFd5yk#4+@RZ2xCJx)xcrHbxM~gYD!du_Kn*E70CvISB-7u-n-vL6pzaO+ zlXa+o86B)mj8U3E%Y4ll3dp9xK+6aKN9c>};%aABb&a~zX_F+riAvMkcbiKRo`31v zvBQLU&AYjC>#p*P&y7j4J$65*cz&)o2`9zc$BWF;_URP0-wfS%V7hT(_8Ky{Efzc= z1{55L%AlaZetHaH?h7GD{$}ZYoh%Y~j%Rx*L0>$b=@qXdC79PKC-P_(wB?tk#j`#4 zDjEW;UVQF!pksMiufeE6<9<&rJ@Oofaxl+hJdVw>fKqyv2Ls>K61Ry$lu4$e|0GR! zZDr#NKU84?2nw(3iOxu;_nQrCFl)j9M|c1Glaz#H1d{%4_| ziNmXwk_Pa8%Ek`FGRBvDM`Z&Ok;=(eR*1^BBBUR`li7R+2IpI@pT8{uvH584;J)~P zO!AHb8;PHbwt$fwz!%q4ybmxfJ;E35`ZNI<{&nwXZ1Tq4e|CM2ek9g76e}+P3i9KK z-^&H(Esm38XeSXoIUw@zGp6j_>9cDqbzFY1caae7dPZ1&gFSCdx4{3jV+O>GiT_JP zEW`5ztkeM$PpiG^g-L|J$dtya%K0q&R<=(^U!-Js<-zH;UZoXdbPYEypyeDtQic5Y8H5@^Bx?V$}w>1cL*!o0KhSi|NZ-xf%diV5+P)Wj3 zdjA$xPnA$R{;U_Q+2C|U(Si@@%1ausTwNx#$iDPodA zK^%0HzAvYT@5V4mA}MTWY{vXH)U-4RdPW)`slU#Ff)CKX%=IgdlKuk`L(;acuq$1a z^B0JC_1br*B4?+UCJ&}xuO?35cMM2eU%`eXK0r~ZrFA~O2k+@*B{CS%n~LyH z6c+74TJ3f^2lHm5!Bt3yPS1;}mG}L!Sd!=YmN3I*U)1xtrDs!wjf2wjoKn1rB2c-t zMW}A+$O5K+98u0{Ce{E<21=&jHYYl+-wAOshSVM2*~Kw_h~_r2hL_iFxVKLV zHD+kzKMf?dpkSd2`XF7ke_7CNHz5?OEYVjc)*95innr)rqi{ zj~<9SZUyN)-J*Wk9lY!LPCb;!2D8sZH)v6q8p&Z~gg z)q_bZEx{RNUIDT67^!hJgR&eG^r{v9)MrfK{ zy4dWvek;V~K3t_@+;>%*9$#`f=QxlQlwLl3dBymFZ~cN#(1M$2OF7TA&453mlI6!W zFyiBJVeTc9aWyRNl30dvvy*KyFH<3`hbmaGD*Ofzv z6X+th0w(bm{Z?#daxqGIP=Pa((e@>f&*@FY#De^!H8?ao_|ux2muF^=Nb>u?HPIqA-q)8nk$4HP3#Z~9yw{KJn6xfb=`_78d-`v^WHCamJ*JmnzTBka`>q^iEauX#VS92Y{$t5#IBRQg7?y+gz z`Ni<0#bpjBcujd@3|n>tAWY{z{yXr!R8uxdcjargFCTSbs5N;!rdvF9WkqotJ8>~7&&SD5CA@6T4S*X;!z2KjOORI!V%PI=`V zY7G2$hokc=iUs|awSD>p6)U!@R;aFS(lbYo%v&K&YmT6tMZ*E|pGN3(Z{mx|$wSq< zUQYXf(^1#jlP1sg>y5#hB*$NJpe5j+T$blP+4_cCId;=3pVlmuqh|GhhH?H`Nq|Xp zN>5_Nk;kA_;SbcaD1)rnpR76WSgbDH#t%k!{PE>EIjAmd*jE3P6{0-@72^&wbMC;p z#fVJ_dJ)Ud9a8lSw4RUL=@aYf1C*YJ6BPv&pAS~mGZMtycS2?N#SseiIE&up9Oi4- zFpp^;VUpKicZPx0-g5fcpVhVmQ`&z5F59xqGAx?Wdk;P+xR?_y7$;pRcIGGBiRbs0 zJb$lr?+w3-iqA%Qk-LY?<<*(h`eF;+qM*KU;LWsxPXPuK@01)+*&^@p1NaqC`XB#R z06O{asC+b=W-w!ZK(J`+w$s_`K*@Gykbn16o{unph!kRO#U!tQ-JFbZNLrvCGe%Fm zRX;zn&%1hGfG-VT+`khHuftW7no$svSXw+kYx2Z}K?K`^k1QC+DUJzpiesd(=>-g7 z?-*lSk$RFlizk2_sSa~3miiJX>j@~QZ2S+WY*JmSmYe-y`7Kap@wW14xLLdq=nUjg zzzUhwIiHRjjMULH`2+efMerSX^M2X$18~kii1z~UGO3s;V0VV($_wFfPoWIM!GCc5B{gWdsacoB@SgF5s|7WEpScbKnm6`@U@5K9zlfP)(c{59u z5$4SkFP-Dz&pMxg(CMcLNNzj<+-_8KqYF&;-ydXJKF<(TV9f`}`xKBoN0LehGVWb3 zbTSg9+LIynvKrU0qW{y4-9U!gXh%Gk0bE!BcfH-Qb!+9deDl_Rd`s@+_csN!&LU2k|%`T_8s z-l&n;Tr4&(oqd38Ggd9Dxj6431AF#V{h@HJy=#*O`W8cMZSkphFD7tWY0eh}`rCOT zAZ|Z2pnIiB_LksBlNuM72mwIo^0@Q6#9wS)$k6<< zI!XM#Y=V>9{T4L#_!)*vE6L3b=BnM{Oj|nX&Ns9SAwh1C9!_A&ZBn8k8OLK9&$)3~@T5=h5JBp@vzI-)!x-eVsm2ktXTIK|7;T?*d|)6sr9~(VuLqM z>_A*~#a;IM<#pFNy*l+Z7`;))@)Ngau|Q+qjTz5MbY<>Peium(xt{j8)0T>UMUB5e zmgENdNCYf}2Js6Lu$d8u=sZc`*lCt_j^2ZIjq!R(18q)68@OMDO*{Onkl%EOmB5pHy)%7ZLKWqIFaMJekapJaV z2i1lM3lvq&k`bkGNUjwyfQem5M9D=af$O38_cYVQGRHFOb{Sy+KQai^*rT~kRII^RPW^5Ob z($}QZ`#!3xmxW{Szlp0RMb?&@imdvk{>@81BPkC#E(I={dTXMHK^-xcMfgOSSeN#v zOrIS>x-c}SP6QXFK~r0ZXk#(5{3pTe$&acK0!ZvAJWpho9bj|reGha_VPZxoAOqXQ z=R3pj8Kd$D9BBbaULlcVdnKC-QL zVVFpL`xan7a$vZKTw+~GmbPy&Rz$A_>6`! zTB+K1p4gjFeXFFp=X{Xjj`HobXa`9sc03iu&YDy-aRAP#YUi6tQN&+dRn=B>KJy|R(DN%CIbPwQ-ZsF8Ug8ILpX(VYw_{C%%c$2iYgBR3yUy{{nyF$m>t>W+)q| z2h{%$v*5xf{wKlm2!iCBRjgac#xL3gV;kTS4I>s$Gjb3R-B-TQXymFom7a&8vFr<< zKCaz~M!UnKoCHm30%tHevk210Jce?mGSHCqMY}{K4^Xw+9iQw&Ja?VL8lpjuU!zY! zX}f+|vMh00&p|u% z)z*0jWMC=<-5zjuN7FA_4Yq56@Wx_gIe>MbS{1AVv8cN_M@4h%+l}CqfKqUa@*j@> zAa%oYdnQOji)8}j4Esj%e4)jG1Y6V>K#j2GMDUqgjY;#y<^KTw=HjZ3M5bLYke;7d zw2NP^rdWFjbk`+)l|KM4r(%qYdL3BWfK1HJn4OOyw}!RR_@5xgs&JD&4Ol_>@9y9^ zFZZp|0Ib=IjK|<15H&bG0n$`}e^$@v?WShdBX5cqsFEEskyar>E*RjdulRmO4-9@i zRkNN1s;gx}s)vM0mw?V4*zrY&pHl4?Uc+@vk-1t?zy8+auBhdp)ljdJRwt|F57gvFs8~oagpp71&Voccy zHF&ZQysN^bh$4n9kWm%9w}x7OWGTqepN|e+AFJ3pMin~e+dz{i(`Rq=wgKi_+NkZ| zxQYoVr4KISRK3ChLFQZa;1yLL{aPTfuTWUa73MFgv-PiR8UL!dBM$_gI}I3+rnY@v z0ubgE9$3e0Lw5hl!qmsx%3&b)HIJbvIxdaey2&1C^qUmE#t9o!T9@iDM%JVc6VTZ* z7*HX`L2z0~Od2>_3GZ#B)+f<}7_@Dg7Jn{_zp`kZXa8e1cF^g+&Bp9oj~1Bt0EeBU zZtY&Ft-!;MRysub*fnM-rgb=>KbvL4Fz>T}n}5HGNj|+eow|eA>cy7@245-$L@z)S z?E_;0nBUdgXMTzLZ$1o(`cIj9TR64F_yVfBU;ZJeS=1R>C06+p!ZK3WnEkM3-@GX{ z%if0|3c1t5q4t#t^CH~W=lDZ||IC@fUCUXOqsZ2@#5Xf~c&d#kQhx$*=`f)%qWO9; zH3OKp8@qZF7ZpD5Sh-2!2lgn#sM#JVa%jL*HN!Xbf(NX9M;S01S-+|b#wgiy5H&N=k34VxT(a=1w4ayKs)|0 zT$%}P-hGXEb8hooh^eon_b_5fP5n*8rR0$|7z~g$)F*B`HHy0d zn~u@$J^TbT?R5~V^px)=TTa+h_ato9b9nr&JK^vAvC0^y3CwFM77=UHeaB26mRb2OUH#`C zIZayIwt+G3e*S!+DOWm&S7XWH)rc0M(+A9+=dJUguMp0ug>S2cinLmn*NDLS)5cgU_ zzf)w%D5i-Nax~7xe!assaD|iAVb)fU6}aeO9~lSqHgCb@&s@YT8cW8#>nR1~iMpVn zEVUI=Gil?+W-qNgdsdavAm(j&u|Tn6*mQ4y>fq(ey4EYMrOC(C_FL#Fu#*<~XN`>% z75wh2^Plw5Ba}@imZGnJ>i{ZYlmNmL4jC*hP=qjY<497*Ps9=>v4gPtHWt(f4O)p0 zC-p3qQ*WI+h6LY(zmlQ4a|BCd^I9r3T`3twhO+XG()x>|Ux9~ccv61$($I=lTg3pl z4b8UYRymcL)ILpd_FcO1kK@;@x6nxrDFy1K`QB9Oe6H_Txn=>7Qh-IWgRXdw{f`Gj z%0O8PObn!-mtV^Oro>4=ulU3|=7MI9Iny5r|q%uBx9JEmU2AOe5ubi4Ypp9v>780G{PBHxcZ!(z?>pp^PGWm% z%!qhTEnQ`obw>d^bp}adoZ2FYoSK^;6U3%zkt)bwatFn3Uk0K%(8?KRjcX7mu5Ps< z+V>{D`*H+Me~sw30w3mB8Q8lUKh2Wnot}{eG7Gr3-(zmNxma=WBlxty?8t?!wJtig zDD@KnFT~mW+xZx!6<;P)+ATi)Dbp*}I_&h<1S=EtzyaOJ6EUUyAF_Ced{J zR-o~!?>vXmmzfFE!0}JFSIZ2sN*7A+;(x9_BCFSEQ}D&6ppNM@08Fwz;P-S=mNT;b zP{oHn4OfUa@(f2LmO{JuA7<4j9-`xb4h-B`Zmgr|;@2Em(vJkG7Y;z0ILLEX2tEA} z8BhxOyLur2r?+-fBj5A`<6rj4c)&qfTYe19%rjlc4FQ?CMze)dVcHgBl4Ufihy2jB@0y0GDijD7^l&Wl?>Vm5Zqlm$PmmuSk1Q zs2Mb=XjbdIw|t5gCmDWy?*QGS=#I;V4xh$SokE*7o|{1Ut&Z~C!BPGC0?8y}FZ%9a z|Jg~OgZLImN)tG_2*|humqsVtW^m0>`HOKm=1DwBBi=Q-a2vDv2w z(}KC1^XV`EO~C(x>tpqzSv{#Uu5#P>3iHI|!`w4a9?M{1itviV8Dvs3ULF1s45^HM z0ewz!$SL?YQRwea=d!ZZfS=4k3+V2i777-;7~l=-X3A=?_6>s*Eb>eV)-j74Z5kw^x<};un zqbs~$sf!HK=Ga$N@4ym|C%%tB4iK>VI3yYT&je_1GZ^X2IyX4Ar$i%=R`7JSA7gSg zmyG8_BcG}=hEzncviq41D%Gxoqw{tDZ=G*MjFLmjmk9Md_N&|+=bbmS|F~e4-C{m4 z11>q>V5VW#L{aAJfe9)*se=M+pG~J|p^eC?2<-neIv5~et}pUP+hc3^0GS4qh}={v zO0*T|#XhwM&u6$jWH2@qRbBPD@ffQjN_a-g0l|=?pLIj^v*OQ^HEta`Rv^}`eNx2} zDAve;v^J2W^;)2AMHRcCwp-yz;cd*0e}%lbqE7UWCW_5^5?>5_`t3EL z!l#@SAuVHMVg}5sfR^_=y+edm(KRJ$pg+T12n(gn2T6^RBEhGg+hWRUe1_y?++k_X zAxBWX4jO-8;3Ek9r-l~gl_a`Z{@39H3pDJ{8Gc*z4nn_Ss*#t>h=imw zd7SMiv!?`6COL`dwe`b*^`>jXQCxQ_`aZGEb^^6AfuWy}gKYY;Z^HBT0inw<-xytewJzE)k&U{S9C@C8Z{?-{W#43wzFb>I| zRR{3^+RQ{SKJ(yFzL+^CUS>}!Cc;L?x`gns#$^8Dw-=81N1NKl^fQme7?xx+tVs3D zJWMMy*EI%NXF6xdWLLO4ivJ`x*W{*1r{6WqeDox6MEH*N$3TT^*TZg0Jk6K6qP66^ z`JUIUTW8I5%^boHz>^}H0^%W84bYj|LUt63H)-F|d`DC?pCJ)Ysg zx0ioubmVSD9fr#%{i66{k9Y^e?;V@nw*1hYMRG(cdpvZ7>k}_7K;Z9*OUu_;ThQTd zp3s31;KlcPaz+5^`|iQY>|BPvvix0PZ8M_ysWEI>KGLy3*!E@ud&@T<7v|xLx{2En zn(l4?TxROh+*!Sd(U#dma_ktkP)_5Au5Sj&;oDmI3G>xow@Ip&UOP7<-Sd0j?Ctq) zI)@_n?-33A_fUt+<5qh8+VJS&})wl+0Qj829g*K1MQ@hh%s z_xsZK2ENDSU93b+t1A7!|5z6oEpmaBE%=7Y_8Tnz(s6bP0QBKSK)k@YCW6<-XP0_2 z5ipGPyR1$!n6Y3WJ-ur1FBSM13zijxwoJHM!!;W_=#s>!*T@^HiVK{1;!IVyeJc+U zE~4C5FzsKSb#cLp3oUbVovSUI=;qE4o~QL)*529f+!3AnA};RKcziFHJwIi2R;{VXEo~IC;7#(@Y_XZ-1Hg_Rs95c+;D}NW#9jt2@`r^Y8r$fUH z;|;Xw>6)y{`KQhbQB$PTKW%nw6RM+hcLyaDX#*6wCtvlwLlGvPUaIkU^`?D0`Tb15 z@||=~D{i=n{~22|LmT^5HUUP({eFqx3^#zJQRmh#&=y1_Pn~~Jhe6kF{a=cwAf)#w z{CnH*Z@p8gKCFFWNT4q(9~n-B=#;@%DU5J1v{~Ho4aJ6YanLWWNE4r5H;Z_%%SM}? zc*BK$6M7pw^UY4XSeH2MF`{OEw>p{DK;q{&A?~N!c6$C?WC9IP;;Fqkdck`;VA&kZ z>cRv>!|xgUFV2t8+~r5pouTcSWlO$)q=syH2+t_MX;hU5fztXzCO+$eQiMfAc9*;l zA8IJ3SU|f&fHy|q#(eR0KOUV&Oq%@~Di4Y9Y@%P#XP}>r_9HCc^^!3o$75B7&9fc+ z%UFw-W}oSLdOQ5j`YxFe^|@#IzCX1CUnE;Wryo4$?tO>lwoL1^fn%4T18j-8l?}ak zGKf|pj<3g+ea2AN>moHfk?AB-u*7f7EaZts4B+?4b2Bd>HcLG&?!ytwqA<} zk#T0kZ5cA(lgkFIkEaxsS>waws^EsF@iW*i#n*20@R7Ij(tUa6A0=pj#cA-{oW{tViKZk{eb zEC@YKpVY(bMm){dKI`GRF(;cNJBM^IPJXBZF_Xv`JQ7Y!n*FmzXOv;^$WzAwnCsIp zBsMC03yJNCZGpgvY9d;|3w(G4!b`j*jN@)04vz@to~36;x>WeSM7Y{-m@=|K%DuU5 zk_8-+Yg?YQ5i12W_Fi%kaI=z=jaS{;NY*(7NTzr4{7NlEV-L4_Jym^G)oo|w7i0aB zr#U}rbws!T7Z*8B@x_(CAS}CHt#zvhCr-MxDb`Sgaw)wBEt?Sg1L^3ZmaGny1Z$}? zu~1uEz~zU9ljVzfc8??tq8C)_f#H|X-E$?Map=)--ggtRMyS(7!wO*}7EzVW;-7Rx zUaoFvUk=r()i(BNiu7r8Ngb6h(7*CAMcIuVRBp_lE_TyhxXpvq^zEb5UtqAuhX!*M z)$^7Ud^OKos9KfBrlz#d3ru}AF!0r!K8g8RnT5|a2taD8SGU9?eKA^UPlI-UC~Y&$ z8BY47nBe7KunpstlH;!~;Q*cWMZc-(BOBI~62kp`2efqwol0=kp(boC(UP?uBC=1H z9oTzvFPW4?mK7sM<}G8^>#?$5Rc)g4FJXu1LbrUUD5T(*tIuV3i*p6nUk|Q77(=wJ zGi>yDExyhucwZKN{>EdIyZ2Hv@$!3QFUVXU9sTR5@9Di!OVBNLUh)hJv;EY%8H=&gO>4xUsh!ZHO5{vn-URkj48$aqV%n|)S9w;}s7XV>@x?lxFdo0R{-38Lo_6Vh8?@XR390^K(*6GH ztl4MJ%W=qwfGT!*bJ>^%%@8?x2dPtvx@@Z%(;V~TgpS>Nt;2beQS z{C8LZHmqAJNYD+|T1QU6cjb2q+07YdiV%qWC+|>Viz(WDOw3c7siJRy5$w;lgVVO0 zn$l(B)OK5%d}~QmneX>G@cO4qY;#OhbBw{^cgYr)YYN5^^PiENnI%0n4lgOJuf-W~ zN7wGd_m__HG8xil&a#*FEN8DKy?5BsG&bs4al)_uRm|7a!fr#R?ek?Z490m<2gF9D zW%{ij#nFQCC7a5BeR17&^?5UOe_U+uIfV;S zIMxBe@GZ7Pn+?mY0r;?#g<-Lrko@Flkmi=rN46wi|1cs5gX?{eO08I$sW#iG6`c6^ zC@2a%W#k?zWo+}(J=;;^v4>-}evkcNM_0;Bjh|mgf$X#E5wiB~{u;)Z=JOVJ6ds?O zCLAX0fo+FrbjF~KCHR7)Uqi3{a6j1H6Ei``|IIr7yVUJj@kp01mKw+RhOu*c^~s-S z|MG9IWUqlLOeiG*+FK5(hDelKw&SUWs|fgm62!8Axn_oXW??i>`~}ND0RhO`%6wT< zstB~)OwGkW`2Lj-*(@Z~IvN^kN2$k#^$tJPb?mQQIA6vsHj4X*&~zuz3o$l~h{k8! zt{CJR5(kyCCcF%M7fwiB0!`J=p^8W4pLq l4w1{#W?bqV{I1lcljXNrj>3aa-c5 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