Author SHA1 Message Date
enne2 2e2c5bbdf6 feat: add LPC-style rat assets, sprite generation scripts, and grid extraction tools 2026-06-27 16:29:46 +02:00
enne2 5f2d09fef4 Fix rat animations and restore map tiles 2026-06-27 15:15:56 +02:00
John Doe bdf5a8d474 Add new start animation asset for game launch 2026-05-22 18:58:09 +02:00
John Doe ac80210ba5 Add guide button to quit game in start menu keybindings 2026-05-09 13:32:57 +02:00
John Doe d9d7a4ac82 Update keybindings and enhance loading screen functionality
- Refactor keybindings for gas spawning across multiple configurations
- Implement new loading screen updates during game initialization
- Add tests to ensure all weapon actions are exposed in keybinding profiles
- Introduce new assets for explosion effects
2026-05-09 13:29:32 +02:00
John Doe 310dc0dca9 Add DAT finale flow, editor, and new soundtrack assets 2026-05-09 12:03:17 +02:00
John Doe f0d056e7f0 Make muOS launcher prefer local venv 2026-05-08 19:45:25 +02:00
John Doe d32d2cd79c Refine start menu difficulty and preview workflow 2026-05-08 18:26:55 +02:00
John Doe f1770b218c Add animated start menu and level music config 2026-05-07 23:18:39 +02:00
John Doe 2367f4fb1c Add menu audio controls and menu music 2026-05-07 20:35:15 +02:00
John Doe a908b50019 Add looping gameplay music 2026-05-07 20:03:20 +02:00
John Doe 5233294b26 Detect muOS board for keybindings 2026-05-07 19:38:05 +02:00
John Doe 486fea38e7 Implement game controller support and add keybindings for gamepad input 2026-05-07 17:50:07 +02:00
John Doe 9421d8d47c Remove 'kill_rat' keybinding from game controls for cleaner input mapping 2026-05-07 17:49:52 +02:00
John Doe 509b3433b8 Refactor rendering logic in MiceMaze and Rat classes for improved clarity and efficiency 2026-04-14 12:15:16 +02:00
John Doe bbafc3bbba Add new PNG assets for Rat character and environmental elements 2026-04-14 11:35:57 +02:00
John Doe b243cf04d3 Add explosion stage 1 PNG assets for all directions
- Added BMP_1_EXPLOSION_DOWN.png to original and preview directories.
- Added BMP_1_EXPLOSION_LEFT.png to original and preview directories.
- Added BMP_1_EXPLOSION_RIGHT.png to original and preview directories.
- Added BMP_1_EXPLOSION_UP.png to original and preview directories.

These assets are part of the explosion animation for the game, enhancing visual effects during gameplay.
2026-04-14 11:24:16 +02:00
John Doe eaafd92dc2 Enhance asset loading by removing unnecessary surface parameter and adding texture variants for grass and flowers 2026-03-28 16:53:22 +01:00
John Doe b60ffd87aa Refactor code structure for improved readability and maintainability 2026-03-28 16:05:08 +01:00
798 changed files with 180976 additions and 275 deletions
@@ -0,0 +1,107 @@
---
applyTo: "tools/vernon/**,assets/Rat/**"
---
# Pixel Art Sprite Workflow — mice project
## Strumenti disponibili
| Script | Uso |
|--------|-----|
| `tools/vernon/image_to_json.py <INPUT.png> <OUTPUT.json>` | Converte PNG → matrice JSON RGBA 64×64 |
| `tools/vernon/json_to_png.py <INPUT.json> <OUTPUT.png>` | Converte matrice JSON RGBA → PNG |
Entrambi usano Pillow e richiedono il `venv` attivo:
```bash
source .venv/bin/activate
```
## Formato JSON
```json
{
"source": "BMP_BOMB0.png",
"width": 64,
"height": 64,
"mode": "RGBA",
"pixels": [
[ [R, G, B, A], ... ], // riga 0, 64 pixel
... // 64 righe totali
]
}
```
Ogni pixel è `[R, G, B, A]` con valori 0–255.
## Convenzioni cromatiche del gioco
- **Colore trasparente (chromakey):** `[128, 128, 128, 192]` — usato come sfondo, il motore lo rende hidden
- **Alpha standard:** `192` per tutti i pixel visibili (coerente con gli asset originali)
## Workflow iterativo di redesign (passi 0–4)
```
0. BACKUP → prima di sovrascrivere, copia l'originale:
cp assets/Rat/<NAME>.png assets/Rat/backup/<NAME>_original.png
1. image_to_json.py → esamina JSON e PNG originale
2. capire struttura: sfondo, palette, forma principale
3. modificare JSON (o generarlo via script Python) con:
- più livelli di shading (8+ valori invece di 3)
- dettagli geometrici aggiuntivi (texture, bordi, ombre interne)
- palette più ricca mantenendo stile pixel art (bordi netti, no anti-alias)
4. json_to_png.py → valuta risultato visivo; se non soddisfacente, torna a 3
```
## Pattern Python per generare JSON programmaticamente
```python
import json, math
from pathlib import Path
W, H = 64, 64
A = 192 # alpha standard
def px(r, g, b): return [r, g, b, A]
TRANSPARENT = px(128, 128, 128)
grid = [[TRANSPARENT[:] for _ in range(W)] for _ in range(H)]
def put(x, y, col):
if 0 <= x < W and 0 <= y < H:
grid[y][x] = col[:]
# ... disegna su grid ...
data = {"source": "BMP_X.png", "width": W, "height": H, "mode": "RGBA", "pixels": grid}
Path("tools/vernon/output/BMP_X_v2.json").write_text(json.dumps(data, indent=2))
```
## Tecniche pixel art a 64×64
- **Shading sferico:** calcola normale + dot product con luce per N livelli di grigio discreti
- **Rope/miccia:** traccia bezier quadratica, alterna 2–3 toni in sequenza (effetto intrecciato)
- **Scintilla:** pixel centrali chiari (bianco/giallo), bordi che degradano in arancio → rosso
- **Outline:** bordo di 1px nero (`[0,0,0,192]`) attorno a tutte le forme principali
- **Nessun anti-aliasing:** ogni pixel è un colore solido discreto della palette scelta
## Asset da redesignare (tutti 64×64)
| File | Gruppo |
|------|--------|
| `BMP_BOMB0.png` … `BMP_BOMB4.png` | Animazione bomba (0=quieta, 4=accesa) |
| `BMP_1_GRASS_1.png` … `BMP_1_GRASS_4.png` | Tile erba tema 1 (verde) — **redesignate con FBM 7-toni** |
| `BMP_2_GRASS_1.png` … `BMP_2_GRASS_4.png` | Tile erba tema 2 (secca/autunnale) |
| `BMP_3_GRASS_1.png` … `BMP_3_GRASS_4.png` | Tile erba tema 3 (dungeon/pietra) |
| `BMP_4_GRASS_1.png` … `BMP_4_GRASS_4.png` | Tile erba tema 4 (fuoco/lava) |
| `BMP_GAS.png`, `BMP_GAS_{DIR}.png` | Gas generico + 4 direzioni |
| `BMP_EXPLOSION.png`, `BMP_EXPLOSION_{DIR}.png` | Esplosione generica + 4 direzioni |
| `BMP_NUCLEAR.png` | Fungo nucleare |
| `BMP_POISON.png` | Veleno |
## Note sull'animazione BOMB (frame 0–4)
- `BOMB0`: bomba ferma, scintilla piccola a riposo
- `BOMB1`–`BOMB3`: miccia che brucia (la scintilla avanza verso il corpo, la corda si accorcia)
- `BOMB4`: quasi esplode (glow rosso/arancio sul corpo, scintilla grande)
Per i frame animati: mantieni identici corpo + miccia, varia solo posizione/dimensione scintilla e eventuale glow progressivo.
+40
View File
@@ -0,0 +1,40 @@
# Project Guidelines
## UI Preview Tool
When editing the start menu, pause menu, or level intro UI, generate a real preview image before judging layout changes.
Use [tools/render_menu_preview.py](tools/render_menu_preview.py) instead of relying on mental layout or ad-hoc screenshots. The tool renders the actual SDL scene and saves a PNG from the real renderer.
Typical command:
```bash
/home/enne2/dev/mice/.venv/bin/python tools/render_menu_preview.py \
--output /tmp/mice_start_preview.png \
--screen start \
--difficulty normal \
--resolution 1280x720
```
Supported screens:
- `start`
- `pause`
- `level_intro`
Useful flags:
- `--difficulty easy|normal|hard`
- `--resolution WIDTHxHEIGHT`
- `--output /path/to/file.png`
- `--seed N` for deterministic previews
- `--animation-ms N` to choose the GIF frame timestamp for the start menu
Workflow when touching menu layout:
1. Edit the menu code.
2. Run the preview tool for the relevant screen.
3. Inspect the generated PNG.
4. Iterate until spacing and readability are correct.
The preview tool is intended for fast visual feedback and should be preferred before launching a full interactive game session for menu-only changes.
+18
View File
@@ -241,6 +241,24 @@ Units interact through a centralized collision and event system:
- `numpy` 2.3.4 for vectorized collision detection
- `sdl2` for graphics and window management
## Map Editor
The project now includes a Tkinter editor for `level.dat` archives:
- Launch with `python tools/level_editor.py`
- Open a specific archive with `python tools/level_editor.py --file assets/Rat/level.dat`
- Start on a specific level with `python tools/level_editor.py --file assets/Rat/level.dat --level 7`
- The editor requires a Python installation with the standard `tkinter` module available at OS level
Editor capabilities:
- Edits the full 32-level DAT archive used by the game
- Creates new DAT archives with 32 default levels
- Paints `EMPTY`, `WALL`, and `TUNNEL` tiles with brush, fill, and rectangle tools
- Supports undo/redo, level copy/paste, and level duplication between slots
- Imports a single level from JSON and exports the current level back to JSON
- Validates common gameplay issues such as missing spawn cells, open borders, and disconnected traversable areas
## Level Sources
- Preferred source: `assets/Rat/level.dat`
+419
View File
@@ -0,0 +1,419 @@
# regenerate_background() Analysis And Refactor Plan
## Scope
This document analyzes `Graphics.regenerate_background()` and proposes a staged refactor plan.
Relevant code paths:
- `engine/graphics.py#L146` `draw_maze()` lazily triggers background generation.
- `engine/graphics.py#L155` `draw_cave_foreground()` consumes cave overlay metadata produced during regeneration.
- `engine/graphics.py#L175` `regenerate_background()` builds the static background texture and cave overlay placements.
- `engine/graphics.py#L311` `add_blood_stain()` confirms that blood is intentionally excluded from the background texture and rendered as a separate overlay.
- `engine/sdl2.py#L98` `create_texture()` composites surface tiles into one SDL texture.
- `engine/sdl2.py#L118` `load_image()` explains why the code keeps both surfaces and textures for the same themed assets.
- `engine/maze.py#L13-L15` define `MAP_EMPTY`, `MAP_WALL`, and `MAP_TUNNEL`.
- `rats.py#L79`, `rats.py#L117-L121`, and `rats.py#L163-L165` show where background state is invalidated.
- `rats.py#L335` shows cave foreground rendering happens after the background draw and before units are drawn.
## What The Method Actually Does
`regenerate_background()` is doing more than the name suggests. It is not only “regenerating a background”; it is handling five separate concerns in one place:
1. It walks the logical map cell by cell.
2. It analyzes neighborhood topology around each wall or tunnel cell.
3. It chooses visual variants, including random grass and flower decoration.
4. It builds cave foreground overlay metadata for later explosion-aware rendering.
5. It commits the accumulated surfaces into a single SDL background texture.
That makes it both a planner and a renderer.
## Current Inputs, Outputs, And Side Effects
### Inputs read from `self`
- `self.map.tiles`, `self.map.width`, `self.map.height`
- `self.cell_size`
- `self.grasses`, `self.grass_textures`
- `self.flowers`, `self.flower_textures`
- `self.edges`, `self.corners`, `self.inner_corners`
- `self.caves`
- `self.render_engine`
### Derived helpers inside the method
- `occupied(x, y)` treats every non-empty cell as occupied, so both walls and tunnels count as solid neighbors for topology decisions.
- `is_tunnel(x, y)` is used only for the flower suppression logic in the bottom-right quadrant.
- `draw(...)` appends background surface tiles.
- `draw_cave(...)` appends cave overlay tuples in the format consumed later by `draw_cave_foreground()`.
- `random_wall()`, `random_wall_texture()`, `random_flower()`, `random_flower_texture()` embed random selection directly in the traversal logic.
### Outputs and side effects
- Resets `self.cave_foreground_tiles`
- Builds a local `texture_tiles` list
- Sets `self.background_texture`
- Does not return a value
This means the method is hard to test in isolation because the real output is split across mutable instance state and SDL object creation.
## Functional Walkthrough
### 1. Initialization
The method creates:
- `texture_tiles`: a list of `(surface, x, y)` tuples for the static background
- `self.cave_foreground_tiles`: a list of `(cell_x, cell_y, direction, surface, x, y)` tuples for overlay rendering
- `half_cell`: used to place quarter-cell tiles at 20 px offsets when `cell_size` is 40
This immediately shows a hidden design choice: one map cell can emit up to four quarter tiles rather than a single full-tile sprite.
### 2. Cell iteration
The outer loop traverses every cell of `self.map.tiles`.
- `MAP_EMPTY`: skipped completely
- `MAP_WALL`: potentially emits several quarter tiles
- `MAP_TUNNEL`: emits cave overlays and sometimes grass filler tiles
### 3. Wall rendering logic
For `MAP_WALL`, the method evaluates the four quadrants independently.
#### Top-left quadrant
If the north-west corner is exposed, it chooses among:
- `inner_corners["WN"]`
- `edges["W"]`
- `edges["N"]`
- `corners["NW"]`
based on whether the north and west neighbors are occupied.
#### Bottom-right quadrant
This is the densest branch. It checks south, east, and south-east occupancy.
- If all three are occupied, it usually draws a random grass tile.
- With a 10% chance, it draws a flower instead, but only if the cell is not near the border and none of the neighboring cells involved are tunnels.
- If only south or east are occupied, it chooses `inner_corners["ES"]`, `edges["E"]`, or `edges["S"]`.
- Otherwise it uses `corners["SE"]`.
This branch mixes topology, decoration policy, border constraints, and tunnel suppression all in one nested block.
#### Top-right quadrant
Mirrors the top-left logic using north and east occupancy:
- `inner_corners["EN"]`
- `edges["E"]`
- `edges["N"]`
- `corners["NE"]`
#### Bottom-left quadrant
Mirrors the same pattern using south and west occupancy:
- `inner_corners["WS"]`
- `edges["W"]`
- `edges["S"]`
- `corners["SW"]`
### 4. Tunnel rendering logic
For `MAP_TUNNEL`, the method checks `above`, `below`, `left`, and `right` occupancy and chooses cave overlay sprites.
Observed behavior:
- If there is no occupied tile above, it always draws a grass filler in the bottom-right quarter and uses the `UP` cave sprite.
- If there is an occupied tile above but not below, it uses the `DOWN` cave sprite.
- If both above and below are occupied and the left side is blocked, it may use a full-quarter wall/flower texture in the cave list.
- If both above and below are occupied and the left side is open, it draws a grass filler plus the `LEFT` cave sprite.
- If above and below are occupied, left is blocked, and right is open, it uses the `RIGHT` cave sprite.
This logic appears tuned to the current level topology and asset set rather than representing a complete, explicit rule system for all tunnel neighbor combinations.
### 5. Commit phase
After traversal, the method calls `render_engine.create_texture(texture_tiles, fill_color=(128, 128, 128))` to compose one static SDL texture for the entire maze background.
This is the correct optimization boundary for the current architecture, but it also means SDL concerns leak directly into the generation logic.
## Why The Method Feels Complex
The complexity is not only “too many lines”. It comes from multiple kinds of coupling.
### 1. Mixed responsibilities
The method mixes:
- map analysis
- rule selection
- random decoration
- cave overlay planning
- final rendering commit
Each of these changes for different reasons, so they should not live in the same function.
### 2. Repeated neighborhood queries
Neighbor checks like `occupied(x, y - 1)` and `occupied(x + 1, y)` are recomputed many times, often inside overlapping branches. That makes the code noisy and increases the chance of introducing asymmetric bugs during edits.
### 3. Hidden representation mismatch
Background composition uses SDL surfaces, while cave overlays use textures. That is why the code has parallel helpers like `random_wall()` and `random_wall_texture()`. The behavior is valid, but the representation split is leaking into every branch.
### 4. Randomness is embedded in rule logic
The function directly calls global `random` during traversal. That makes visual behavior hard to snapshot-test or compare before and after a refactor.
### 5. Side effects are scattered across the class lifecycle
Invalidation is controlled elsewhere in `rats.py`, where the code manually clears:
- `self.background_texture`
- `self.blood_layer_sprites`
- `self.cave_foreground_tiles`
This is correct today, but it creates a fragile contract between game flow code and rendering code.
### 6. Tunnel rules are implicit
The tunnel branch contains nested assumptions that are hard to verify by inspection. It is not obvious whether the logic is exhaustive, map-specific, or intentionally asymmetric.
## Important Invariants To Preserve
Any refactor must keep these behaviors unless you explicitly choose to change them:
1. Blood stains remain outside the static background texture.
2. `draw_cave_foreground()` must still be able to swap cave sprites for explosion sprites at runtime.
3. Quarter-tile placement and offsets must remain visually identical.
4. Random flower placement must preserve the current frequency and tunnel/border exclusions, or the change must be documented as a visual redesign.
5. Theme asset selection must keep using surfaces for background composition and textures for runtime overlays unless the render-engine API changes.
## Refactor Goals
The target should be:
- easier to read
- behaviorally stable
- testable without SDL
- explicit about map-topology rules
- easy to extend with new wall or tunnel tile rules
## Recommended Refactor Direction
The safest path is not a full rewrite. It is a staged extraction toward a pure planning layer.
### Stage 1: Name The Concepts
Extract small private helpers without changing data structures yet.
Suggested helpers:
- `_is_occupied(x, y)`
- `_is_tunnel(x, y)`
- `_make_cell_context(x, y)`
- `_append_background_tile(surface, x, y, texture_tiles)`
- `_append_cave_tile(surface, x, y, direction)`
- `_choose_wall_fill(x, y, allow_flower)`
This alone will remove repeated neighbor reads and make the current logic easier to reason about.
### Stage 2: Introduce A Pure Planning Model
Create lightweight data containers, for example:
```python
from dataclasses import dataclass
@dataclass(frozen=True)
class TilePlacement:
surface: object
x: int
y: int
@dataclass(frozen=True)
class CavePlacement:
cell_x: int
cell_y: int
direction: str | None
sprite: object
x: int
y: int
@dataclass(frozen=True)
class CellContext:
x: int
y: int
cell: int
north: bool
south: bool
east: bool
west: bool
north_west: bool
north_east: bool
south_west: bool
south_east: bool
```
Then split the method into:
- `_build_background_plan()`
- `_plan_wall_cell(context, plan)`
- `_plan_tunnel_cell(context, plan)`
- `_commit_background_plan(plan)`
The important shift is this: planning should produce plain Python data first, and SDL texture creation should happen only in the commit step.
### Stage 3: Replace Nested Branches With Rule Helpers
The wall logic is currently “four quadrants, each with a small rule tree”. Keep that structure, but make it explicit.
Suggested helpers:
- `_plan_wall_nw(context, px, py, plan)`
- `_plan_wall_ne(context, px, py, half_cell, plan)`
- `_plan_wall_sw(context, px, py, half_cell, plan)`
- `_plan_wall_se(context, px, py, half_cell, plan)`
This sounds verbose, but it is much easier to review because each helper owns one visual quadrant and one set of rules.
### Stage 4: Isolate Decoration Policy
The flower rule is currently buried inside the `SE` branch. Extract it into a dedicated function such as:
```python
def _should_place_flower(self, x, y, context) -> bool:
...
```
That function should own:
- the 10% probability
- border exclusions
- tunnel exclusions
This makes visual tuning possible without reopening the topology logic.
### Stage 5: Make Tunnel Rules Explicit
Tunnel behavior needs a named rule function with documented cases.
For example:
- `_classify_tunnel(context) -> TunnelPattern`
- `_plan_tunnel_pattern(pattern, px, py, plan)`
Even if the final logic stays the same, naming the tunnel patterns will expose whether the code is intentionally map-specific or accidentally incomplete.
### Stage 6: Centralize Invalidation
Introduce one method such as:
```python
def invalidate_background(self):
self.background_texture = None
self.cave_foreground_tiles.clear()
```
Then use that method from lifecycle points in `rats.py`.
This reduces the chance of future bugs where one part of the cached rendering state is reset and another is forgotten.
## Suggested Final Shape
The long-term shape can stay inside `Graphics` and still be much cleaner:
```python
def regenerate_background(self):
plan = self._build_background_plan()
self._commit_background_plan(plan)
def _build_background_plan(self):
...
def _plan_wall_cell(self, context, plan):
...
def _plan_tunnel_cell(self, context, plan):
...
def _commit_background_plan(self, plan):
self.cave_foreground_tiles = plan.cave_tiles
self.background_texture = self.render_engine.create_texture(
plan.background_tiles,
fill_color=(128, 128, 128),
)
```
This would preserve the current class boundaries while making the core algorithm testable.
## Test Strategy Before Refactoring
Because the function is visual and randomized, refactoring without a guardrail is risky.
Recommended safety steps:
1. Introduce a seeded RNG path so map generation can be deterministic during tests.
2. Add a small test map fixture that exercises walls, corners, borders, and tunnels.
3. Snapshot the produced tile plan, not the SDL texture object.
4. Verify cave overlay tuples are identical before and after the extraction.
5. Add a smoke test for `draw_cave_foreground()` with an explosion unit to ensure cave sprite replacement still works.
## Proposed Implementation Order
### Phase 0: Freeze Current Behavior
- Add a deterministic RNG entry point or injectable random source.
- Capture the current background plan for one or two representative maps.
### Phase 1: Extract Context And Emit Helpers
- Remove repeated `occupied(...)` calls.
- Keep current tuple outputs and current SDL commit behavior.
### Phase 2: Split Wall And Tunnel Planning
- Move wall rules into quadrant helpers.
- Move tunnel rules into a dedicated planner.
### Phase 3: Introduce A `BackgroundPlan`
- Return plain data from planning.
- Keep SDL texture creation in one place.
### Phase 4: Centralize Cache Invalidation
- Replace direct state resets with a single background invalidation method.
### Phase 5: Optional Optimization Pass
- Consider caching immutable plans by `(level_index, theme_index)` if needed.
- Consider precomputing per-cell contexts if profiling shows the planner is still hot.
## Refactor Risks And Questions
These should be clarified before implementation:
1. Are tunnel patterns guaranteed by the level data, or should the code become exhaustive for arbitrary maps?
2. Is `occupied()` intentionally treating tunnels as “solid” for wall topology, or is that only a rendering shortcut?
3. Is the flower placement rule part of the visual identity, or can it be simplified?
4. Do we want to keep both surfaces and textures in the theme cache, or would a render-engine API change be acceptable later?
## Recommended First Refactor PR
The lowest-risk first PR would do only this:
1. Extract `CellContext` creation.
2. Extract the four wall-quadrant planners.
3. Extract tunnel planning into one helper.
4. Leave the tuple formats and SDL commit step unchanged.
That PR would reduce complexity sharply while keeping the visual output almost certainly identical.
## Summary
`regenerate_background()` is complex because it is simultaneously a topology analyzer, decoration policy engine, cave overlay planner, and SDL background composer. The safest refactor is to separate planning from rendering, then isolate wall rules, tunnel rules, and decoration policy into named helpers with deterministic test coverage.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More