Merge remote-tracking branch 'origin/dev' into dev-attempt-01

This commit is contained in:
Oleksandr Bezdieniezhnykh
2025-12-03 23:17:26 +02:00
360 changed files with 3883 additions and 102 deletions
@@ -1,14 +1,14 @@
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md.md`. `@_docs/00_problem/restrictions.md.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Role ## Role
You are a professional software architect You are a professional software architect
@@ -1,14 +1,14 @@
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md.md`. `@_docs/00_problem/restrictions.md.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Role ## Role
You are a professional software architect You are a professional software architect
@@ -1,17 +1,17 @@
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md.md`. `@_docs/00_problem/restrictions.md.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Existing solution draft: ## Existing solution draft:
`@docs/01_solution/solution_draft.md` `@_docs/01_solution/solution_draft.md`
## Role ## Role
You are a professional software architect You are a professional software architect
@@ -1,19 +1,19 @@
# decompose # decompose
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md`. `@_docs/00_problem/restrictions.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Existing solution: ## Existing solution:
`@docs/01_solution/solution_draft.md` `@_docs/01_solution/solution_draft.md`
## Role ## Role
You are a professional software architect You are a professional software architect
@@ -27,7 +27,7 @@
- When you've got full understanding of how exactly each component will interact with each other, create components - When you've got full understanding of how exactly each component will interact with each other, create components
## Output ## Output
- Store description of each component to the file `docs/02_components/[##]_[component_name]/[##]._component_[component_name].md` with the next structure: - Store description of each component to the file `_docs/02_components/[##]_[component_name]/[##]._component_[component_name].md` with the next structure:
- Component Name - Component Name
- Detailed description - Detailed description
- API methods, for each method: - API methods, for each method:
@@ -40,7 +40,7 @@
- Test cases for the method - Test cases for the method
- Integration tests for the component if needed. - Integration tests for the component if needed.
- Non-functional tests for the component if needed. - Non-functional tests for the component if needed.
- Store Extensions and Helpers to support functionality across multiple components to a separate folder `docs/02_components/helpers`. - Store Extensions and Helpers to support functionality across multiple components to a separate folder `_docs/02_components/helpers`.
- Generate draw.io components diagram shows relations between components. - Generate draw.io components diagram shows relations between components.
## Notes ## Notes
@@ -4,7 +4,7 @@
- @00_problem - @00_problem
## Solution and decomposition ## Solution and decomposition
- @docs/01_solution/solution.md - @_docs/01_solution/solution.md
- @02_components - @02_components
## Role ## Role
@@ -1,19 +1,19 @@
# generate Jira Epics # generate Jira Epics
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md`. `@_docs/00_problem/restrictions.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Existing solution: ## Existing solution:
`@docs/01_solution/solution.md` `@_docs/01_solution/solution.md`
## Role ## Role
You are a world class product manager You are a world class product manager
@@ -1,19 +1,19 @@
# generate Tests # generate Tests
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is examples from the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md`. `@_docs/00_problem/restrictions.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Existing solution: ## Existing solution:
`@docs/01_solution/solution_draft.md` `@_docs/01_solution/solution_draft.md`
## Role ## Role
You are a professional Quality Assurance Engineer You are a professional Quality Assurance Engineer
@@ -23,7 +23,7 @@
- Cover all the the criteria with tests specs - Cover all the the criteria with tests specs
## Output ## Output
Store all tests specs to the files `docs/03_tests/[##]_[test_name]_spec.md` Store all tests specs to the files `_docs/03_tests/[##]_[test_name]_spec.md`
Types and structures of tests: Types and structures of tests:
- Integration tests - Integration tests
@@ -4,10 +4,10 @@
--component component_spec.md --component component_spec.md
## Existing solution: ## Existing solution:
`@docs/01_solution/solution.md` `@_docs/01_solution/solution.md`
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Role ## Role
You are a professional software architect You are a professional software architect
@@ -1,34 +1,35 @@
# Create initial structure # Create initial structure
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is an example of the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is an example of the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md`. `@_docs/00_problem/restrictions.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Existing solution spec: ## Existing solution spec:
`@docs/01_solution/solution.md` `@_docs/01_solution/solution.md`
## Components with Features specs ## Components with Features specs
`@docs/02_components` `@_docs/02_components`
## Role ## Role
You are a professional software architect and developer You are a professional software architect
## Task ## Task
- Read carefully all the component specs and features in the components folder: `@docs/02_components` - Read carefully all the component specs and features in the components folder: `@_docs/02_components`
- Investgate in internet what are the best way and tools to implement components and its features - Investgate in internet what are the best way and tools to implement components and its features
- Create initial structure: - Make a plan for the creating initial structure:
- DTOs - DTOs
- component's interfaces - component's interfaces
- empty implementations - empty implementations
- helpers - empty implementations or interfaces - helpers - empty implementations or interfaces
- add README.md, describe the project by @_docs/01_solution/solution.md
## Notes ## Notes
- Follow SOLID principles - Follow SOLID principles
@@ -4,28 +4,29 @@
component_folder component_folder
## The problem description ## The problem description
`@docs/00_problem/problem_description.md`. `@_docs/00_problem/problem_description.md`.
## Data samples ## Data samples
Located here: `@docs/00_problem/input_data`. They are for reference only, yet it is an example of the real data. Located here: `@_docs/00_problem/input_data`. They are for reference only, yet it is an example of the real data.
## Restrictions for the input data ## Restrictions for the input data
`@docs/00_problem/restrictions.md`. `@_docs/00_problem/restrictions.md`.
## Acceptance criteria for the output of the system: ## Acceptance criteria for the output of the system:
`@docs/00_problem/acceptance_criteria.md`. `@_docs/00_problem/acceptance_criteria.md`.
## Existing solution: ## Existing solution:
`@docs/01_solution/solution.md` `@_docs/01_solution/solution.md`
## Role ## Role
You are a professional software architect and developer You are a professional software architect and developer
## Task ## Task
- Read carefully component spec in the component_folder: `@docs/02_components/[##]_[component_name]/[##]._component_[component_name]` - Read carefully component spec in the component_folder: `@_docs/02_components/[##]_[component_name]/[##]._component_[component_name]`
- Read carefully all the component features in the component_folder: `@docs/02_components/[##]_[component_name]/[##].[##]_feature_[feature_name]` - Read carefully all the component features in the component_folder: `@_docs/02_components/[##]_[component_name]/[##].[##]_feature_[feature_name]`
- Investgate in internet what are the best way and tools to implement component and its features - Investgate in internet what are the best way and tools to implement component and its features
- During the investigation is is possible that found solutions required architecturally reorganization of the features. It is ok, propose that and if user agrees, include reorganization in the build feature plan. Also it is possible that interface could be changed or even removed or added new one. It is ok. - During the investigation is is possible that found solutions required architecturally reorganization of the features. It is ok, propose that and if user agrees, include reorganization in the build feature plan. Also it is possible that interface could be changed or even removed or added new one. It is ok.
- Analyze the existing codebase and get full context for the component's implementation
- Make sure feature is connected and communicated properly with other features and existing code - Make sure feature is connected and communicated properly with other features and existing code
- If component has dependency on another one, create temporary mock for the dependency - If component has dependency on another one, create temporary mock for the dependency
- Create unit tests from the Test cases description, run it and make sure the result is a success - Create unit tests from the Test cases description, run it and make sure the result is a success
+21
View File
@@ -0,0 +1,21 @@
# Database Configuration
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=gps_denied
DATABASE_USER=postgres
DATABASE_PASSWORD=
# API Configuration
API_HOST=0.0.0.0
API_PORT=8000
API_DEBUG=false
# Model Paths
SUPERPOINT_MODEL_PATH=models/superpoint.engine
LIGHTGLUE_MODEL_PATH=models/lightglue.engine
DINOV2_MODEL_PATH=models/dinov2.engine
LITESAM_MODEL_PATH=models/litesam.engine
# Satellite Data
SATELLITE_CACHE_DIR=satellite_cache
GOOGLE_MAPS_API_KEY=
+45
View File
@@ -1,2 +1,47 @@
.DS_Store .DS_Store
.idea .idea
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
.env
.venv
env/
venv/
ENV/
*.swp
*.swo
*~
*.log
*.sqlite
*.db
satellite_cache/
image_storage/
models/*.engine
models/*.onnx
.coverage
htmlcov/
.pytest_cache/
.mypy_cache/
+169
View File
@@ -0,0 +1,169 @@
# Azaion GPS Denied Desktop
**A Resilient, GNSS-Denied Geo-Localization System for Wing-Type UAVs**
GPS-denied UAV localization system using visual odometry and satellite imagery matching for fixed-wing UAVs operating over Eastern/Southern Ukraine.
## Overview
Azaion GPS-Denied addresses the challenge of autonomous navigation in GNSS-denied environments where traditional GPS is unavailable or unreliable. The system is designed for high-speed, fixed-wing UAVs operating without IMU data over visually homogeneous agricultural terrain.
### Key Features
- **Tri-Layer Localization**: Sequential tracking, global re-localization, and metric refinement
- **Sharp Turn Recovery**: Handles 0% image overlap during banking maneuvers
- **350m Outlier Tolerance**: Robust to large positional errors from airframe tilt
- **Real-time Processing**: <5 seconds per frame on RTX 2060/3070
- **Human-in-the-Loop**: Fallback to user input when automation fails
### Accuracy Targets
| Metric | Target |
|--------|--------|
| Photos within 50m error | 80% |
| Photos within 20m error | 60% |
| Processing time per frame | <5 seconds |
| Image registration rate | >95% |
## Architecture
### Processing Layers
| Layer | Purpose | Algorithm | Latency |
|-------|---------|-----------|---------|
| L1: Sequential Tracking | Frame-to-frame pose | SuperPoint + LightGlue | ~50-100ms |
| L2: Global Re-Localization | Recovery after track loss | DINOv2 + VLAD (AnyLoc) | ~200ms |
| L3: Metric Refinement | Precise GPS anchoring | LiteSAM | ~300-500ms |
### Core Components
- **Factor Graph Optimizer** (GTSAM): Fuses relative and absolute measurements
- **Atlas Multi-Map**: Route chunks as first-class entities for handling disconnected segments
- **Satellite Data Manager**: Google Maps tile caching with Web Mercator projection
## Tech Stack
- **Python**: 3.10+ (GTSAM compatibility)
- **Web Framework**: FastAPI (async)
- **Database**: PostgreSQL + SQLAlchemy ORM
- **ML Runtime**: TensorRT (primary), ONNX Runtime (fallback)
- **Graph Optimization**: GTSAM
- **Similarity Search**: Faiss
## Development Setup
### Prerequisites
- Python 3.10+
- PostgreSQL 14+
- NVIDIA GPU with CUDA support (RTX 2060/3070 recommended)
- [uv](https://docs.astral.sh/uv/) package manager
### Installation
1. **Clone the repository**
```bash
git clone <repository-url>
cd gps-denied
```
2. **Install uv** (if not already installed)
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
3. **Create virtual environment and install dependencies**
```bash
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -e ".[dev]"
```
4. **Install ML dependencies** (optional, requires CUDA)
```bash
uv pip install -e ".[ml]"
```
5. **Set up PostgreSQL database**
```bash
createdb gps_denied
```
6. **Configure environment**
```bash
cp .env.example .env
# Edit .env with your database credentials
```
### Running the Service
```bash
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
### API Documentation
Once running, access the interactive API docs at:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
### Running Tests
```bash
pytest
```
With coverage:
```bash
pytest --cov=. --cov-report=html
```
## API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/flights` | Create new flight |
| GET | `/api/v1/flights/{id}` | Get flight details |
| GET | `/api/v1/flights/{id}/status` | Get processing status |
| POST | `/api/v1/flights/{id}/batches` | Upload image batch |
| POST | `/api/v1/flights/{id}/user-fix` | Submit user GPS anchor |
| GET | `/api/v1/stream/{id}` | SSE stream for real-time results |
## Project Structure
```
gps-denied/
├── main.py # FastAPI application entry point
├── pyproject.toml # Project dependencies
├── api/ # REST API routes
│ ├── routes/
│ │ ├── flights.py # Flight management endpoints
│ │ ├── images.py # Image upload endpoints
│ │ └── stream.py # SSE streaming
│ └── dependencies.py # Dependency injection
├── components/ # Core processing components
│ ├── flight_api/ # API layer component
│ ├── flight_processing_engine/
│ ├── sequential_visual_odometry/
│ ├── global_place_recognition/
│ ├── metric_refinement/
│ ├── factor_graph_optimizer/
│ ├── satellite_data_manager/
│ └── ...
├── models/ # Pydantic DTOs
│ ├── core/ # GPS, Camera, Pose models
│ ├── flight/ # Flight, Waypoint models
│ ├── processing/ # VO, Matching results
│ ├── chunks/ # Route chunk models
│ └── ...
├── helpers/ # Utility functions
├── db/ # Database layer
│ ├── models.py # SQLAlchemy models
│ └── connection.py # Async database connection
└── _docs/ # Documentation
```
## License
Proprietary - All rights reserved

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 4.8 MiB

After

Width:  |  Height:  |  Size: 4.8 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 8.1 MiB

After

Width:  |  Height:  |  Size: 8.1 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 961 KiB

After

Width:  |  Height:  |  Size: 961 KiB

Before

Width:  |  Height:  |  Size: 985 KiB

After

Width:  |  Height:  |  Size: 985 KiB

Before

Width:  |  Height:  |  Size: 990 KiB

After

Width:  |  Height:  |  Size: 990 KiB

Before

Width:  |  Height:  |  Size: 922 KiB

After

Width:  |  Height:  |  Size: 922 KiB

Before

Width:  |  Height:  |  Size: 947 KiB

After

Width:  |  Height:  |  Size: 947 KiB

Before

Width:  |  Height:  |  Size: 786 KiB

After

Width:  |  Height:  |  Size: 786 KiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1010 KiB

After

Width:  |  Height:  |  Size: 1010 KiB

Before

Width:  |  Height:  |  Size: 959 KiB

After

Width:  |  Height:  |  Size: 959 KiB

Before

Width:  |  Height:  |  Size: 947 KiB

After

Width:  |  Height:  |  Size: 947 KiB

Before

Width:  |  Height:  |  Size: 957 KiB

After

Width:  |  Height:  |  Size: 957 KiB

Before

Width:  |  Height:  |  Size: 1005 KiB

After

Width:  |  Height:  |  Size: 1005 KiB

Before

Width:  |  Height:  |  Size: 971 KiB

After

Width:  |  Height:  |  Size: 971 KiB

Before

Width:  |  Height:  |  Size: 891 KiB

After

Width:  |  Height:  |  Size: 891 KiB

Before

Width:  |  Height:  |  Size: 992 KiB

After

Width:  |  Height:  |  Size: 992 KiB

Before

Width:  |  Height:  |  Size: 999 KiB

After

Width:  |  Height:  |  Size: 999 KiB

Before

Width:  |  Height:  |  Size: 961 KiB

After

Width:  |  Height:  |  Size: 961 KiB

Before

Width:  |  Height:  |  Size: 898 KiB

After

Width:  |  Height:  |  Size: 898 KiB

Before

Width:  |  Height:  |  Size: 747 KiB

After

Width:  |  Height:  |  Size: 747 KiB

Before

Width:  |  Height:  |  Size: 874 KiB

After

Width:  |  Height:  |  Size: 874 KiB

Before

Width:  |  Height:  |  Size: 1003 KiB

After

Width:  |  Height:  |  Size: 1003 KiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 928 KiB

After

Width:  |  Height:  |  Size: 928 KiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1004 KiB

After

Width:  |  Height:  |  Size: 1004 KiB

Before

Width:  |  Height:  |  Size: 790 KiB

After

Width:  |  Height:  |  Size: 790 KiB

Before

Width:  |  Height:  |  Size: 963 KiB

After

Width:  |  Height:  |  Size: 963 KiB

Before

Width:  |  Height:  |  Size: 980 KiB

After

Width:  |  Height:  |  Size: 980 KiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 981 KiB

After

Width:  |  Height:  |  Size: 981 KiB

Before

Width:  |  Height:  |  Size: 1022 KiB

After

Width:  |  Height:  |  Size: 1022 KiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 992 KiB

After

Width:  |  Height:  |  Size: 992 KiB

Before

Width:  |  Height:  |  Size: 965 KiB

After

Width:  |  Height:  |  Size: 965 KiB

Before

Width:  |  Height:  |  Size: 912 KiB

After

Width:  |  Height:  |  Size: 912 KiB

Before

Width:  |  Height:  |  Size: 1019 KiB

After

Width:  |  Height:  |  Size: 1019 KiB

Before

Width:  |  Height:  |  Size: 997 KiB

After

Width:  |  Height:  |  Size: 997 KiB

Before

Width:  |  Height:  |  Size: 767 KiB

After

Width:  |  Height:  |  Size: 767 KiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Before

Width:  |  Height:  |  Size: 892 KiB

After

Width:  |  Height:  |  Size: 892 KiB

Before

Width:  |  Height:  |  Size: 998 KiB

After

Width:  |  Height:  |  Size: 998 KiB

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