From eee9dd8c944331dd804752383692076ab4d2790e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 13:03:35 +0300 Subject: [PATCH 1/8] Example: core_3d_fps_controller Quake like camera animations and strafe jump movement --- examples/Makefile | 1 + examples/Makefile.Web | 4 + examples/core/core_3d_fps_controller.c | 360 +++++++++++++++++++++++++ examples/core/resources/huh_jump.wav | Bin 0 -> 19050 bytes 4 files changed, 365 insertions(+) create mode 100644 examples/core/core_3d_fps_controller.c create mode 100644 examples/core/resources/huh_jump.wav diff --git a/examples/Makefile b/examples/Makefile index 32a3a75ab..edd2eb399 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -500,6 +500,7 @@ CORE = \ core/core_3d_camera_free \ core/core_3d_camera_mode \ core/core_3d_camera_split_screen \ + core/core_3d_fps_controller \ core/core_3d_picking \ core/core_automation_events \ core/core_basic_screen_manager \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 35ae70a18..5ba550eb0 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -382,6 +382,7 @@ CORE = \ core/core_3d_camera_free \ core/core_3d_camera_mode \ core/core_3d_camera_split_screen \ + core/core_3d_fps_controller \ core/core_3d_picking \ core/core_automation_events \ core/core_basic_screen_manager \ @@ -587,6 +588,9 @@ core/core_3d_camera_mode: core/core_3d_camera_mode.c core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_3d_fps_controller: core/core_3d_fps_controller.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_3d_picking: core/core_3d_picking.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) diff --git a/examples/core/core_3d_fps_controller.c b/examples/core/core_3d_fps_controller.c new file mode 100644 index 000000000..56d8c4543 --- /dev/null +++ b/examples/core/core_3d_fps_controller.c @@ -0,0 +1,360 @@ +/******************************************************************************************* +* +* raylib [core] example - Input Gestures for Web +* +* Example complexity rating: [★★★☆] 3/4 +* +* Example originally created with raylib 5.5 +* +* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025-2025 Agnis Aldins (@nezvers) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" +#include "rcamera.h" + +//#define PLATFORM_WEB + +#if defined(PLATFORM_WEB) +#include +#endif + +#if defined(PLATFORM_DESKTOP) +#define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB +#define GLSL_VERSION 100 +#endif + + +/* Movement constants */ +#define GRAVITY 32.f +#define MAX_SPEED 20.f +#define CROUCH_SPEED 5.f +#define JUMP_FORCE 12.f +#define MAX_ACCEL 150.f +/* Grounded drag */ +#define FRICTION 0.86f +/* Increasing air drag, increases strafing speed */ +#define AIR_DRAG 0.98f +/* Responsiveness for turning movement direction to looked direction */ +#define CONTROL 15.f +#define CROUCH_HEIGHT 0.f +#define STAND_HEIGHT 1.f +#define BOTTOM_HEIGHT 0.5f + +#define NORMALIZE_INPUT 0 + +typedef struct { + Vector3 position; + Vector3 velocity; + Vector3 dir; + bool isGrounded; + Sound soundJump; +}Body; + +const int screenWidth = 1280; +const int screenHeight = 720; +Vector2 sensitivity = { 0.001f, 0.001f }; + +Body player; +Camera camera; +Vector2 lookRotation = { 0 }; +float headTimer; +float walkLerp; +float headLerp; +Vector2 lean; + +void UpdateDrawFrame(void); // Update and Draw one frame + +void DrawLevel(); + +void UpdateCameraAngle(Camera* camera, Vector2* rot, float headTimer, float walkLerp, Vector2 lean); + +void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed, bool crouchHold); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "Raylib Quake-like controller"); + InitAudioDevice(); + + player = (Body){ Vector3Zero(), Vector3Zero(), Vector3Zero(), false, LoadSound("resources/huh_jump.wav")}; + camera = (Camera){ 0 }; + camera.fovy = 60.f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera projection type + + lookRotation = Vector2Zero(); + headTimer = 0.f; + walkLerp = 0.f; + headLerp = STAND_HEIGHT; + lean = Vector2Zero(); + + camera.position = (Vector3){ + player.position.x, + player.position.y + (BOTTOM_HEIGHT + headLerp), + player.position.z, + }; + UpdateCameraAngle(&camera, &lookRotation, headTimer, walkLerp, lean); + + DisableCursor(); // Limit cursor to relative movement inside the window + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + UpdateDrawFrame(); + } +#endif + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadSound(player.soundJump); + CloseAudioDevice(); + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +void UpdateDrawFrame(void) +{ + // Update + //---------------------------------------------------------------------------------- + + Vector2 mouse_delta = GetMouseDelta(); + lookRotation.x -= mouse_delta.x * sensitivity.x; + lookRotation.y += mouse_delta.y * sensitivity.y; + + char sideway = (IsKeyDown(KEY_D) - IsKeyDown(KEY_A)); + char forward = (IsKeyDown(KEY_W) - IsKeyDown(KEY_S)); + bool crouching = IsKeyDown(KEY_LEFT_CONTROL); + UpdateBody(&player, lookRotation.x, sideway, forward, IsKeyPressed(KEY_SPACE), crouching); + + float delta = GetFrameTime(); + headLerp = Lerp(headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.f * delta); + camera.position = (Vector3){ + player.position.x, + player.position.y + (BOTTOM_HEIGHT + headLerp), + player.position.z, + }; + + if (player.isGrounded && (forward != 0 || sideway != 0)) { + headTimer += delta * 3.f; + walkLerp = Lerp(walkLerp, 1.f, 10.f * delta); + camera.fovy = Lerp(camera.fovy, 55.f, 5.f * delta); + } + else { + walkLerp = Lerp(walkLerp, 0.f, 10.f * delta); + camera.fovy = Lerp(camera.fovy, 60.f, 5.f * delta); + } + + lean.x = Lerp(lean.x, sideway * 0.02f, 10.f * delta); + lean.y = Lerp(lean.y, forward * 0.015f, 10.f * delta); + + UpdateCameraAngle(&camera, &lookRotation, headTimer, walkLerp, lean); + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawLevel(); + + EndMode3D(); + + // Draw info box + DrawRectangle(5, 5, 330, 100, Fade(SKYBLUE, 0.5f)); + DrawRectangleLines(5, 5, 330, 100, BLUE); + + DrawText("Camera controls:", 15, 15, 10, BLACK); + DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK); + DrawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK); + DrawText(TextFormat("- Velocity Len: (%06.3f)", Vector2Length((Vector2) { player.velocity.x, player.velocity.z })), 15, 60, 10, BLACK); + + + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed, bool crouchHold) +{ + Vector2 input = (Vector2){ (float)side, (float)-forward }; +#if defined(NORMALIZE_INPUT) + // Slow down diagonal movement + if (side != 0 & forward != 0) + { + input = Vector2Normalize(input); + } +#endif + + float delta = GetFrameTime(); + + if (!body->isGrounded) + { + body->velocity.y -= GRAVITY * delta; + } + if (body->isGrounded && jumpPressed) + { + body->velocity.y = JUMP_FORCE; + body->isGrounded = false; + SetSoundPitch(body->soundJump, 1.f + (GetRandomValue(-100, 100) * 0.001)); + PlaySound(body->soundJump); + } + + Vector3 front_vec = (Vector3){ sin(rot), 0.f, cos(rot) }; + Vector3 right_vec = (Vector3){ cos(-rot), 0.f, sin(-rot) }; + + Vector3 desired_dir = (Vector3){ + input.x * right_vec.x + input.y * front_vec.x, + 0.f, + input.x * right_vec.z + input.y * front_vec.z, + }; + + body->dir = Vector3Lerp(body->dir, desired_dir, CONTROL * delta); + + float decel = body->isGrounded ? FRICTION : AIR_DRAG; + Vector3 hvel = (Vector3){ + body->velocity.x * decel, + 0.f, + body->velocity.z * decel + }; + + float hvel_length = Vector3Length(hvel); // a.k.a. magnitude + if (hvel_length < MAX_SPEED * 0.01f) { + hvel = (Vector3){ 0 }; + } + + /* This is what creates strafing */ + float speed = Vector3DotProduct(hvel, body->dir); + + /* + Whenever the amount of acceleration to add is clamped by the maximum acceleration constant, + a Player can make the speed faster by bringing the direction closer to horizontal velocity angle + More info here: https://youtu.be/v3zT3Z5apaM?t=165 + */ + float max_speed = crouchHold ? CROUCH_SPEED : MAX_SPEED; + float accel = Clamp(max_speed - speed, 0.f, MAX_ACCEL * delta); + hvel.x += body->dir.x * accel; + hvel.z += body->dir.z * accel; + + body->velocity.x = hvel.x; + body->velocity.z = hvel.z; + + body->position.x += body->velocity.x * delta; + body->position.y += body->velocity.y * delta; + body->position.z += body->velocity.z * delta; + + /* Fancy collision system against "THE FLOOR" */ + if (body->position.y <= 0.f) + { + body->position.y = 0.f; + body->velocity.y = 0.f; + body->isGrounded = true; // <= enables jumping + } +} + +void UpdateCameraAngle(Camera* camera, Vector2* rot, float headTimer, float walkLerp, Vector2 lean) +{ + const Vector3 up = (Vector3){ 0.f, 1.f, 0.f }; + const Vector3 targetOffset = (Vector3){ 0.f, 0.f, -1.f }; + + /* Left & Right */ + Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, rot->x); + + // Clamp view up + float maxAngleUp = Vector3Angle(up, yaw); + maxAngleUp -= 0.001f; // avoid numerical errors + if ( -(rot->y) > maxAngleUp) { rot->y = -maxAngleUp; } + + // Clamp view down + float maxAngleDown = Vector3Angle(Vector3Negate(up), yaw); + maxAngleDown *= -1.0f; // downwards angle is negative + maxAngleDown += 0.001f; // avoid numerical errors + if ( -(rot->y) < maxAngleDown) { rot->y = -maxAngleDown; } + + /* Up & Down */ + Vector3 right = Vector3Normalize(Vector3CrossProduct(yaw, up)); + + // Rotate view vector around right axis + Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, -rot->y - lean.y); + + // Head animation + // Rotate up direction around forward axis + float _sin = sin(headTimer * PI); + float _cos = cos(headTimer * PI); + const float stepRotation = 0.01f; + camera->up = Vector3RotateByAxisAngle(up, pitch, _sin * stepRotation + lean.x); + + /* BOB */ + const float bobSide = 0.1f; + const float bobUp = 0.15f; + Vector3 bobbing = Vector3Scale(right, _sin * bobSide); + bobbing.y = fabsf(_cos * bobUp); + camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp)); + + camera->target = Vector3Add(camera->position, pitch); +} + + +void DrawLevel() +{ + const int floorExtent = 25; + const float tileSize = 5.f; + const Color tileColor1 = (Color){ 150, 200, 200, 255 }; + // Floor tiles + for (int y = -floorExtent; y < floorExtent; y++) + { + for (int x = -floorExtent; x < floorExtent; x++) + { + if ((y & 1) && (x & 1)) + { + DrawPlane((Vector3) { x * tileSize, 0.f, y * tileSize}, + (Vector2) {tileSize, tileSize}, tileColor1); + } + else if(!(y & 1) && !(x & 1)) + { + DrawPlane((Vector3) { x * tileSize, 0.f, y * tileSize}, + (Vector2) {tileSize, tileSize}, LIGHTGRAY); + } + } + } + + const Vector3 towerSize = (Vector3){ 16.f, 32.f, 16.f }; + const Color towerColor = (Color){ 150, 200, 200, 255 }; + + Vector3 towerPos = (Vector3){ 16.f, 16.f, 16.f }; + DrawCubeV(towerPos, towerSize, towerColor); + DrawCubeWiresV(towerPos, towerSize, DARKBLUE); + + towerPos.x *= -1; + DrawCubeV(towerPos, towerSize, towerColor); + DrawCubeWiresV(towerPos, towerSize, DARKBLUE); + + towerPos.z *= -1; + DrawCubeV(towerPos, towerSize, towerColor); + DrawCubeWiresV(towerPos, towerSize, DARKBLUE); + + towerPos.x *= -1; + DrawCubeV(towerPos, towerSize, towerColor); + DrawCubeWiresV(towerPos, towerSize, DARKBLUE); +} + diff --git a/examples/core/resources/huh_jump.wav b/examples/core/resources/huh_jump.wav new file mode 100644 index 0000000000000000000000000000000000000000..9ca8a2e683ef87d19f594be54d04a40dd0bade10 GIT binary patch literal 19050 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 Gd;ABC^mEGq literal 0 HcmV?d00001 From 4d5a56a5f89d37f96ca72d245e39679c2ffc4b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 13:15:14 +0300 Subject: [PATCH 2/8] change game's resolution --- examples/core/core_3d_fps_controller.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/core/core_3d_fps_controller.c b/examples/core/core_3d_fps_controller.c index 56d8c4543..ff348daef 100644 --- a/examples/core/core_3d_fps_controller.c +++ b/examples/core/core_3d_fps_controller.c @@ -58,8 +58,8 @@ typedef struct { Sound soundJump; }Body; -const int screenWidth = 1280; -const int screenHeight = 720; +const int screenWidth = 800; +const int screenHeight = 450; Vector2 sensitivity = { 0.001f, 0.001f }; Body player; From 4233544670c9a2ef9a30e4dcbe747395efea7c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 13:32:08 +0300 Subject: [PATCH 3/8] Update core_3d_fps_controller.c --- examples/core/core_3d_fps_controller.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/core/core_3d_fps_controller.c b/examples/core/core_3d_fps_controller.c index ff348daef..d4936388b 100644 --- a/examples/core/core_3d_fps_controller.c +++ b/examples/core/core_3d_fps_controller.c @@ -356,5 +356,7 @@ void DrawLevel() towerPos.x *= -1; DrawCubeV(towerPos, towerSize, towerColor); DrawCubeWiresV(towerPos, towerSize, DARKBLUE); -} + // Red sun + DrawSphere((Vector3) { 300.f, 300.f, 0.f }, 100.f, (Color) { 255, 0, 0, 255 }); +} From a2cf878190569f2d37c90ff475594d90205eafb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 13:43:38 +0300 Subject: [PATCH 4/8] cleanup variable shadowing --- examples/core/core_3d_fps_controller.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/core/core_3d_fps_controller.c b/examples/core/core_3d_fps_controller.c index d4936388b..3a21ac2dd 100644 --- a/examples/core/core_3d_fps_controller.c +++ b/examples/core/core_3d_fps_controller.c @@ -74,7 +74,7 @@ void UpdateDrawFrame(void); // Update and Draw one frame void DrawLevel(); -void UpdateCameraAngle(Camera* camera, Vector2* rot, float headTimer, float walkLerp, Vector2 lean); +void UpdateCameraAngle(); void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed, bool crouchHold); @@ -167,7 +167,7 @@ void UpdateDrawFrame(void) lean.x = Lerp(lean.x, sideway * 0.02f, 10.f * delta); lean.y = Lerp(lean.y, forward * 0.015f, 10.f * delta); - UpdateCameraAngle(&camera, &lookRotation, headTimer, walkLerp, lean); + UpdateCameraAngle(); // Draw //---------------------------------------------------------------------------------- @@ -272,46 +272,46 @@ void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed } } -void UpdateCameraAngle(Camera* camera, Vector2* rot, float headTimer, float walkLerp, Vector2 lean) +void UpdateCameraAngle() { const Vector3 up = (Vector3){ 0.f, 1.f, 0.f }; const Vector3 targetOffset = (Vector3){ 0.f, 0.f, -1.f }; /* Left & Right */ - Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, rot->x); + Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, lookRotation.x); // Clamp view up float maxAngleUp = Vector3Angle(up, yaw); maxAngleUp -= 0.001f; // avoid numerical errors - if ( -(rot->y) > maxAngleUp) { rot->y = -maxAngleUp; } + if ( -(lookRotation.y) > maxAngleUp) { lookRotation.y = -maxAngleUp; } // Clamp view down float maxAngleDown = Vector3Angle(Vector3Negate(up), yaw); maxAngleDown *= -1.0f; // downwards angle is negative maxAngleDown += 0.001f; // avoid numerical errors - if ( -(rot->y) < maxAngleDown) { rot->y = -maxAngleDown; } + if ( -(lookRotation.y) < maxAngleDown) { lookRotation.y = -maxAngleDown; } /* Up & Down */ Vector3 right = Vector3Normalize(Vector3CrossProduct(yaw, up)); // Rotate view vector around right axis - Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, -rot->y - lean.y); + Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, -lookRotation.y - lean.y); // Head animation // Rotate up direction around forward axis float _sin = sin(headTimer * PI); float _cos = cos(headTimer * PI); const float stepRotation = 0.01f; - camera->up = Vector3RotateByAxisAngle(up, pitch, _sin * stepRotation + lean.x); + camera.up = Vector3RotateByAxisAngle(up, pitch, _sin * stepRotation + lean.x); /* BOB */ const float bobSide = 0.1f; const float bobUp = 0.15f; Vector3 bobbing = Vector3Scale(right, _sin * bobSide); bobbing.y = fabsf(_cos * bobUp); - camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp)); + camera.position = Vector3Add(camera.position, Vector3Scale(bobbing, walkLerp)); - camera->target = Vector3Add(camera->position, pitch); + camera.target = Vector3Add(camera.position, pitch); } From fca2317640dc32e231316e33a0967cee70382c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 13:44:50 +0300 Subject: [PATCH 5/8] remove //#define PLATFORM_WEB --- examples/core/core_3d_fps_controller.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/core/core_3d_fps_controller.c b/examples/core/core_3d_fps_controller.c index 3a21ac2dd..ddb25ba8a 100644 --- a/examples/core/core_3d_fps_controller.c +++ b/examples/core/core_3d_fps_controller.c @@ -19,8 +19,6 @@ #include "raymath.h" #include "rcamera.h" -//#define PLATFORM_WEB - #if defined(PLATFORM_WEB) #include #endif From fa9653d179b56a1c663f0e34a7167c2f6f3c299d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 13:50:24 +0300 Subject: [PATCH 6/8] Fix function call --- examples/core/core_3d_fps_controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/core_3d_fps_controller.c b/examples/core/core_3d_fps_controller.c index ddb25ba8a..c4ef367e9 100644 --- a/examples/core/core_3d_fps_controller.c +++ b/examples/core/core_3d_fps_controller.c @@ -102,7 +102,7 @@ int main(void) player.position.y + (BOTTOM_HEIGHT + headLerp), player.position.z, }; - UpdateCameraAngle(&camera, &lookRotation, headTimer, walkLerp, lean); + UpdateCameraAngle(); DisableCursor(); // Limit cursor to relative movement inside the window From f6b7168ed4c2c70d15c01ed9f3710e8c976b7452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 16:06:46 +0300 Subject: [PATCH 7/8] Add preview image --- examples/core/core_3d_fps_controller.png | Bin 0 -> 16483 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/core/core_3d_fps_controller.png diff --git a/examples/core/core_3d_fps_controller.png b/examples/core/core_3d_fps_controller.png new file mode 100644 index 0000000000000000000000000000000000000000..65a908d529e5eeb82682af2230caf35d1877b4b2 GIT binary patch literal 16483 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 a_X6v}toVg7jH&UmNmWtnezm-1`2Pd$cN=8@ literal 0 HcmV?d00001 From ed022e89e5aabd91c80288df0c671efb4c7e9492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Mon, 23 Jun 2025 16:22:14 +0300 Subject: [PATCH 8/8] fix preview crop --- examples/core/core_3d_fps_controller.png | Bin 16483 -> 9083 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/core/core_3d_fps_controller.png b/examples/core/core_3d_fps_controller.png index 65a908d529e5eeb82682af2230caf35d1877b4b2..d4f83482ffbc77da8353983100d6590071719d23 100644 GIT binary patch literal 9083 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 literal 16483 zcmb`ubySpX7e4w>(jX}*0wU5qNC|>;N;-7N&>$_{ph$=`LrY2P5CYN)3JfuXNQzPe z0@BjwVf1~!@B6La`Qxm0Sc^4l?tAZRU)R2CKQYgAw3JDS7>ED>AXQbluL}S;Yyg1u zivSyJ8CTN41wXJnb(Q6T>Om$n_yyPQp5{FOc#}wcYJ~@WCw!~|^#lM~j>~^6Ro$Dv z06_M)>iv8APs}&6*SEY)4CaU6C1`ySuxp^VxT$SGG=D zYy1X&oFB{|g{|D(hg!_bAjtPC^0upHCxZG#SPsX(uCtu{RM4gN9JFcQ<`CEZ-H;wQ z`XzAO=Df$V?F=^6-?qQbQqj-&t6tmh;JJDBlg`F7&3L-=HLBe0_i#c1|IN|7d{zJm z&1!lB4Z#8j4uFRvF9-QHHiQ`b$S0WO1wTUBED_)b5F7gcp;OOgf>ZYB^Wpo$Ag8@& z+JW*zm%#R+uOU1~MHf507dFkoTjZPK{?pU*+pDh<*W52djAU9N&VLW)oucys12a*r zhiylE7Qef$?cD)8LstiCp?SvxD{VWe0*UMW7U#MpEkDra&a_~k-DY0Iru&f0;fx5! zlqe^1EPW%x4zW3NWFdQ=5OVkfOlRKjqxqB1zGs`-ttV}H!9zi^XKjgR12utr>32_0 zz%UnQyRsLjcCsg#T4+z-mGJ?T--lOdnYPy8eAH5cCpOpjJvyQMLHKKi*ueISlXG0I6uhx50;BX-_uVg zc_**hPfzon%o7JM%gi5T`L?g_xBvbg5VFuRe?0gl=+~=6>78GM@cpdB)9%Leo(yC& zI=0t&gdJfXu+jsay}SF%_8C&x%5}2WO@3)@>t;gXP1EZ_~j?G+TjN{UHmpHBSy(=1vz*w5BQ--<)p; z$UgoITQb`ojF)|Qc1_DB+Gex6sY_r^@fpGYjsfZ2Q>q}!B2mNVFRHKGc02; z4&4sU*0HATsthZ{-E&#lOlQNlnis3gEXM_nA>TL-+t!cV0;hf7Z_ll?EyWLoOs`w) zch28&K)mcdF1EGye{lVsU$;_&rSrIJPVWTzZX+Q8 z2o9dPyBM;4bY>cV{KykFT^X{oIq$#C7`(l8@pDM##M>=+5I(o}J};n~c<#LUTHCHz z&G~Q)Mp^K0-?{n@Se0`MC`n7Z-EXkzh;e@x{sQtA4@}=G&9sO(N9m_)Z4ZnAAnV8Z zFoY+mYct5;yom|nGO=rMGHBO&%s0Os9gw%XEPi*ZswSjU%KRip_G0bY+4lMG-gr6u#5A9ge3$H)Mj z7)lUh1jC_Xml14Ob1`@Kp_vtNlb9k?>p)S`(yxK^`S=DqeF|ZSni-we}Ocwv$%bqvrYJ`eX=?U!~Dm z>6f8es4tnO&{n}=tH&gho9uP*>F(B9mGiMv&%@uR@!i+vI0C+L?eurQ?qy#w96|Og zAg$MP-A{sk6ZKD)e`){zSg6H+o@f8-T~wfKAo2>?{MKFAFD;}jkxdtmYx`23vZ3!9 z9{}v$8B2P-dcAjMJ`|jZ-wwAgIr3b@bZz;6sW9JBmpwxro_#ocf6;4xkwgwo^=^yv zo%FW7V&&xPL3__tEl$5*oFw|5f0La#I#Y-6tjN#zXRSW?qA?RFJMOeQ6cg}MYKKsH zQk?FRtBv^d3$i?N@kMu%+{X|dp@y~bnmfKrW4}ji+-}9a-+M%$j5BKPF2#Bx-O#*X z0sssv=U1E!V`ui~VM`Y}zh54nj;V(n^|l`xUF;uT9JdGlP@cc|r9gi6HBV+IbLcb= zColL{C%){((U9!UCw6j~z2U`nq~w>A&6&Oa+-Y>oNbte8dyN)5L%oeplOx2lTZfY@ zu4~DNpps+u76Z1VOyN7B-JiB!x!T27`5*9*h!07L2cP7&EGE(q-eI7B?=BcJ$FmuH z-E0;egAIrdoQ=2`61Dgm9j$nP>-R{O`aHto=*`wyM`GL02-%$omg8$~$CCoGd*33+ zWltXqKYXSgw5CTc{Y&oncvyivc+)cv?u=-zi70_1@8kyW@~zkTZuOTgYVdqzHe`y6q! zYwmuyySg?gO%3FmZIZhnbO(BjNR=UW4amNWf?p@W8y2k~wbPyX-z&0v3n4yRTWtbI zukl#|1?elbum2vfyPMnw@*)pBK;-3EA)3S5Hs+d!BTj0>S>E~`)t&Bs^Apcz`uVQu zaG?0rO70USh;VZ({5g7eLG$c~D;?oF$yn=iFlF4HFM_kX4h+#QI17rl}c zZ=>0Do?tl}$!l8{m;F6OesR1WeDVdHY!*S?;Mn#gp7p^u1Lj-XPv#DTe>So_`4;x5 z{AK6yym;XE(Y$jn2G#3M)yTExSJ7m72(3&Dso~k+-7PC+a*0`A?U}sVtvlbxNby~B zv*yJfDnqQiXv8g=hhn7O+QnV*iIt8%-KDL$BP9|t!l#@ZLzSR(g}hDBB0EU&z|Yyc zG?x$<7CpqThjL9(2#5uHbAVKh+IE(dulr4|{vwY6hc67jIYjj5d1|frL*`v)L-CS> zjG(b=B4>k|JoORE+DO^?!M5puMDxclH>-|PHo0!Cy~58tWHMXN^`%C+Kk;R8j*vQ@ z=OJs#43=WOc#q_1ez&F7dS<~e#W|(CoaDunIJw?^gfMsaYROD*%geq30QbPu?H4}J z61Jlkah?b{uep$EDz;TS9DEB^cBwxJyg^D*y5bqI<8ZXny=XL-F0)%koVTA&j~QH#L7MyOzw^N>98oaNCW2_4@08v){9yX3wNwl1ZUt_kVp@IK|Pk za6eeUKh79>k9RqpE{|>P@>9J+O;40Y(AR|5ko8V*=742EQYFed=oCCQQR!_(y)Jz@ z@B=AVS+&PcTzbz1@WF!MP@^9DOqnHUkC^B7;+yK_x0fY^5?De6hJU`SHuChH5v~^_ zWQmtW>Gjv=ZkRGA@c*|O=PfjZ3;pW|*4%xgC!=gkGl@h!-eDksy z?u9%3qY`{DQSp`@kt~#nrR;CHLkQc}l>rGyt#fX0) z?rAhCta78=oynbPv8F7&$1hy#z(QRsq+MLBp7m>Ef? z$G`ain-%HM_*H^Oacn^?PYeI9k&IiAsVrI=${hR`W9>dnP+z z-f9sNj0uaVRX$H;n9QR`9=?PHYoIIs=)%?JW-n1j8xeRaPa}J`tQ4toG=n)a3;kWs zJHn@qN&|e|p9#i!oDJDC4x(S+qrD(XU)zxk=b594D{K7wBsB?fUU|LB(H6+3O&md= z&{rtR^(QNp1UE=o$x&$MI8tZBLot>C<>-)Q1{NqJB=FJi@wn{w#iO4%BFnErD)2Pi z6h1xklDi}?OoHE%w2&up_N01Kcj#lqv6s5|%OP>kfk>^{;@sfHMUKcdn*VlrhLk5T z;C42AqG6-(DbY*mpL9j_ib5h!RqX17YM}&TH=PZgHH;KKrFv=nWAL%ZODxhO>>ot8&)=gP^Y=tMIA7>)}5JiXZnxFa|P^259$1=!)Tm>X65U z!!T5+RQ-xbK{~%(24Sn$5v`|KI_yyfA>65xr^ij=e$ajKj3N59@3^85CM(M_(xP98 zql+4P4hi26D<}#M|yexJrl$O_0OkVP9$x%fi ziJqbD2qaR-oC2tirYn;}miK<-94BR;JC+6(odjlhr{j4_?z4B3D`cvV+9lX8iHuqf zeosnfFkf3f^kV1aT#RVdO7PvKT6R(vN14g<{5K-+8>rdtI-R-X5o?}A&`l#*;nU%e z>nswb!GpiLb0$B$o(_Q}1&jlndwIJ_omS~n};dCV!Luvr*Zb+X>>B1*f&8CsKIN77c#pl{|A-A&loec#w zI2AsXdYQu?$-+}@st@u!kGIduk1jL!j9mdeC3IFCJoPzgJ2N`?ecou|;^L39mEaG8 zOs3K(QXdw7Z=-<0_`O|ZWZ?T`{zn;|n@+OrdLe{W)DRxJl1$b`J;@r)w{MU;ulCLS zj;S0oC8|FTedPw~B5I+Xf=Ck9Jd~fyOC1Q${t1((Sb23D%BMjx^uPORL*P+Y8HnIC zB%=dYcerxC-0Fm}j=lIV6Usk(2Myuq=c^t(%wPX8ND|EXgHQ9X!5;*}zX(bH5J-)8 znRt8Q(jIfc*5PgQt^HZ(0R@DI@-P3YaOBHcXc?Xrg3T(6UjAaQBJnLZbfm<+}*?hYY8 zqgU9;yI_i4f9Hci+9dD(5Kgx`JNxWPQqn0(l{9adi-mqL^R969f>}xNX#*wUOu+VeI zuXwQ^MLuUgGCRs^LaFpVE_%iIxh6L|nTG{^mwaWhZ-rzfF>W!N>0WRok|@FfMsSoe z=+yn>4fM$9Rnk#w&k8RiTGV&&@y&Lg3lYpZ;9;R}mt^|aJCE_RSa!sFLO9KpzvC4B zbq=&_<1ESTO_4=78Sop1!e@aT)<<6?(fD6x8sDTo)4gVhs^rWoW2%RXYsT6yMB*uuFR-_ zYwND?sdTW|g|zLX-}D78;BFP+;6UJ)tmU{1?pB}i_ecbCm_GL+KYc1T=j@FU2hSSx z-9*`f(I$x>+8M&0fp_IOB9XCSe}(TlpEg2OIhhrXU)b<_vm6f{sgx%F=w|c;LBO%7 zI9oAYS&oyn>KoWTB1pXo;kk0DL`Sj`iD*TtF*H)Z9^KiPc_ec8z0jALq|MzFiKG8j zMRIvsfX7L}3#6K`IcpFSt*peq@5K%~U92-@XkD67x!Zn`-9G>>CgC8M76UpZM9JR7 z3Sn(&%pgBkluWebJTb`as7c0ePric$!4k9FIM#^f05{kn4Q_+CpDp(iQBugFxe~OKd z9pK>zo}SdMe|HQa!FW3O=>)zXpF!_5U%D zRw<=Q_!sg|fe>l)uSbBw>KbY!66;@9-K<{TX!|bU?>>feS*w6$&I0wn7N1$Y%+RJ? zT>oMuE3C$%3L-`RPHei2yD`Hw#R`OWf3;f)R*@A{sPs|{M*Jz(x-6TS<&BaO*t7Bf zh>z;@lDe$k*y6(fv0%6^f1++jq4bx!l^|HoCy2e$pwaH4WaEEF&1bL1E0r%=-}BJ%D_Fjl}!*@m}SY#I;ZW zpb*TVEU-oSg~xZmuz>p=qUw>fDlvo&IAGm<6?asaB8w;I<|Nr=z0RcZ<-UEhSG1+x zrK7uGJXOIn6jpduC+Ha2Ri_=vucnMobb0TSAPSvNV3v|VMh#rTkdEG`U`Qe(O~JbS zc6C&ZLXwO5+U+YKn;SPu;B2BPgG4D{p+E9&C5lB2buBbnNQS1sRFXpnyiSPxz7g^} z=Ch4=h;>80yM~G4?Q|_d>ML+O_f=BEV+0k9n4#CpFj5j7DCbuTy&5*CMV~lMjKJfw zIp&diSZXjTg%ziC8-OTcKYzUOw`#a?vxMr^3*EP!;G!xE9o(j4d{ozj zT#Nh~{v;zUE?m{&3X3J8LyGE5j}<;nh`{RV!7WFk8$S{oOPDK&&cf!Jym#0e3 zTnsq}X!YaK6J?TIN#DQ$d1n)5*PMo-P%f0iIL@|29vFedw%`@f_)>qFWF3K$5cUh* zdnrHBpQH%~IDR3F+kWccyyPLx$q-ER8 z1SWL0`DL9JaF|h&aH>KdKGgy1Ooh6=oSDM-5RA?y;d6=Wu!26f;CF6bU=%ub?mh8R zVcz9c>tjy|*x;iA$J0h`HO{4ogFqx&Pdx@7qtwa~|SkUgbT%ovto zkDfnpaF}Pso#dT_yTm^j#{idiJjBvhnR0y!ZpJ>go<`K*r5HG6Xy~*>uRA3=Z0?w?PcTADoZ}f|$u@VEGd}i)Vv95}damx$L3~F%f?yZj;&< z)&&g%lf1XpA8=AnUqXk4#Kp+16rF{qb-?c3Q=87G#VGmR`;aI_JpdQHMh(~f`7Lbf z&1J5?vDgT_IKaESXjbg7Nd<@c)TUAijxv`6D+9}b10gx&-%xLu<5iyH-w8#A$A3kh ziMk>rtr|LHd!lgDXh~jxn0#MHk1Y}4i~}2!B9qeaA762%b&f`#6-Ob3F|3qd>l>4F z;MPKGNlTW}X|JzmgJVt6)Al5d?MenAgm?nA?>+icoft004<`PpJH#lx3;Q7!gxJuX zuO$MR#Rj$}Y|BWg2wa&2_cz{^SaW>1m>IYlqJ@-*i}0~h@ZosGP1PfvFeD9(7&{^a zyAc$@Y9uQ8r1E2zGZyd@j6!RDe3;t>tGWgw1}yPGGFL|%4yhqdRNLayxRf8qx#1=#sMWo46kpx+&Y)Q2`#OWJg4`hlJXy8k$0E6!9wM4Ff0g9?mxC9 zwb1RzOUB^+3Yewj-eA{%84`u0(r7;cR?w5lC*%%hTflxY)3q4K1y}drPt5NFv3xtR~Us zggvHFxbMU`&eQTLEdl_@#(~qs3>s(Nol+H{waRU3uf8s)UnNZk0FNo04X;WHcnl^L zZEI!8WO|a%Xd02jDDSKwcLIGPAPtK-Fi8_2X$ zWG<5WlCa<;VAx3#B@8L~((~GPO{Hm&TuJZL^Y6*BDaiXP}pq zPzP($y3_aWAxgg3fC8K})R z+nHN+rRPi82N65;8rBEH@nv>ASr6&x^yZ^xdcabk7AhuGQByg#Om2FETnN{&xPd(? zXxlPQqs(g@(BYb_bfnv2f<0j5i9qfQrbNG~q=~oR#piz!Lx?nEA^l<{RM}&F z(O$Y>AfxNn1iUfTY*BRvsC1c9V!06jaK?i4bB&&SFwEgH0`rl236q$olH?^!Q9Y7X zy1#wsAqI{X%z(4vi$x0ajjZ8PnI*_R1-TvU$jbK1>)?D)^)CX3n1SnJpS$0XiPl zLK7YiGpdPJ{bP|^!rEGq{H!3GsI|f*$`B6_#Bxr%mL?WWxlyF^Jd5KJh0KSwwJ_Ol zpN#t$<@&(*CeQ({gloL(AU)NQbI}K&ES*Wj)P|@~GtC4LS$?&}wTFVPYUkv2e8strI0I>e|)|?QHpp0MSMmpT)w8EY6 z7k`oaO+wQsu4StViqXrMU;T0X~yRVvB+nbBt5#7NP z@$JUCK{8oc@uq|-WtB}!GC5h$+R61x4L=tdjutC&)(0Q}AnT5mXk3owr!j+ztkJZh zjq^t7*BY^gX8nLNaQ___-1lw94oK=y_bhHgwl%+hNBU%Q5JzqUjM|+A(J701vZ~?Q zVk3xjIT&C1=+fcodmV7ZhkG+m)P+&-5LJJ8*gGSRQ{}60rY10f$$An(`POuuH3_@U*UunlC^6`eA_J80Eh6B|J^ zuhy%c_fHZeK9=O*gtkDddbhb%z(6?nb46N6mA@9E+LwgB{uiN`*9{2$GM77OB{9g3zu2W3=KrYC zs;oQ_YXBeNw@SKYO)onQB&=ktY|38lCr+FbV`uU*-P$}mGt}V7z{MMlScf(DI~J zt))sqf_^uWd+}6EzgdW!qK381{ePM}+MU;HMwniJA^ql7XgSKwqDxiQis-oV(vxhpVYZTxWIjUxItR#QkzcWuhGa$5?L(^skc7)O>#-o z5CBifAQik$eL=;{uFYKn!v)Kme#H_V*L{ez@vwnH@brGpRRfNi!Edx&YQwK`G2bB` zWYTV}-V^Stz*S~v!+VAk$MRKO+V~!G#0rj^xkg#+D^{hy^x1(Ml9QF;m9O`gjwAEP z7T;fs9-EP=5mg@S)>?S21jvCk8lF(ScUs>*p)7M5igqrA`wwtA1qPVQkoH(Us7w3A zeU3oEu@eNog#o^W0oJYL-HQT&4}QF-h}M@1*bFS@l1?SW$f0&33TnEwPsn6z$8|#g z$b-2{d&_+e?^St@%VE3jKYk@egJAVUgPL)v5!XCt*QO|c2*}yjLZ=aLKYW>-CXjIsHg_9qsPKQQGc)< zG1w+=-@Z#5538+?@`rL;c-TR-ox_{HiN z-~jUAQjAMYZ8f!dJnnIN*j{E_ySsm@KV*?ho`wt{02jH4q2Yl?e5XPG_WVVmW9Q(P zzqofWxX6dlul-_IjQDy(E}oa;Nm;nPJyp(S(_a8Whbd?9T1ulRgD}@1dc?g~8_r^0i>j~KB2J^<)E-;~#7+9w+~iG!Xl@TX2||?{0;bAx&rL z4TF2Y4gSeW(udH|{(4*^WJ&DcwTGUE?Q4Ms6oEv#G`PU`aO4!AC$my+s{VM~x!iTS z-l=ohD5r)yT>D;mI3Q>n&3VGukao}Gtiz=Ab>Xh!csQ~~(!u~YFI=AjEA*WuV!~Q&#WZytzgkjrTt+IC z_GidAR|VT|>Y`Wz-~%4KJ~nmyy}iieaffpIfUtVYiwZ3$Mv^i{l0inZgwaMuqL1O4 z9`Ql@S_(#x_a90h`y9=y>7O`>7}T|P7}s7HlvZBSDrd*g@|Z~9@j!N%z+V?`;7x>| z)kxab zdSZA$csSBH{B^3QK^^`RC&7C0pMdd;@F|3$`YD&zI5j{3o+XfVo+leJ&S_c3mD*qy zHlP(8=hUTrL;x-xTnxTX^WK#F*MylP+UHIE4dQyv>a^c_+1xz9Rchx6XG6nZg`^!O zzORd?KTd@6j^(~H{;us_UJ1zQ)IxV3TC_R2St7>9tY;nX(K>3I@@<#iF@OR$ZckSF zRSL{2GKMy8>Z&(_ilAjO?)4w?zU$j!h2~o#maWPcO=+sm$xPHYW+kI(9~B&Yz(`8P zNXqIwo-(UD4shbDuWSBg{Nm}9r_rS%nrj$ESJs_;N7lBg>c>!PT~7Dd9EZ#>kxem? z=__ky>wRmWj*f3!>v@UmSNq>zcMfLW^HeK~R;u;9mgZ^^8>~aANtiDE2cEv<9Go=4n8b{&5o&k0H z8Zjop&-M*k>}P!^^&PiHt?F)2V0jpgQ0iM_5LGK{rWDuPx=SeY4SI*e@8ftE$6xCG< z%7+2D`?b(?sKwjov_Ub<#f7)7nG<_Z+z6uKV~r}8#{nohVP-ukAMv=2_n3WBfFQ{@ z+C?_GV{T)4B7>+a09!b+IgabOr$O^~sh_v8j=kvkJ}HLo8Pr8mmlKf!_i^FgVf*`% za-&(r6BFyE#3+gz5g2IWKhTyzt^CH@%nix0l1!4X0s2aNLN5Jr2H+_HWF5QY7QfC& z>{e|Ku01NANA3#GWzc#|PzIZzH~eOs7)R45eEo`{B!-tU`!F%ZdXBA`^KFm@5$Zk_ zFwX}gU3z8Q;+RCxtv~l3@z|Rt1;)BUBVtz+M)?wd}vO~kHrYdu?;GA9rhG`_h`rw!c4;_9aa9f z@`#T(lOq66LzFVys~? zKF}40lnmnvC)RK7llsXfH061duU{ojdZIp-x=M{4h{S>0el3zquihbRQ8A0J!uwBe z`JY~>MZS9alRUnn>K-tEwl|foW1z<|&~GaRhKtqT57Fux**M+n7p7!S^sZu4tXRVV z7CK;14Ls9)2&po>0!%Lbv!vc;!=yrkeXP*OmWYJOBFSEReZ<(emuF5;UF)K^)dofO z2BE+WrpZe738NL%{;b_aSw)3dp{?q(q&|!*7Bzpm~XM_Vt4MWDc(1#X8dL|L6Ahcc!^x&L3J}H?U8a4tjp|M zCpXW)Y@C{MTE^cNMXK7G5v%^w)kWQgH&yT!gtYPpbFZ$Jp+8aog1V~j>SgY|yKgBr zdD;3-ORPCM#M?u4yNcd6N0m`xP{o~fQ`C)o@^aWUY?M^3Kq~UO9o$O5RbuA}()H&% zWVW+*D`nMrV21n%laXt*FR=}UutOhOB3uPI+`_WF89|LrX-ga$kO~tOqK6*|0PwEz zcMB4u*UiBbPyf@gkLdvKed>CjRZ{Tvt7kYHHol;)U84X#V8cI#^jS4^c`ZFLPRkM` zta4@LvK(gzo+_?GoRU45N+gg52;##U+t-B2!x##x7z&Wvy~R$=)431KM4XiSb*XL@ zjPu>Zt9*$IyaC?>=IfQB_G*-Q)eM_RNGrajA&()*K?qon)FG#eXk*YC#A7>CIThPu zWA6eDIDn^kkbc^hrm2Gblb`hQ;vPfB*;#@T7&4c=ildNz{bpNkv*B4toFJb>E^X;8 z4J{0)0SMYT5Busbt}dnT*+}}TS!*KUf4fJj!I)RKbdaF)nj};T6skg4<<7^gfyp&@ zy|b9Hd5b5Xx@J+NVPhI~EfE#)q0kI&+czVeTD|PrqF9v1q}~6PimP9;6j`V*!GK>9Q`&7?4jXo#q~Y)MHvPKz>TYX zQ@nb!X$~=xn+*o{*Lqp&{|EHxvh&2Pecu?i%_i-!$?mC=I$LTwxQDaZHei5@K;X$rj;VsDEgMu~5J6GJBw>?FqTIT`)u#<0=Ep|& zypi8KXHNfdD#bW`ohk?qaHSN3fcoy-`|DP&hjB}L?bKhVfOj}^lTGZ$3*+p3l}wDp zaV~)1z5>LlqOU~(&v*K!<4^M{2loUvjz$cdatyFv>{u*q+4hoAfvp5l+E<43WNX9M z*r9S@E#eTfv(cn5HrZ-C`j!c=-#NY?)Ta;XV|WWKDdQU@TblNaA()6$aD*m=gA$j( z++Bjcg)ZaED*AVX$(qJ)<~?)G4Gf6&Nq);%NyB$l>YGKs2Q@E3jGyykWjG!X_6~fp zpoEsr0foC5H&I}Rv`c>5qP^iW&FbiEM(PO73J2L<0#|{+=`IrlB^u6bGXCrX-A0Zv zQyWb(xa%Jt)bna~zBEC5=uVcK0$1_A@}Aj_l&q544oj81F+k21_yo9;r#4iBnN!Bt zX-sna06HQS=MX0$KQ6BFO>g+vOb}7y%7Ko~0hc=-_ySfE;nS$zT5*t+rp0-X!|qxf=<)Pe=Q)LYv(31A_|GQc3u}w z?~ppN#_W_5G9A%$^CH!ik@q0dYlmBdrde1zq5UE7Vi6OPRv7kj%$tH^tDXo~q<=sc`JzW3?c5PiJB$++-*G)x6g{E# zWFJ_`OD=)kPB0PmzmAlOxHapsz47fuKcqi@QA(lHMY-IUGgYgBUP!GoBMI6UB452I z0U7HrQZ4nvJ|m1vT2(W07k0L_moqx<85vVtrSM#J72Vd>_ub+hpnB=GKoaXA-0YI_ ztY#4H)^vOJv7Atjya<26*V5rQhc^yue*A-DCPVqEVK0zthqhsRH)}HNIn~6kDd4Zs z4Yjf=9g^0hlz6@H`jqzax^VTTB5_KLv3@|ClR|NAi|%8}VmpTA&;3PqnsThU@*-)4 zr5Z|&%!2)y95U9|sE?VvRu;t^4@3uAbG%$av9m&5?|l5=OFv+y;61u`{Gd7WhekH! z(ZM{-tcbXohU2&_I8jrW z3Z^>kb!E3utGR)CW8Y`BsW&47WL?uE-H=?Zsnl;0c0I*Po*{iRGtp0r(~MEkedxY8 zi_P5Klx5AHncN~`JDta)!!q>CW=*0tDWu?JGWFMv%7_97+%=5rUDJSi4I8IbzB|Z6 zT2sNhSlZtr`dJ|UzHC`jix(x|PwK1(bgj-5{vU3`4k0P#f>=>fShKav{+slo4#F^e zTJ=OJB_U0v#ws~-$^3%M3~!`vv)NXz>fsu6&n;V>#RVk~FXlul_g69Tl>o3jZSF1F zoPkJWeK*fA!-gN-pepA(>0=7A;U%Yh0>gZK&F-Ip574RU!@^*SsTFD@@(bbxr|ZpU zZD`hgyb^PsKdVaTcMJ2|(a92zrEMaUS*NAyQA9WBeS)E<#fB+4^BDte8qSUTPFy)f ztkMkUt}7h{52CUHN>yUqxQ-Zliy4Vtv78#9*@XJ%p=KnEh4q?p;yB!Ia#=A zRm|gc4yzZs-{2ZW0Yl&z48dOC*FR0siY99C;y5)*mUwLIa zpnRCFyw#%k%EactGk)&_ma!bxUifYX0XVpMD}5042ieNgRLoTkB(Nd7&vYrC!oK^$ zqqo%DPx8HdVo^EO9;;#|mRbo4T*D+AUG)z{KMI}*^3Qs@Xy_|t>637j(D@?)!~k>A zH4Az78aZGMTq+R%qzabNH!j&ko;F_>rDA)Rag1GF=Vuw@yb+l4^VnIL^FEn z^u0Pne)yS7#q|!$c&%-9)>e?1CCT;Om0K^(n@veLET#5lb~Et!b-;uDzH^bPrgeig z4;no<>{bY&KD!OOs7OnzBXId@@ZdI?AY*`5*2Z9VqvGVIC+4CYM10 zU5=#~XfPn;s5upd)u%IUFOX*4Fx5`oNS+c=H8Q&1Yd1kVDqt73_mrm~qF%uNFmPa^ z>cJ?)>8Y>?)+~TO@VdE>`h~2QYgfS%^24JlE(hYld>7KNG<`Zm>xs&iPn?G!)~t?* z@n@mt22H!?;|Km9B5B#gCVwPmue7bv#1$Fh2Ux!}k`WWRScOuzZ zC}A;QRJ2W%p>SKaYBOU4^;KoPE3G(|P6GnIROk_!!g)9-*GhvDM}=4_$_K(`yudMF zE-@01^ap=Q;HES}&GqK)uoX!pEiIX6Y@g~@gx>0l*}?~Rlv)r3GKIkdLyp>9;ZFIy z6A|BYBff5UsL`(Ha^Bs32BYRne(QTZhu~q1kEgFjvyF;V1#Ql=pph1nk4y#0DE&K@ z5WCyR=TC!0z~eB`(qoDT%Iln#df+T3Nl?o^b&PfEqkVNC0u7u%L zje&c<4edn((K)la(6HF`B3tj!Q;5WVEa1#!wjnD(I_pKFfx2+wW){6!lGugpG}_$ zQ(UXs_0Oo3ND7xqJWr3NvQv2Al@^qrkyU!Zr}%PWnUVSaoqWx&WS%#NO}(ef_BuqH zHBCalo;Kfv7Z-32<*j1aiIyjU>`#-Fwy^DUl7nVf9;Y zbyZI0wkO=0Oe3NTcJz`A=CUeIWno0h@()ZnCXeUGRtWJ ziA#(`d}{dvcrjB~>Tn{Z(g>{6Z(xg|D(OI!=$Ph`Wlg*UN{hM^<`7X}yr=F$!gsyT zvK+UsSO$A$(y=bl+dBAK)Z!q_VSgBMjA!&b4U1n$jPre+^TXKS@yBsKr9uOVPO*Jc zydUvu$<8Wg^J{M~m4q8`^5Im6l`G)bcM68>Riq%-+Tto&@V~9CHkyMA{u`Yhc@2LQ zUVVYQ9;Y$Rz&*%w=170E))uuFPDcqHj=sD^Z z$0}~Ax6~T3G~{wx==@15Z$K*pa({o|bW|o^B?{%#;K|~U!3OeW#-{8F;Z|awt)cML zVZ~50!RoTQJ;TtT2Yxxxn^=>?Insl36El;Qy|U-qQ?n#y_z&aVCFY85V>Kw))`9b> zVh`iQ52Sj!V(HUmeBH62}yN&F7a}R!=3wxeAR)W z5~za|keyi$wZ{T_GdvngsqcA#_uM0I$=?}xrc7155wTi^4GE?kF5!3an*&M-6vI3#%fSf zB${~@*~y=A909%{_L~y?X`1|DCy)$8mZ+5CFXvn1F6e|?5o^4@_vIz{Vhs4_JYaKu a_X6v}toVg7jH&UmNmWtnezm-1`2Pd$cN=8@