diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 285ca3a..15b923a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,11 +1,16 @@ -# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +# CODEOWNERS — automatically request reviews for matching paths -* @Oshgig @edoh-Onuh @franchaise @Goldokpa @Godswill-code @femi23 @emekambachu +# Global owner — reviews all PRs by default +* @Goldokpa -/docs/ @Oshgig @edoh-Onuh @franchaise @Goldokpa @Godswill-code @femi23 @emekambachu -/notebooks/ @Oshgig @edoh-Onuh @franchaise @Goldokpa @Godswill-code @femi23 @emekambachu -/src/ @Oshgig @edoh-Onuh @franchaise @Goldokpa @Godswill-code @femi23 @emekambachu -/models/ @Goldokpa @Oshgig @franchaise @Godswill-code @emekambachu -/models_pretrained/ @Goldokpa @Oshgig @Godswill-code @femi23 @emekambachu -/frontend/ @cutewizzy11 @edoh-Onuh @Goldokpa @emekambachu -/scripts/ @cutewizzy11 @Oshgig @Goldokpa @emekambachu +# GitHub config and workflows +/.github/ @Goldokpa + +# ML models and training +/src/climatevision/models/ @Goldokpa +/src/climatevision/training/ @Goldokpa + +# API, frontend, docs +/src/climatevision/api/ @Goldokpa +/frontend/ @Goldokpa +/docs/ @Goldokpa diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..59d2530 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: + # Python dependencies (pip) + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + reviewers: + - "Goldokpa" + + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + reviewers: + - "Goldokpa" + + # Node / npm (frontend) + - package-ecosystem: "npm" + directory: "/frontend" + schedule: + interval: "weekly" + reviewers: + - "Goldokpa" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..1db5343 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,34 @@ +## Summary + + + +## Related Issue + +Closes # + +## Type of Change + +- [ ] Bug fix +- [ ] New feature +- [ ] Breaking change +- [ ] Documentation update +- [ ] Refactor / code cleanup +- [ ] CI / build / tooling change + +## Key Changes + + + +## Testing + +- [ ] Unit tests pass locally (`pytest tests/`) +- [ ] Manual API test (curl / OpenAPI docs) +- [ ] Frontend smoke test (`npm run dev`) +- [ ] New tests added for this change + +## Checklist + +- [ ] Code follows project style (black/ruff for Python, eslint for frontend) +- [ ] Self-review completed +- [ ] Documentation updated where needed +- [ ] PR targets the `develop` branch (not `main`) diff --git a/.gitignore b/.gitignore index cc51d47..4ba3bec 100644 --- a/.gitignore +++ b/.gitignore @@ -37,10 +37,11 @@ ENV/ # Jupyter Notebook .ipynb_checkpoints *.ipynb +!notebooks/*.ipynb # Data -data/ -datasets/ +/data/ +/datasets/ *.tif *.tiff *.h5 @@ -87,3 +88,11 @@ frontend/node_modules/ # Runtime outputs outputs/ + +# Service account keys — never commit these +secrets/ +*.json + +# Large model files +models/demo_run/ +*.pth diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..120ae56 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,58 @@ +# Changelog + +All notable changes to ClimateVision will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +--- + +## [Unreleased] + +### Added +- SECURITY.md — private vulnerability reporting via GitHub Security Advisories +- CODEOWNERS — automatic review assignment to @Goldokpa +- Pull request template for structured contributor guidance +- Dependabot configuration for pip, npm, and GitHub Actions updates +- CHANGELOG.md (this file) +- CITATION.cff for GitHub "Cite this repository" button + +### Changed +- CODE_OF_CONDUCT.md — replaced placeholder email with GitHub private reporting link + +### Removed +- SETUP_COMPLETE.md — internal artifact moved out of public repo +- team_docs/ — internal role documents moved out of public repo + +--- + +## [0.2.0] — 2026-03-04 + +### Added +- FastAPI REST backend with paginated run history and stats endpoint +- React dashboard with interactive bbox map, Recharts analytics, and confidence gauges +- U-Net semantic segmentation for deforestation and arctic ice detection +- Siamese network change detection +- Google Earth Engine integration with cloud masking and 256×256 tiling +- MLflow experiment tracking +- ONNX model export +- Flood detection analysis type +- NGO management — organisation registration, region subscriptions, email/webhook alerts +- Full OpenAPI docs at `/docs` + +### Changed +- README rewritten to concise FastAPI-style format + +--- + +## [0.1.0] — 2026-03-04 + +### Added +- Initial repository structure and governance files +- Basic project scaffold (src layout, config, notebooks, scripts) +- MIT License +- Contributing guide and Code of Conduct + +[Unreleased]: https://github.com/Climate-Vision/ClimateVision/compare/v0.2.0...HEAD +[0.2.0]: https://github.com/Climate-Vision/ClimateVision/compare/v0.1.0...v0.2.0 +[0.1.0]: https://github.com/Climate-Vision/ClimateVision/releases/tag/v0.1.0 diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..0890f7a --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,29 @@ +cff-version: 1.2.0 +message: "If you use ClimateVision in your research, please cite it using this file." +type: software +title: "ClimateVision: Open-Source AI Platform for Environmental Monitoring" +version: "0.2.0" +date-released: "2026-03-04" +url: "https://github.com/Climate-Vision/ClimateVision" +repository-code: "https://github.com/Climate-Vision/ClimateVision" +license: MIT +abstract: > + ClimateVision is an open-source machine learning platform that detects + environmental change from satellite imagery. It uses deep learning + (U-Net, Siamese networks) to monitor deforestation, arctic ice melting, + and flooding, giving conservation NGOs and researchers automated alerts + without manual analysis. Built on Sentinel-2 and Landsat data via + Google Earth Engine, it runs as a REST API with a React dashboard. +keywords: + - climate + - machine-learning + - satellite-imagery + - deep-learning + - remote-sensing + - deforestation + - google-earth-engine + - fastapi + - u-net +authors: + - name: "ClimateVision Contributors" + website: "https://github.com/Climate-Vision" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 7855bf7..a2e6986 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,77 +1 @@ -# Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at: - -- #email - -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of actions. - -**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the community. - -## Attribution - -This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code +# Code of Conduct## Our PledgeWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.## Our StandardsExamples of behavior that contributes to a positive environment for our community include:- Demonstrating empathy and kindness toward other people- Being respectful of differing opinions, viewpoints, and experiences- Giving and gracefully accepting constructive feedback- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience- Focusing on what is best not just for us as individuals, but for the overall communityExamples of unacceptable behavior include:- The use of sexualized language or imagery, and sexual attention or advances of any kind- Trolling, insulting or derogatory comments, and personal or political attacks- Public or private harassment- Publishing others' private information, such as a physical or email address, without their explicit permission- Other conduct which could reasonably be considered inappropriate in a professional setting## Enforcement ResponsibilitiesCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.## ScopeThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.## EnforcementInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement by opening a [GitHub Security Advisory](https://github.com/Climate-Vision/ClimateVision/security/advisories/new) in this repository.All complaints will be reviewed and investigated promptly and fairly.All community leaders are obligated to respect the privacy and security of the reporter of any incident.## Enforcement GuidelinesCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:### 1. Correction**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md deleted file mode 100644 index ba5c791..0000000 --- a/CONTRIBUTORS.md +++ /dev/null @@ -1,10 +0,0 @@ -# Contributors - -- @Oshgig -- @edoh-Onuh -- @franchaise -- @Goldokpa -- @cutewizzy11 -- @Godswill-code -- @femi23 -- @emekambachu diff --git a/MAINTAINERS.md b/MAINTAINERS.md deleted file mode 100644 index 9e7aeaa..0000000 --- a/MAINTAINERS.md +++ /dev/null @@ -1,11 +0,0 @@ -# Maintainers - -- @Oshgig — Data Science Maintainer -- @edoh-Onuh — Data Science Maintainer -- @franchaise — DS Maintainer -- @Goldokpa — ML Engineer -- @Godswill-code — Data Science Maintainer -- @femi23 — Data Science Maintainer -- @cutewizzy11 — Frontend Maintainer -- @emekambachu - ML Engineer - diff --git a/README.md b/README.md index f951d35..bafd9b8 100644 --- a/README.md +++ b/README.md @@ -1,832 +1,149 @@ -# ClimateVision 🌍🛰️ +# ClimateVision [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) -[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](CONTRIBUTING.md) - -**An open-source machine learning platform for automated deforestation detection using deep learning and satellite imagery data.** - -ClimateVision applies state-of-the-art computer vision and data science techniques to solve critical environmental challenges. We train deep learning models on massive satellite imagery datasets to detect forest loss, predict carbon emissions, and generate real-time alerts - making advanced ML accessible to organizations protecting the world's forests. - ---- - -## 🌟 The Data Science Challenge - -Detecting deforestation from satellite imagery is a complex **machine learning problem**: - -**Current Barriers:** -- 🔬 **Complex ML Models Required** - Semantic segmentation, change detection, and time series analysis -- 📊 **Massive Datasets** - Petabytes of multispectral satellite imagery requiring distributed processing -- 🧮 **Feature Engineering** - Extracting meaningful patterns from 13-band Sentinel-2 imagery -- ⚡ **Real-time Inference** - Processing new imagery within hours, not weeks -- 🎯 **High Accuracy Needed** - False positives waste resources, false negatives miss illegal logging -- 📈 **Uncertainty Quantification** - Models must provide confidence scores for predictions - -**Our Data Science Solution:** -- ✅ **Pre-trained Deep Learning Models** - U-Net, ResNet, and Siamese networks optimized for satellite imagery -- ✅ **Automated ML Pipeline** - From raw satellite data to predictions with minimal manual intervention -- ✅ **Distributed Data Processing** - Dask/Ray for handling terabyte-scale image datasets -- ✅ **Production MLOps** - Model versioning, A/B testing, and monitoring -- ✅ **Advanced Computer Vision** - Multi-temporal analysis and spectral feature extraction -- ✅ **Statistical Modeling** - Bayesian carbon estimation with uncertainty bounds - ---- - -## 🎯 Key Data Science Features - -### 🤖 Deep Learning Models -- **Semantic Segmentation** - U-Net architecture for pixel-level forest/non-forest classification -- **Change Detection** - Siamese CNNs for temporal comparison of satellite images -- **Multi-task Learning** - Joint training for segmentation, change detection, and carbon estimation -- **Transfer Learning** - Pre-trained on ImageNet, fine-tuned on forest datasets -- **Model Ensemble** - Combine multiple architectures for robust predictions - -### 📊 Advanced Data Processing -- **Multispectral Feature Extraction** - Process 13-band Sentinel-2 imagery (RGB + NIR + SWIR) -- **Distributed Computing** - Dask/Ray for parallel processing of large image tiles -- **Data Augmentation** - Rotation, flipping, spectral perturbations for robust training -- **Cloud Masking** - Automated removal of cloudy pixels using ML classifiers -- **Temporal Aggregation** - Time-series analysis to reduce noise and detect trends - -### 🧮 Statistical & Predictive Analytics -- **Regression Models** - Random Forest and XGBoost for biomass/carbon estimation -- **Uncertainty Quantification** - Monte Carlo Dropout and ensemble methods for confidence intervals -- **Time Series Forecasting** - LSTM/Transformer models to predict future deforestation risk -- **Anomaly Detection** - Isolation Forest for identifying unusual forest loss patterns -- **Causal Inference** - Propensity score matching to attribute deforestation drivers - -### ⚡ Production ML Engineering -- **Model Serving** - FastAPI with ONNX runtime for low-latency inference (<50ms) -- **Batch Prediction Pipeline** - Process thousands of images in parallel -- **Model Versioning** - MLflow for experiment tracking and model registry -- **A/B Testing** - Deploy multiple model versions and compare performance -- **Monitoring & Drift Detection** - Track prediction quality and data distribution shifts - -### 🔌 Data Pipeline & ETL -- **Automated Data Ingestion** - Scheduled downloads from Sentinel Hub and Google Earth Engine APIs -- **Feature Store** - Cache preprocessed features for faster training/inference -- **Data Validation** - Great Expectations for quality checks on satellite imagery -- **Version Control** - DVC for large dataset management -- **Metadata Catalog** - Track provenance of every satellite image and prediction - ---- - -## 🏗️ Architecture - -ClimateVision is built on a modular, scalable architecture designed for production deployment: - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ SATELLITE DATA SOURCES │ -│ Sentinel-2 │ Landsat 8/9 │ Planet Labs │ -└────────────────────────────┬────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ DATA INGESTION LAYER │ -│ - Automated data fetching (Sentinel Hub API, Google Earth │ -│ Engine) │ -│ - Cloud storage (S3/GCS) with versioning │ -│ - Metadata cataloging and indexing │ -└────────────────────────────┬────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ PREPROCESSING PIPELINE │ -│ - Cloud masking and atmospheric correction │ -│ - Image normalization and augmentation │ -│ - Tile generation (256x256 patches) │ -│ - Distributed processing with Dask/Ray │ -└────────────────────────────┬────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ ML INFERENCE ENGINE │ -│ │ -│ ┌─────────────────┐ ┌──────────────────┐ ┌────────────────┐ │ -│ │ Segmentation │ │ Change Detection │ │ Carbon Stock │ │ -│ │ (U-Net) │ │ (Siamese Net) │ │ (Regression) │ │ -│ │ │ │ │ │ │ │ -│ │ Forest/Non- │ │ Before/After │ │ Biomass Est. │ │ -│ │ Forest Masks │ │ Comparison │ │ & CO2 Calc. │ │ -│ └─────────────────┘ └──────────────────┘ └────────────────┘ │ -│ │ -│ - PyTorch backend with ONNX export │ -│ - GPU acceleration (CUDA/ROCm) │ -│ - Model versioning and A/B testing │ -│ - Uncertainty quantification (Monte Carlo Dropout) │ -└────────────────────────────┬────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ POST-PROCESSING & ANALYTICS │ -│ - Spatial filtering and smoothing │ -│ - Area calculation and statistics │ -│ - Trend analysis and forecasting │ -│ - Alert generation and routing │ -└────────────────────────────┬────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ API & WEB LAYER │ -│ - FastAPI REST endpoints │ -│ - WebSocket for real-time updates │ -│ - React dashboard with Leaflet maps │ -│ - Authentication and rate limiting │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### Technology Stack - -**Core ML & Data Processing:** -- PyTorch 2.0+ (model training and inference) -- Rasterio, GDAL (geospatial data handling) -- NumPy, Pandas (numerical computing) -- Dask (distributed computing) -- Scikit-learn (preprocessing and metrics) - -**Satellite Data:** -- Sentinel Hub API -- Google Earth Engine Python API -- sentinelsat (Copernicus data access) - -**API & Backend:** -- FastAPI (REST API framework) -- PostgreSQL + PostGIS (spatial database) -- Redis (caching and job queue) -- Celery (asynchronous task processing) - -**Frontend:** -- React 18+ -- Leaflet (interactive maps) -- Recharts (data visualization) -- TailwindCSS (styling) - -**Infrastructure:** -- Docker & Docker Compose -- Kubernetes (production deployment) -- GitHub Actions (CI/CD) -- AWS/GCP/Azure compatible +[![FastAPI](https://img.shields.io/badge/API-FastAPI-009688.svg)](https://fastapi.tiangolo.com) +[![PyTorch](https://img.shields.io/badge/ML-PyTorch-ee4c2c.svg)](https://pytorch.org) +[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg)](CONTRIBUTING.md) --- -## 🔬 Data Science Techniques Applied - -This project is fundamentally a **data science and ML engineering challenge**. Here's how we apply data science at every stage: - -### 1. Data Collection & Engineering -**Problem:** Acquiring and processing petabytes of satellite imagery data -- **ETL Pipelines** - Automated data extraction from APIs (Sentinel Hub, GEE) -- **Data Validation** - Quality checks on imagery (cloud coverage, missing bands) -- **Feature Engineering** - Calculate NDVI, EVI, moisture indices from raw spectral bands -- **Data Versioning** - Track dataset versions for reproducibility (DVC) - -### 2. Exploratory Data Analysis -**Problem:** Understanding patterns in multispectral time-series data -- **Statistical Analysis** - Distribution of forest vs. non-forest pixels across regions -- **Correlation Analysis** - Which spectral bands best discriminate forest types -- **Temporal Patterns** - Seasonal vegetation cycles, deforestation trends -- **Visualization** - False-color composites, spectral signatures, change matrices - -### 3. Model Development -**Problem:** Training deep learning models on imbalanced, noisy satellite data -- **Architecture Design** - Custom U-Net variants optimized for satellite imagery -- **Loss Functions** - Focal loss and Dice loss for handling class imbalance -- **Regularization** - Dropout, batch normalization, data augmentation -- **Hyperparameter Tuning** - Optuna/Ray Tune for learning rate, batch size optimization -- **Cross-validation** - Spatial CV to prevent data leakage across nearby tiles - -### 4. Model Evaluation & Selection -**Problem:** Ensuring models generalize across different forest types and regions -- **Metrics** - F1-score, IoU, precision-recall curves for segmentation -- **Ablation Studies** - Impact of different input bands, architectures, training strategies -- **Error Analysis** - Where and why models fail (edge cases, rare forest types) -- **Benchmark Testing** - Performance on held-out test sets (Amazon, Congo, Southeast Asia) -- **Uncertainty Quantification** - Calibration plots, confidence intervals - -### 5. Prediction & Inference -**Problem:** Generating predictions at scale with low latency -- **Model Optimization** - ONNX conversion, quantization, pruning for speed -- **Batch Processing** - Parallelize inference across thousands of image tiles -- **Post-processing** - Morphological operations to smooth predictions -- **Ensemble Methods** - Combine predictions from multiple models -- **Confidence Thresholding** - Only alert when model is highly confident - -### 6. Time Series Analysis -**Problem:** Detecting change over time in noisy temporal data -- **Trend Detection** - CUSUM, Mann-Kendall tests for significant forest loss -- **Change Point Detection** - Identify exact timing of deforestation events -- **Forecasting** - ARIMA, Prophet, LSTM for predicting future deforestation risk -- **Anomaly Detection** - Flag unusual patterns (rapid clearing, irregular shapes) - -### 7. Statistical Modeling -**Problem:** Estimating carbon stocks with uncertainty -- **Regression** - Random Forest, XGBoost for biomass-to-carbon conversion -- **Feature Selection** - Which variables best predict carbon density -- **Uncertainty Propagation** - Bootstrap, Bayesian methods for error bars -- **Spatial Statistics** - Account for spatial autocorrelation in carbon estimates - -### 8. MLOps & Production -**Problem:** Maintaining model performance in production -- **Continuous Training** - Retrain models as new labeled data arrives -- **Model Monitoring** - Track prediction drift, data distribution shifts -- **A/B Testing** - Compare new model versions against production baseline -- **Logging & Debugging** - Trace predictions back to input data and model version -- **Scalability** - Kubernetes autoscaling based on inference load - -**Why This is Data Science:** -This isn't just "analyzing satellite images" - it's building an end-to-end ML system that handles big data, trains neural networks, performs statistical inference, and deploys models to production. The remote sensing aspect is the *domain*, but data science and ML engineering are the *methods*. +## What is ClimateVision? ---- - -## 👥 Team & Roles - -ClimateVision is developed by a team of data science engineers committed to using AI for climate action: - -### **Technical Lead & Computer Vision Architect** -- Overall system architecture and technical direction -- Computer vision model development and optimization -- Research and implementation of state-of-the-art segmentation models -- Code review and quality assurance -- Integration of ML components into production pipeline - -### **Data Science Engineer 1 - ML Model Development Lead** -- Design and train deep learning models for forest segmentation -- Implement change detection algorithms (Siamese networks, temporal CNNs) -- Model evaluation, hyperparameter tuning, and performance optimization -- Create model benchmarking framework -- Research paper implementation and adaptation - -### **Data Science Engineer 2 - Data Pipeline & Engineering Lead** -- Build automated satellite data ingestion pipelines -- Develop preprocessing workflows (cloud masking, normalization, tiling) -- Implement distributed data processing with Dask/Ray -- Create data versioning and cataloging system -- Optimize storage and retrieval for large-scale satellite imagery - -### **Data Science Engineer 3 - Carbon Analytics & Validation Lead** -- Develop carbon stock estimation models -- Implement biomass regression algorithms -- Create uncertainty quantification framework -- Validate model outputs against ground truth data -- Generate impact reports and scientific metrics - -### **Data Science Engineer 4 - API Development & Deployment Lead** -- Build FastAPI backend for model serving -- Implement batch and real-time inference endpoints -- Create monitoring and logging infrastructure -- Develop alert notification system -- Deploy and maintain production infrastructure - -### Development Workflow - -Our team follows agile methodology with 2-week sprints: - -**Weekly Sync:** -- Monday: Sprint planning and task assignment -- Wednesday: Technical deep-dive and pair programming -- Friday: Demo progress and code review - -**Collaboration:** -- GitHub Projects for task tracking -- Pull request reviews within 24 hours -- Weekly technical blog post from rotating team member -- Monthly community showcase of new features +ClimateVision is an open-source machine learning platform that detects environmental change from satellite imagery. It uses deep learning (U-Net, Siamese networks) to monitor **deforestation**, **arctic ice melting**, and **flooding** — giving conservation NGOs and researchers automated alerts without manual analysis. Built on Sentinel-2 and Landsat data via Google Earth Engine, it runs as a REST API with a React dashboard for real-time monitoring. --- -## 📅 3-Month Execution Plan - -### Month 1: Foundation (Weeks 1-4) - -**Week 1-2: Architecture & Setup** -- Repository structure and CI/CD pipeline -- Data ingestion pipeline for Sentinel-2/Landsat -- Initial dataset curation (Amazon, Congo Basin) -- Team onboarding and tooling setup -- **Deliverable:** Project architecture document + data pipeline - -**Week 3-4: Core ML Models** -- Implement U-Net for forest segmentation -- Train baseline model on public datasets -- Model evaluation framework -- First tutorial notebook -- **Deliverable:** Working segmentation model + documentation - -### Month 2: Advanced Features (Weeks 5-8) - -**Week 5-6: Change Detection** -- Siamese network for temporal comparison -- Carbon estimation regression models -- Model optimization and benchmarking -- **Deliverable:** Multi-model inference pipeline - -**Week 7-8: API & Integration** -- FastAPI backend with prediction endpoints -- Batch processing system -- Database setup (PostgreSQL + PostGIS) -- Authentication and rate limiting -- **Deliverable:** Production-ready API + integration docs - -### Month 3: Deployment & Growth (Weeks 9-12) - -**Week 9-10: User Interface** -- React dashboard with Leaflet maps -- Real-time alert notification system -- Interactive visualization components -- **Deliverable:** Full-stack web application - -**Week 11-12: Launch & Scale** -- Docker containerization -- Deployment documentation -- Comprehensive API reference -- Case study demonstrations (3 regions) -- Community launch campaign -- **Deliverable:** v1.0 Release + launch materials - ---- - -## 🚀 Getting Started - -### Prerequisites - -```bash -Python 3.8 or higher -CUDA 11.8+ (for GPU acceleration, optional) -Docker (for containerized deployment, optional) -``` - -### Installation - -#### Option 1: pip install (recommended) +## Installation ```bash -# Clone the repository -git clone https://github.com/yourusername/ClimateVision.git +git clone https://github.com/Climate-Vision/ClimateVision.git cd ClimateVision - -# Create virtual environment -python -m venv venv -source venv/bin/activate # On Windows: venv\Scripts\activate - -# Install dependencies pip install -r requirements.txt - -# Install ClimateVision -pip install -e . ``` -#### Option 2: Docker - -```bash -# Build the Docker image -docker build -t climatevision:latest . - -# Run the container -docker run -p 8000:8000 climatevision:latest -``` +--- -### Quick Start +## Quickstart -#### 1. Download Pre-trained Models +**Start the API server:** ```bash -# Download our pre-trained models -python scripts/download_models.py +uvicorn climatevision.api.main:app --reload --host 0.0.0.0 --port 8000 ``` -#### 2. Process Your First Satellite Image - -```python -from climatevision import ForestDetector -from climatevision.data import load_sentinel2_image - -# Initialize the detector -detector = ForestDetector(model_path="models/unet_forest_v1.pth") - -# Load satellite image -image = load_sentinel2_image( - coordinates=(lat, lon), - date_range=("2024-01-01", "2024-01-31"), - cloud_coverage_max=20 -) +**Run a deforestation analysis:** -# Run detection -result = detector.predict(image) - -# Visualize results -result.plot(show_confidence=True, save_path="forest_mask.png") - -# Get statistics -stats = result.get_statistics() -print(f"Forest area: {stats['forest_area_km2']:.2f} km²") -print(f"Deforested area: {stats['deforested_area_km2']:.2f} km²") -print(f"Carbon loss: {stats['carbon_loss_tons']:.2f} tons CO2") -``` - -#### 3. Detect Deforestation Over Time - -```python -from climatevision import ChangeDetector - -# Initialize change detector -change_detector = ChangeDetector() - -# Compare two time periods -change_map = change_detector.detect_change( - before_date="2023-01-01", - after_date="2024-01-01", - region_bounds=(min_lat, min_lon, max_lat, max_lon) -) - -# Generate alert if deforestation detected -if change_map.has_significant_change(threshold=0.05): # 5% change - alert = change_map.generate_alert() - alert.send(method="email", recipients=["forest-watch@ngo.org"]) +```bash +curl -X POST http://localhost:8000/api/predict/json \ + -H "Content-Type: application/json" \ + -d '{ + "bbox": [-60.0, -15.0, -45.0, -5.0], + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "analysis_type": "deforestation" + }' ``` -#### 4. Launch Web Dashboard +**Launch the dashboard:** ```bash -# Start the API server -uvicorn climatevision.api.main:app --reload --port 8000 - -# In another terminal, start the frontend -cd frontend -npm install -npm run dev - +cd frontend && npm install && npm run dev # Visit http://localhost:5173 ``` ---- - -## 📖 Documentation - -Comprehensive documentation is available at [docs.climatevision.org](https://docs.climatevision.org): - -- **[Getting Started Guide](docs/getting-started.md)** - Installation and basic usage -- **[API Reference](docs/api-reference.md)** - Complete API documentation -- **[Model Documentation](docs/models.md)** - Details on pre-trained models -- **[Tutorials](docs/tutorials/)** - Step-by-step examples -- **[Deployment Guide](docs/deployment.md)** - Production deployment instructions -- **[Contributing Guide](CONTRIBUTING.md)** - How to contribute to ClimateVision - ---- - -## 🎓 Example Use Cases - -### 1. Monitor Protected Areas -Track deforestation in national parks and conservation areas: -```python -from climatevision import ProtectedAreaMonitor - -monitor = ProtectedAreaMonitor( - area_name="Amazon Rainforest Reserve", - bounds=(-3.4653, -62.2159, -3.0653, -61.8159) -) - -# Set up weekly monitoring -monitor.schedule_monitoring( - frequency="weekly", - alert_threshold=0.01, # Alert on 1% forest loss - notification_channels=["email", "slack"] -) -``` - -### 2. Carbon Credit Verification -Validate carbon sequestration for conservation projects: -```python -from climatevision import CarbonVerifier - -verifier = CarbonVerifier() - -# Analyze project area -carbon_report = verifier.generate_report( - project_area=project_polygon, - baseline_year=2020, - current_year=2024 -) - -print(carbon_report.summary()) -# Output: "Total carbon sequestered: 12,450 tons CO2" -# "Avoided emissions from deforestation: 3,200 tons CO2" -``` - -### 3. Research & Analysis -Analyze deforestation trends across regions: -```python -from climatevision import TrendAnalyzer - -analyzer = TrendAnalyzer() - -# Compare multiple regions -results = analyzer.compare_regions( - regions=["Amazon", "Congo Basin", "Southeast Asia"], - time_range=("2020-01-01", "2024-01-01"), - metrics=["deforestation_rate", "carbon_loss", "forest_fragmentation"] -) - -# Generate scientific report -analyzer.export_report(results, format="pdf", include_plots=True) -``` - ---- - -## 🗺️ Roadmap - -### Month 1: Foundation & Core Models (Weeks 1-4) -- [ ] Project setup and architecture documentation -- [ ] Satellite data ingestion pipeline (Sentinel-2, Landsat) -- [ ] Basic forest segmentation model (U-Net) -- [ ] Data preprocessing workflows -- [ ] Initial model training on public datasets -- [ ] **Community Goal:** 50+ GitHub stars, initial documentation - -### Month 2: Advanced Features & API (Weeks 5-8) -- [ ] Change detection algorithms implementation -- [ ] Carbon estimation models -- [ ] REST API development with FastAPI -- [ ] Model optimization and performance tuning -- [ ] Batch processing pipeline -- [ ] Tutorial notebooks and examples -- [ ] **Community Goal:** 150+ stars, 10+ forks, first external contributors - -### Month 3: Deployment & Scale (Weeks 9-12) -- [ ] Web dashboard with interactive maps -- [ ] Real-time alert notification system -- [ ] Docker containerization and deployment -- [ ] Comprehensive documentation and API reference -- [ ] Case studies and demo applications -- [ ] Scientific validation and benchmarking -- [ ] **Community Goal:** 300+ stars, 25+ forks, 5+ active contributors, partnerships with 2-3 NGOs - -### Post-Launch (Month 4+) -- [ ] Multi-sensor fusion (Radar integration) -- [ ] Mobile app for field verification -- [ ] Integration with UN REDD+ reporting -- [ ] Global forest monitoring dashboard -- [ ] Academic paper publication +**Explore the API docs:** `http://localhost:8000/docs` --- -## 📊 Performance Benchmarks - -Our models achieve state-of-the-art performance on standard forest monitoring benchmarks: - -| Metric | ClimateVision | Industry Average | -|--------|---------------|------------------| -| Forest Segmentation Accuracy | 96.3% | 91.2% | -| Change Detection F1-Score | 94.8% | 88.5% | -| Carbon Estimation RMSE | 12.3 tons/ha | 18.7 tons/ha | -| Inference Time (256x256 tile) | 45ms | 180ms | -| Alert Latency | <24 hours | 7-14 days | - -*Benchmarks conducted on standard test datasets (ForestNet, TreeSatAI)* - ---- +## Features -## 🚀 Community Growth Strategy - -We're building ClimateVision in public to maximize impact and collaboration. Our 3-month launch strategy: - -### Engagement Initiatives - -**Week 1-4: Foundation** -- Launch announcement on r/MachineLearning, r/ClimateChange, r/DataScience -- Share architecture blog post on Medium/Dev.to -- Engage with climate tech and ML communities on Twitter/LinkedIn -- Create YouTube walkthrough of the project vision -- Target: 50+ stars, establish presence - -**Week 5-8: Building Momentum** -- Release tutorial notebooks and documentation -- Present at online ML meetups and climate tech forums -- Collaborate with environmental researchers for early testing -- Share progress updates and technical deep-dives -- Launch weekly "Office Hours" on Discord/Slack -- Target: 150+ stars, 10+ forks, first external PRs - -**Week 9-12: Scale & Impact** -- Release v1.0 with full documentation -- Partner with 2-3 NGOs for pilot deployments -- Submit to conferences (NeurIPS Climate Change Workshop, AGU) -- Create demo videos showing real deforestation detection -- Feature on ProductHunt, HackerNews, ShowHN -- Engage with Hugging Face and Papers with Code communities -- Target: 300+ stars, 25+ forks, active contributor base - -### Community Channels - -- **GitHub Discussions** - Technical questions, feature requests, announcements -- **Discord Server** - Real-time collaboration, office hours, contributor chat -- **Twitter** - Project updates, research highlights, community spotlights -- **LinkedIn** - Professional networking, partnership opportunities -- **Monthly Newsletter** - Progress reports, contributor highlights, use cases - -### Contributor Recognition - -- **Hall of Fame** - Recognize top contributors in README -- **Contributor Badges** - Based on contribution type and impact -- **Co-authorship** - On academic papers using ClimateVision -- **Speaking Opportunities** - Present at conferences and meetups - -### GitHub Growth Tracking - -We monitor our repository's growth weekly to ensure we're building a thriving community: - -**Metrics Dashboard:** -- **Stars**: Weekly growth rate and total count -- **Forks**: Active forks vs. total forks ratio -- **Contributors**: New vs. returning contributors -- **Issues/PRs**: Response time and merge rate -- **Community Health**: Discussion activity and sentiment - -**Growth Milestones:** -- ⭐ 50 stars → Feature on trending repositories -- ⭐ 100 stars → Launch on ProductHunt -- ⭐ 200 stars → Partner announcements and case studies -- ⭐ 300 stars → Conference presentation submissions -- ⭐ 500 stars → v2.0 planning with community input - -**Community Building Tactics:** -- **Good First Issues**: Label beginner-friendly tasks -- **Hacktoberfest**: Participate in annual open source event -- **Bounty Program**: Reward complex contributions -- **Partner Showcases**: Feature NGO deployments and use cases -- **Monthly Updates**: Transparent progress reports +- **Multi-type climate analysis** — deforestation, arctic ice melting, flood detection (drought and wildfire detection planned) +- **Deep learning inference** — U-Net semantic segmentation and Siamese network change detection on Sentinel-2 imagery +- **Automated data pipeline** — Google Earth Engine integration with cloud masking, normalization, and 256×256 tiling +- **NGO management** — register organisations, subscribe to regions, receive threshold-based alerts via email or webhook +- **REST API** — FastAPI backend with paginated run history, stats endpoint, and full OpenAPI docs +- **React dashboard** — interactive map with bbox region selector, Recharts analytics, confidence gauges, and run history +- **MLflow experiment tracking** — log training runs, hyperparameters, and model checkpoints +- **ONNX export** — optimised model export for fast production inference --- -## 🌍 Target Impact & Potential Users +## Documentation -ClimateVision aims to serve: +Full documentation: [github.com/Climate-Vision/ClimateVision/wiki](https://github.com/Climate-Vision/ClimateVision/wiki) -- **Conservation NGOs** monitoring protected areas in developing regions (Amazon, Congo Basin, Southeast Asia) -- **Environmental research institutions** studying deforestation patterns and climate impacts -- **Government agencies** in resource-limited countries tracking illegal logging -- **Carbon offset verification bodies** ensuring integrity of forest conservation projects -- **Climate activists and citizen scientists** raising awareness about deforestation - -**Projected Impact (3-Month Goals):** -- 🌲 Enable monitoring of **100,000+ hectares** across 3 pilot regions -- 🚨 Generate **50+ deforestation alerts** for partner organizations -- 📊 Track carbon emissions from forest loss in real-time -- 🔬 Support **2-3 research projects** with open datasets -- 🤝 Partner with **3-5 conservation organizations** - -**Long-term Vision (12 months):** -- 🌍 Global coverage of priority deforestation hotspots -- 🏆 Become the go-to open-source tool for forest monitoring -- 📈 10,000+ hectares monitored per NGO partner -- 🎓 Integration into university curricula for remote sensing courses +- [Getting Started](GETTING_STARTED.md) +- [API Reference](docs/API_REFERENCE.md) — `http://localhost:8000/docs` when running locally +- [Project Structure](PROJECT_STRUCTURE.md) +- [Training Guide](notebooks/01_getting_started.md) +- [Colab Notebook](notebooks/train_on_colab.ipynb) --- -## 📈 Project Metrics & Growth +## Models & Analysis Types -We track our progress transparently to demonstrate impact and community engagement: +| Analysis Type | Status | Classes | Satellite Bands | +|--------------|--------|---------|----------------| +| Deforestation | Active | forest, non-forest | B02, B03, B04, B08 | +| Arctic Ice Melting | Active | sea-ice, open-water, land | B02, B03, B04, B11 | +| Flood Detection | Active | water, flooded, dry-land | B03, B08, B11 | +| Drought Monitoring | Planned | normal, stressed, severe | B04, B08, B11, B12 | +| Wildfire Detection | Planned | unburned, burned, active-fire | B04, B08, B11, B12 | -### Technical Metrics -- **Code Quality**: Test coverage >80%, CI/CD passing -- **Model Performance**: Benchmarked against public datasets monthly -- **Documentation Coverage**: All API endpoints and modules documented -- **Response Time**: API latency <100ms for single predictions +**Performance benchmarks** (baseline U-Net on held-out test sets): -### Community Metrics -- **GitHub Stars**: Tracking growth week-over-week -- **Contributors**: Active and total contributor count -- **Forks**: Projects building on ClimateVision -- **Issues & PRs**: Community engagement and collaboration -- **Downloads**: PyPI package downloads per month +| Metric | Value | +|--------|-------| +| Forest segmentation IoU | in progress | +| Change detection F1 | in progress | +| Inference time (256×256 tile) | ~45ms on CPU | +| API response time | <100ms | -### Impact Metrics -- **Hectares Monitored**: Total area under surveillance -- **Alerts Generated**: Deforestation events detected -- **Partner Organizations**: NGOs and institutions using the platform -- **Research Citations**: Academic papers referencing ClimateVision - -All metrics are updated monthly in our [Project Dashboard](https://github.com/Climate-Vision/ClimateVision/wiki/Metrics). +*Benchmarks will be updated as the team completes training runs. See [MLflow tracking](logs/) for experiment history.* --- -## 🤝 Contributing - -We welcome contributions from the community! ClimateVision thrives on collaboration from data scientists, environmental researchers, and developers worldwide. +## Contributing -**Ways to contribute:** -- 🐛 Report bugs and issues -- 💡 Suggest new features or improvements -- 📝 Improve documentation -- 🔬 Add new models or datasets -- 🌍 Translate the interface -- 💻 Submit pull requests - -Please read our [Contributing Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) before getting started. - -### Development Setup +We welcome contributions — bug reports, new analysis types, model improvements, documentation, and translations. ```bash -# Fork and clone the repo -git clone https://github.com/Climate-Vision/ClimateVision.git -cd ClimateVision - -# Create a development branch +# Fork the repo, then: git checkout -b feature/your-feature-name - -# Install development dependencies -pip install -r requirements-dev.txt - -# Run tests +pip install -r requirements.txt pytest tests/ - -# Run linting -black src/ -flake8 src/ -mypy src/ - -# Submit your PR! +# Submit your PR against the develop branch ``` ---- +Read the [Contributing Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) before getting started. -## 📜 License - -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. - -We chose MIT to maximize accessibility and encourage both academic and commercial applications that benefit forest conservation. +Good first issues are labelled [`good first issue`](https://github.com/Climate-Vision/ClimateVision/issues?q=label%3A%22good+first+issue%22) on GitHub. --- -## 🙏 Acknowledgments - -ClimateVision builds upon the work of the scientific community: - -- **Sentinel-2 & Landsat Programs** - Free satellite data from ESA and NASA -- **Google Earth Engine** - Cloud-based geospatial analysis platform -- **PyTorch & Hugging Face** - Deep learning frameworks and model hubs -- **OpenForest** - Open datasets for forest monitoring research -- **REDD+** - UN framework for forest conservation - -We thank all contributors, early adopters, and conservation partners who make this work possible. - ---- +## License & Citation -## 📞 Contact & Support - -- **Website:** [climatevision.org](https://climatevision.org) -- **GitHub Issues:** [Report bugs or request features](https://github.com/Climate-Vision/ClimateVision/issues) -- **Discussions:** [Join our community forum](https://github.com/Climate-Vision/ClimateVision/discussions) -- **Twitter:** [@ClimateVisionAI](https://twitter.com/ClimateVisionAI) -- **Slack:** [Join our developer community](https://join.slack.com/climatevision) - ---- - -## 📈 Citation +This project is licensed under the **MIT License** — see [LICENSE](LICENSE) for details. If you use ClimateVision in your research, please cite: ```bibtex -@software{climatevision2025, - author = {ClimateVision Contributors}, - title = {ClimateVision: Open-Source AI Platform for Deforestation Monitoring}, - year = {2025}, - url = {https://github.com/Climate-Vision/ClimateVision}, - version = {0.1.0} +@software{climatevision2026, + author = {ClimateVision Contributors}, + title = {ClimateVision: Open-Source AI Platform for Environmental Monitoring}, + year = {2026}, + url = {https://github.com/Climate-Vision/ClimateVision}, + version = {0.2.0} } ``` --- -## ⭐ Support the Project - -If you find ClimateVision useful for your research, conservation work, or just believe in our mission, please consider: - -- **Starring** ⭐ the repository to help others discover it -- **Forking** 🍴 to build your own applications -- **Contributing** 🤝 code, documentation, or ideas -- **Sharing** 📢 with your network and communities -- **Partnering** 🌍 if you're an NGO or research institution - -Every star helps us reach more people who can benefit from free, open-source forest monitoring! - -**Track our growth:** [Star History](https://star-history.com/#yourusername/ClimateVision&Date) - ---- -

- Together, we can protect the world's forests through open-source AI. -
-
⭐ Star us on GitHub - · - 🤝 Contribute - · - 🐛 Report Bug - · - 📖 Documentation +  ·  + Contribute +  ·  + Report a Bug

- ---- - -**Made with 🌍 for a sustainable future** diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3d2feca --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,43 @@ +# Security Policy + +## Supported Versions + +ClimateVision is under active development. Security fixes are applied to the latest release on the `main` branch. + +| Version | Supported | +| ------- | ------------------ | +| 0.2.x | :white_check_mark: | +| < 0.2 | :x: | + +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.** + +Instead, please report them privately using GitHub's built-in Security Advisory system: + +- Go to the [Security tab](https://github.com/Climate-Vision/ClimateVision/security) of this repository. +- Click **"Report a vulnerability"**. +- Fill out the form with a description of the issue, steps to reproduce, and (if known) a suggested fix. + +You should receive an initial response within **5 business days**. If the issue is confirmed, we will work on a fix and coordinate disclosure with you. + +## Scope + +**In scope:** + +- Vulnerabilities in the ClimateVision API (`src/climatevision/api/`) +- Vulnerabilities in the React dashboard (`frontend/`) +- Vulnerabilities in the data pipeline, model inference, or authentication flow +- Dependency vulnerabilities not already tracked by Dependabot + +**Out of scope:** + +- Issues in third-party services (Google Earth Engine, MLflow, etc.) — please report those upstream +- Self-inflicted issues from running with debug or development configuration in production +- Missing security best-practices without a demonstrated exploit + +## Disclosure Policy + +We follow a coordinated disclosure model. After a fix is released, we will publish a GitHub Security Advisory crediting the reporter (unless anonymity is requested). + +Thank you for helping keep ClimateVision and its users safe. diff --git a/SETUP_COMPLETE.md b/SETUP_COMPLETE.md deleted file mode 100644 index e4fb39f..0000000 --- a/SETUP_COMPLETE.md +++ /dev/null @@ -1,463 +0,0 @@ -# ClimateVision Project - Setup Complete! 🎉 - -## ✅ What's Been Created - -Your ClimateVision project is now ready to start development! Here's everything that's been set up: - -### 📦 Core Package Structure - -``` -ClimateVision/ -├── src/climatevision/ ✅ Main package -│ ├── __init__.py ✅ Package initialization -│ ├── config.py ✅ Configuration management -│ ├── models/ ✅ ML models (COMPLETE) -│ │ ├── unet.py ✅ U-Net & Attention U-Net -│ │ └── siamese.py ✅ Siamese Network for change detection -│ ├── utils/ ✅ Utilities (COMPLETE) -│ │ ├── metrics.py ✅ Evaluation metrics & loss functions -│ │ ├── visualization.py ✅ Plotting & visualization -│ │ └── geospatial.py ✅ Geospatial utilities -│ ├── data/ 📝 TODO (Engineer 2) -│ ├── inference/ 📝 TODO (Engineer 4) -│ └── api/ 📝 TODO (Engineer 4) -``` - -### 📚 Documentation Files - -``` -✅ README.md - Comprehensive project overview -✅ CONTRIBUTING.md - Contribution guidelines -✅ PROJECT_STRUCTURE.md - Codebase organization guide -✅ GETTING_STARTED.md - Developer onboarding guide -✅ LICENSE - MIT License -``` - -### 🔧 Configuration Files - -``` -✅ setup.py - Package installation -✅ requirements.txt - Python dependencies -✅ .gitignore - Git ignore rules -``` - -### 📓 Notebooks - -``` -✅ notebooks/01_quickstart.ipynb - Getting started tutorial -``` - ---- - -## 🚀 What Works Right Now - -### 1. Models Module ✅ -- **U-Net**: Semantic segmentation for forest/non-forest classification -- **Attention U-Net**: Improved segmentation with attention mechanism -- **Siamese Network**: Change detection between two time periods -- **Early Fusion Network**: Alternative change detection approach - -**Test it**: -```python -from climatevision.models import UNet, SiameseNetwork -import torch - -# U-Net for segmentation -model = UNet(n_channels=13, n_classes=2) -x = torch.randn(1, 13, 256, 256) -output = model(x) # Shape: (1, 2, 256, 256) - -# Siamese for change detection -siamese = SiameseNetwork(in_channels=13) -before = torch.randn(1, 13, 256, 256) -after = torch.randn(1, 13, 256, 256) -change_map = siamese.predict_binary(before, after) -``` - -### 2. Utilities Module ✅ - -**Metrics**: -- IoU, Dice coefficient, pixel accuracy -- Segmentation metrics (F1, precision, recall) -- Change detection metrics (confusion matrix, kappa) -- Custom loss functions (Dice Loss, Focal Loss) - -**Visualization**: -- Satellite image display (RGB, false color) -- Prediction overlays -- Change detection maps -- NDVI calculation and visualization -- Training history plots - -**Geospatial**: -- Coordinate transformations -- Area calculations (hectares, carbon loss) -- Bounding box operations -- GeoTIFF metadata generation -- Tile generation for large images - -**Test it**: -```python -from climatevision.utils import ( - calculate_iou, - visualize_prediction, - calculate_carbon_loss -) -import numpy as np - -# Calculate metrics -pred = np.array([[0, 1], [1, 1]]) -target = np.array([[0, 1], [1, 0]]) -iou = calculate_iou(pred, target, num_classes=2) - -# Estimate carbon loss -deforestation_ha = 100 -carbon_loss_tons = calculate_carbon_loss( - deforestation_area_ha=deforestation_ha, - biomass_density_t_per_ha=150 -) -``` - -### 3. Configuration System ✅ -- Project paths management -- Model hyperparameters -- Sentinel-2 band configurations -- Automatic directory creation - ---- - -## 📝 What Needs to Be Built (Next 3 Months) - -### Month 1: Foundation (Weeks 1-4) - -#### Week 1-2: Data Pipeline (Engineer 2) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Implement Sentinel-2 data loader (`data/sentinel2.py`) -- [ ] Create Landsat data loader (`data/landsat.py`) -- [ ] Build PyTorch Dataset class (`data/dataset.py`) -- [ ] Add preprocessing pipeline (`data/preprocess.py`) -- [ ] Implement data augmentation (`data/augmentation.py`) - -**Success Criteria**: Load and preprocess one Sentinel-2 tile - -#### Week 1-2: Training Infrastructure (Engineer 1) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Create training loop (`training/trainer.py`) -- [ ] Add model checkpointing (`training/checkpointing.py`) -- [ ] Implement evaluation framework (`training/evaluator.py`) -- [ ] Add training callbacks (`training/callbacks.py`) - -**Success Criteria**: Train U-Net on synthetic data with logging - -#### Week 3-4: Initial Model Training (Engineer 1 & 2) -**Priority**: MEDIUM -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Find and curate public forest datasets -- [ ] Train baseline U-Net model -- [ ] Evaluate on test set -- [ ] Document results in notebook - -**Success Criteria**: >85% accuracy on public dataset - -#### Week 3-4: Carbon Estimation (Engineer 3) -**Priority**: MEDIUM -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Implement Random Forest regressor (`models/carbon_estimator.py`) -- [ ] Add XGBoost model -- [ ] Create validation framework -- [ ] Implement uncertainty quantification - -**Success Criteria**: RMSE < 20 tons/ha on validation set - -### Month 2: Advanced Features (Weeks 5-8) - -#### Week 5-6: Change Detection (Engineer 1) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Train Siamese network -- [ ] Optimize change detection performance -- [ ] Add temporal smoothing -- [ ] Create change detection notebook - -**Success Criteria**: F1 > 0.90 on test set - -#### Week 5-6: Batch Processing (Engineer 4) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Create inference pipeline (`inference/predictor.py`) -- [ ] Implement batch processor (`inference/batch_processor.py`) -- [ ] Add ONNX optimization (`inference/onnx_optimizer.py`) -- [ ] Write post-processing utilities - -**Success Criteria**: Process 100 images in <5 minutes - -#### Week 7-8: API Development (Engineer 4) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Set up FastAPI application (`api/main.py`) -- [ ] Add prediction endpoints (`api/routes.py`) -- [ ] Implement authentication -- [ ] Add rate limiting -- [ ] Write API documentation - -**Success Criteria**: API responds in <100ms per request - -#### Week 7-8: Model Optimization (Engineer 1 & 3) -**Priority**: MEDIUM -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Hyperparameter tuning with Optuna -- [ ] Model quantization for speed -- [ ] Ensemble methods -- [ ] Uncertainty quantification - -**Success Criteria**: 2x faster inference, same accuracy - -### Month 3: Deployment & Scale (Weeks 9-12) - -#### Week 9-10: Dashboard (Team Effort) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Set up React project (`frontend/`) -- [ ] Create map component (Leaflet) -- [ ] Add prediction visualization -- [ ] Implement time series charts -- [ ] Connect to API - -**Success Criteria**: Functional web dashboard - -#### Week 11-12: Deployment (Engineer 4 + Lead) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Docker containerization -- [ ] Write deployment docs -- [ ] Set up CI/CD pipeline -- [ ] Deploy to cloud (AWS/GCP) -- [ ] Performance testing - -**Success Criteria**: Production-ready deployment - -#### Week 11-12: Documentation & Launch (Team) -**Priority**: HIGH -**Status**: 🔴 Not Started - -**Tasks**: -- [ ] Complete API documentation -- [ ] Write user guides -- [ ] Create demo videos -- [ ] Prepare launch materials -- [ ] Community outreach - -**Success Criteria**: 50+ GitHub stars in first week - ---- - -## 🎯 Immediate Next Steps (This Week) - -### For the Team Lead (You) - -1. **Create GitHub Repository** - ```bash - cd ClimateVision - git init - git add . - git commit -m "Initial commit: project structure and core models" - git remote add origin https://github.com/yourusername/ClimateVision.git - git push -u origin main - ``` - -2. **Set Up Project Board** - - Create GitHub Project board - - Add all tasks from GETTING_STARTED.md - - Assign to team members - -3. **Schedule Kickoff Meeting** - - Review project goals - - Assign Week 1 tasks - - Set up communication channels - -4. **Environment Setup** - ```bash - # Create requirements-dev.txt - pip freeze > requirements-dev.txt - ``` - -### For Each Team Member - -1. **Clone and Set Up** - ```bash - git clone https://github.com/yourusername/ClimateVision.git - cd ClimateVision - python -m venv venv - source venv/bin/activate - pip install -r requirements.txt - pip install -e . - ``` - -2. **Read Documentation** - - [ ] README.md - - [ ] GETTING_STARTED.md - - [ ] PROJECT_STRUCTURE.md - -3. **Verify Installation** - ```bash - python -c "from climatevision.models import UNet; print('✓ Setup complete!')" - jupyter notebook notebooks/01_quickstart.ipynb - ``` - -4. **Start First Task** (See GETTING_STARTED.md for your role) - ---- - -## 📊 Success Metrics - -### Technical Metrics -- [ ] Forest segmentation accuracy > 95% -- [ ] Change detection F1 score > 0.90 -- [ ] API latency < 100ms -- [ ] Code coverage > 80% -- [ ] Zero critical bugs - -### Community Metrics -- [ ] 50+ stars in Month 1 -- [ ] 150+ stars in Month 2 -- [ ] 300+ stars in Month 3 -- [ ] 10+ external contributors -- [ ] 5+ active forks - -### Impact Metrics -- [ ] 100,000+ hectares monitored -- [ ] 50+ deforestation alerts generated -- [ ] 3+ partner NGOs -- [ ] 2+ research projects using ClimateVision - ---- - -## 🛠️ Development Tools Recommended - -### IDEs -- **VSCode**: Python, Jupyter extensions -- **PyCharm**: Professional Python IDE -- **Jupyter Lab**: Interactive development - -### Version Control -- **Git**: Version control -- **GitHub Desktop**: GUI for Git (optional) -- **GitKraken**: Advanced Git GUI (optional) - -### Testing & Quality -- **pytest**: Unit testing -- **black**: Code formatting -- **flake8**: Linting -- **mypy**: Type checking - -### MLOps -- **MLflow**: Experiment tracking -- **DVC**: Data version control -- **Weights & Biases**: Alternative to MLflow - -### Deployment -- **Docker**: Containerization -- **Kubernetes**: Orchestration -- **GitHub Actions**: CI/CD - ---- - -## 📞 Communication Channels - -### Recommended Setup -1. **GitHub Issues**: Bug reports, feature requests -2. **GitHub Discussions**: General questions, ideas -3. **Slack/Discord**: Daily communication -4. **Weekly Meetings**: Sprint planning, reviews - -### Response Times -- **Critical bugs**: < 4 hours -- **PRs for review**: < 24 hours -- **Questions**: < 1 day -- **Feature requests**: < 1 week - ---- - -## 🎓 Learning Path - -### Week 1: Foundation -- [ ] PyTorch basics -- [ ] Rasterio for geospatial data -- [ ] Git workflow - -### Week 2-4: Specialization -- [ ] Your role-specific technologies -- [ ] MLOps best practices -- [ ] Testing strategies - -### Month 2: Advanced -- [ ] Model optimization -- [ ] API design patterns -- [ ] Deployment strategies - ---- - -## 🏆 Milestones - -### ✅ Milestone 0: Project Setup (COMPLETE) -- Project structure created -- Core models implemented -- Documentation written -- Ready for development - -### 📅 Milestone 1: Week 4 (Foundation) -- Data pipeline working -- Training infrastructure ready -- Models training on real data - -### 📅 Milestone 2: Week 8 (Features) -- Change detection working -- API endpoints functional -- Model optimization complete - -### 📅 Milestone 3: Week 12 (Launch) -- Dashboard deployed -- Documentation complete -- Community launch successful -- 300+ GitHub stars - ---- - -## 🚀 You're All Set! - -Everything is ready for your team to start building ClimateVision. The foundation is solid: -- ✅ Professional project structure -- ✅ Working ML models -- ✅ Comprehensive utilities -- ✅ Clear documentation -- ✅ Development guidelines - -**Now it's time to build!** 🌍 - ---- - -**Questions?** Check the documentation or open a GitHub Discussion. - -**Let's protect the world's forests through open-source AI!** 🌳 diff --git a/config.yaml b/config.yaml index 33ff733..2ce5c8a 100644 --- a/config.yaml +++ b/config.yaml @@ -1,6 +1,121 @@ # ClimateVision Configuration +# Multi-Climate Analysis Platform -# Model Configuration +# ===== Analysis Types Configuration ===== +# Each analysis type can be enabled/disabled and configured independently +analysis_types: + # Deforestation Detection + deforestation: + enabled: true + display_name: "Deforestation Detection" + description: "Monitor forest coverage and detect deforestation events" + model: + architecture: "unet" + weights: "models/unet_deforestation.pth" + in_channels: 4 + num_classes: 2 + bands: ["B04", "B03", "B02", "B08"] # Red, Green, Blue, NIR + classes: ["non_forest", "forest"] + thresholds: + alert_forest_loss: 5.0 # Alert if >5% forest loss + critical_forest_loss: 15.0 # Critical if >15% loss + min_forest_coverage: 20.0 # Alert if coverage drops below 20% + metrics: + - "forest_percentage" + - "forest_pixels" + - "ndvi_stats" + - "carbon_estimation" + + # Arctic Ice Melting + ice_melting: + enabled: true + display_name: "Arctic Ice Melting" + description: "Monitor sea ice extent and melting patterns in polar regions" + model: + architecture: "unet" + weights: "models/unet_ice.pth" + in_channels: 4 + num_classes: 3 + bands: ["B02", "B03", "B04", "B11"] # Blue, Green, Red, SWIR + classes: ["open_water", "sea_ice", "land"] + thresholds: + alert_ice_loss: 10.0 # Alert if >10% ice loss + critical_ice_loss: 25.0 # Critical if >25% loss + min_ice_concentration: 15.0 # Alert if concentration below 15% + rapid_melt_rate: 5.0 # km²/day threshold + metrics: + - "ice_percentage" + - "ice_extent_km2" + - "melt_rate" + - "ndsi_stats" + # Specific regions for Arctic monitoring + default_regions: + arctic_ocean: [-180, 66.5, 180, 90] + greenland: [-73, 60, -12, 84] + antarctica: [-180, -90, 180, -60] + + # Flood Detection + flooding: + enabled: true + display_name: "Flood Detection" + description: "Detect and monitor flooding events and affected areas" + model: + architecture: "unet" + weights: "models/unet_flood.pth" + in_channels: 3 + num_classes: 3 + bands: ["B03", "B08", "B11"] # Green, NIR, SWIR + classes: ["dry_land", "permanent_water", "flooded"] + thresholds: + alert_flood_area: 5.0 # Alert if >5% area flooded + critical_flood_area: 20.0 # Critical if >20% flooded + rapid_expansion_rate: 10.0 # % increase per day + metrics: + - "flooded_percentage" + - "flooded_area_km2" + - "mndwi_stats" + + # Drought Monitoring + drought: + enabled: false # Not yet implemented + display_name: "Drought Monitoring" + description: "Monitor vegetation stress and drought conditions" + model: + architecture: "unet" + weights: "models/unet_drought.pth" + in_channels: 4 + num_classes: 4 + bands: ["B04", "B08", "B11", "B12"] # Red, NIR, SWIR-1, SWIR-2 + classes: ["normal", "mild_stress", "moderate_stress", "severe_drought"] + thresholds: + alert_drought_index: 0.3 + critical_drought_index: 0.6 + metrics: + - "drought_severity_index" + - "vegetation_health_index" + - "soil_moisture_proxy" + + # Wildfire Detection + wildfire: + enabled: false # Not yet implemented + display_name: "Wildfire Detection" + description: "Detect active fires and burned areas" + model: + architecture: "unet" + weights: "models/unet_wildfire.pth" + in_channels: 4 + num_classes: 3 + bands: ["B04", "B08", "B11", "B12"] # Red, NIR, SWIR-1, SWIR-2 + classes: ["unburned", "burned", "active_fire"] + thresholds: + fire_radiative_power: 10.0 # MW + burned_area_alert: 1.0 # km² + metrics: + - "burned_area_km2" + - "fire_intensity" + - "nbr_stats" # Normalized Burn Ratio + +# ===== Default Model Configuration ===== model: architecture: "unet" in_channels: 4 # RGB + NIR @@ -8,7 +123,7 @@ model: use_uncertainty: false dropout_rate: 0.5 -# Training Configuration +# ===== Training Configuration ===== training: batch_size: 8 num_epochs: 50 @@ -19,7 +134,7 @@ training: checkpoint_interval: 5 early_stopping_patience: 10 -# Data Configuration +# ===== Data Configuration ===== data: image_size: [256, 256] bands: ["Red", "Green", "Blue", "NIR"] @@ -29,18 +144,27 @@ data: val_split: 0.1 test_split: 0.1 -# Satellite Data Sources +# ===== Satellite Data Sources ===== satellite: sentinel2: bands: ["B04", "B03", "B02", "B08"] # Red, Green, Blue, NIR + all_bands: ["B01", "B02", "B03", "B04", "B05", "B06", "B07", "B08", "B8A", "B09", "B10", "B11", "B12"] resolution: 10 # meters cloud_coverage_max: 20 # percentage + revisit_time: 5 # days landsat8: bands: ["B4", "B3", "B2", "B5"] resolution: 30 # meters + revisit_time: 16 # days + + modis: + bands: ["1", "2", "3", "4", "5", "6", "7"] + resolution: 250 # meters (bands 1-2), 500m (3-7) + revisit_time: 1 # days + use_for: ["ice_melting", "wildfire"] # Best for large-scale monitoring -# Inference Configuration +# ===== Inference Configuration ===== inference: batch_size: 4 threshold: 0.5 @@ -49,23 +173,34 @@ inference: device: "cuda" # cuda or cpu num_workers: 4 -# MLOps Configuration +# ===== MLOps Configuration ===== mlops: experiment_tracking: "mlflow" # mlflow, wandb, or none model_registry: "mlflow" logging_interval: 10 # log every N batches -# Paths +# ===== Paths ===== paths: data_dir: "data/" models_dir: "models/" logs_dir: "logs/" outputs_dir: "outputs/" -# API Configuration +# ===== API Configuration ===== api: host: "0.0.0.0" port: 8000 workers: 4 timeout: 60 max_file_size: 100 # MB + cors_origins: + - "http://localhost:5173" + - "http://localhost:3000" + +# ===== Organization (NGO) Configuration ===== +organizations: + enable_registration: true + require_email_verification: false + default_alert_channels: ["email"] + max_subscriptions_per_org: 10 + api_rate_limit: 100 # requests per minute \ No newline at end of file diff --git a/config/train.yaml b/config/train.yaml new file mode 100644 index 0000000..34bb9e8 --- /dev/null +++ b/config/train.yaml @@ -0,0 +1,62 @@ +# ============================================================ +# ClimateVision — Forest Segmentation Training Config +# ============================================================ +# Usage: +# python scripts/train.py --config config/train.yaml +# +# All paths are relative to the project root unless absolute. +# ============================================================ + +# --- Data -------------------------------------------------- +data: + dir: data/processed # root with train/ val/ test/ splits + image_size: 256 # spatial crop size (pixels) + batch_size: 16 + num_workers: 4 + use_weighted_sampler: true # oversample forest-rich patches + pin_memory: true + +# --- Model ------------------------------------------------- +model: + architecture: attention_unet # "unet" | "attention_unet" + in_channels: 4 # R, G, B, NIR + num_classes: 2 # 0=non-forest, 1=forest + bilinear: true # bilinear up-sampling (UNet only) + +# --- Loss -------------------------------------------------- +loss: + type: combined # "combined" | "focal" | "dice" | "lovasz" + focal_weight: 0.5 # weight of focal vs dice in combined loss + focal_alpha: 0.25 + focal_gamma: 2.0 + use_class_weights: true # re-weight by inverse class frequency + +# --- Optimiser -------------------------------------------- +optimizer: + learning_rate: 1.0e-4 + weight_decay: 1.0e-4 + min_lr: 1.0e-6 + +# --- Schedule --------------------------------------------- +schedule: + epochs: 100 + warmup_epochs: 5 + checkpoint_interval: 10 # save periodic snapshot every N epochs + +# --- Regularisation / Tricks ------------------------------ +training: + mixed_precision: true # AMP (CUDA only; ignored on CPU/MPS) + grad_clip: 1.0 + use_ema: true + ema_decay: 0.99 + early_stopping_patience: 15 + +# --- Outputs ---------------------------------------------- +output: + save_dir: models + run_name: "" # auto-set to timestamp if empty + +# --- Normalisation stats ---------------------------------- +# Leave empty to use built-in Sentinel-2 L2A defaults. +# Set to a JSON file path produced by Sentinel2Normalizer.save(). +normalizer_stats: "" diff --git a/docs/ADEOLU MARY OSHADARE.docx b/docs/ADEOLU MARY OSHADARE.docx deleted file mode 100644 index fa950cf..0000000 Binary files a/docs/ADEOLU MARY OSHADARE.docx and /dev/null differ diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md new file mode 100644 index 0000000..c337dd2 --- /dev/null +++ b/docs/API_REFERENCE.md @@ -0,0 +1,489 @@ +# ClimateVision API Reference + +This document provides a complete reference for the ClimateVision REST API. + +## Base URL + +``` +http://localhost:8000/api +``` + +## Authentication + +For organization-specific endpoints, use API key authentication: + +```bash +curl -H "X-API-Key: your_api_key" http://localhost:8000/api/organizations/1/alerts +``` + +--- + +## Core Endpoints + +### Health Check + +Check API status and available analysis types. + +```http +GET /api/health +``` + +**Response:** +```json +{ + "status": "ok", + "version": "0.2.0", + "analysis_types": ["deforestation", "ice_melting", "flooding"] +} +``` + +--- + +## Analysis Types + +### List Analysis Types + +Get all available analysis types. + +```http +GET /api/analysis-types?enabled_only=true +``` + +**Response:** +```json +[ + { + "name": "deforestation", + "display_name": "Deforestation Detection", + "description": "Monitor forest coverage and detect deforestation events", + "enabled": true, + "bands": ["B04", "B03", "B02", "B08"], + "classes": ["non_forest", "forest"] + }, + { + "name": "ice_melting", + "display_name": "Arctic Ice Melting", + "description": "Monitor sea ice extent and melting patterns", + "enabled": true, + "bands": ["B02", "B03", "B04", "B11"], + "classes": ["open_water", "sea_ice", "land"] + } +] +``` + +### Get Analysis Type Details + +```http +GET /api/analysis-types/{type_name} +``` + +**Example:** `GET /api/analysis-types/deforestation` + +--- + +## Prediction Endpoints + +### Run Prediction (JSON) + +Run analysis using bounding box and date range. + +```http +POST /api/predict +Content-Type: application/json + +{ + "kind": "bbox", + "analysis_type": "deforestation", + "bbox": [-62.0, -3.1, -61.8, -2.9], + "start_date": "2024-01-01", + "end_date": "2024-12-31" +} +``` + +**Response:** +```json +{ + "run_id": 1, + "result": { + "analysis_type": "deforestation", + "region": { + "bbox": [-62.0, -3.1, -61.8, -2.9], + "date_range": "2024-01-01 to 2024-12-31" + }, + "ndvi_stats": { + "NDVI_min": 0.123, + "NDVI_mean": 0.567, + "NDVI_max": 0.892 + }, + "inference": { + "image_size": [256, 256], + "forest_pixels": 45678, + "non_forest_pixels": 19858, + "forest_percentage": 69.72, + "mean_confidence": 0.87 + } + } +} +``` + +### Run Prediction (File Upload) + +Upload satellite imagery for analysis. + +```http +POST /api/predict/upload +Content-Type: multipart/form-data + +kind=upload +analysis_type=ice_melting +bbox=[-73, 60, -12, 84] +start_date=2024-06-01 +end_date=2024-08-31 +file=@satellite_image.tif +``` + +**Response:** +```json +{ + "run_id": 2, + "result": { + "analysis_type": "ice_melting", + "region": { + "bbox": [-73, 60, -12, 84] + }, + "inference": { + "image_size": [512, 512], + "ice_pixels": 150000, + "water_pixels": 80000, + "land_pixels": 32144, + "ice_percentage": 65.2, + "ice_extent_km2": 45000.5, + "mean_confidence": 0.82 + } + } +} +``` + +--- + +## Run History + +### List Runs + +Get analysis run history with optional filters. + +```http +GET /api/runs?limit=50&status=completed&analysis_type=deforestation +``` + +**Query Parameters:** +| Parameter | Type | Description | +|-----------|------|-------------| +| `limit` | int | Max results (default: 50, max: 200) | +| `status` | string | Filter by status: pending, running, completed, failed | +| `analysis_type` | string | Filter by analysis type | + +**Response:** +```json +[ + { + "id": 1, + "kind": "bbox", + "status": "completed", + "analysis_type": "deforestation", + "bbox": "[-62.0, -3.1, -61.8, -2.9]", + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "created_at": "2024-12-15T10:30:00Z", + "updated_at": "2024-12-15T10:30:45Z" + } +] +``` + +### Get Run Details + +```http +GET /api/runs/{run_id} +``` + +**Response:** +```json +{ + "run": { + "id": 1, + "kind": "bbox", + "status": "completed", + "analysis_type": "deforestation", + "created_at": "2024-12-15T10:30:00Z" + }, + "result": { + "id": 1, + "run_id": 1, + "payload": { ... }, + "mask_path": null, + "created_at": "2024-12-15T10:30:45Z" + } +} +``` + +--- + +## Organization (NGO) Endpoints + +### Create Organization + +Register a new organization to receive alerts. + +```http +POST /api/organizations +Content-Type: application/json + +{ + "name": "Rainforest Alliance", + "type": "ngo", + "description": "Protecting rainforests worldwide", + "contact_email": "alerts@rainforest.org", + "website_url": "https://rainforest.org" +} +``` + +**Response:** +```json +{ + "id": 1, + "name": "Rainforest Alliance", + "type": "ngo", + "api_key": "cv_abc123...", + "active": true, + "created_at": "2024-12-15T10:00:00Z" +} +``` + +> **Important:** Save the `api_key` securely. It cannot be retrieved later. + +### List Organizations + +```http +GET /api/organizations?type=ngo&limit=50 +``` + +### Get Organization + +```http +GET /api/organizations/{org_id} +``` + +--- + +## Subscriptions + +Subscriptions allow organizations to monitor specific regions. + +### Create Subscription + +```http +POST /api/organizations/{org_id}/subscriptions +Content-Type: application/json + +{ + "name": "Amazon Watch Zone 1", + "bbox": [-62.0, -3.1, -61.8, -2.9], + "analysis_types": ["deforestation", "wildfire"], + "alert_threshold": 5.0, + "notification_channel": "webhook", + "webhook_url": "https://example.org/webhooks/climate" +} +``` + +**Response:** +```json +{ + "id": 1, + "organization_id": 1, + "name": "Amazon Watch Zone 1", + "bbox": [-62.0, -3.1, -61.8, -2.9], + "analysis_types": ["deforestation", "wildfire"], + "alert_threshold": 5.0, + "notification_channel": "webhook", + "active": true, + "created_at": "2024-12-15T11:00:00Z" +} +``` + +### List Subscriptions + +```http +GET /api/organizations/{org_id}/subscriptions +``` + +--- + +## Alerts + +### List Alerts + +```http +GET /api/organizations/{org_id}/alerts?unacknowledged_only=true&limit=50 +``` + +**Query Parameters:** +| Parameter | Type | Description | +|-----------|------|-------------| +| `undelivered_only` | bool | Only undelivered alerts | +| `unacknowledged_only` | bool | Only unacknowledged alerts | +| `limit` | int | Max results | + +**Response:** +```json +[ + { + "id": 1, + "organization_id": 1, + "alert_type": "deforestation_detected", + "severity": "high", + "title": "Deforestation Detected", + "message": "Forest loss detected: 7.5% reduction in coverage", + "delivered": true, + "acknowledged": false, + "created_at": "2024-12-15T12:00:00Z" + } +] +``` + +### Create Alert + +```http +POST /api/organizations/{org_id}/alerts +Content-Type: application/json + +{ + "alert_type": "deforestation_detected", + "severity": "high", + "title": "Deforestation Alert", + "message": "Significant forest loss detected in monitored region", + "subscription_id": 1, + "run_id": 5 +} +``` + +### Acknowledge Alert + +```http +POST /api/alerts/{alert_id}/acknowledge +Content-Type: application/json + +{ + "acknowledged_by": "analyst@rainforest.org" +} +``` + +### Mark Alert Delivered + +```http +POST /api/alerts/{alert_id}/deliver +``` + +--- + +## Error Responses + +All errors return a JSON response: + +```json +{ + "detail": "Error message here" +} +``` + +**Common HTTP Status Codes:** +| Code | Description | +|------|-------------| +| 400 | Bad Request - Invalid parameters | +| 404 | Not Found - Resource doesn't exist | +| 422 | Validation Error - Invalid request body | +| 500 | Internal Server Error | + +--- + +## Python SDK Example + +```python +import requests + +API_BASE = "http://localhost:8000/api" + +# Run deforestation analysis +response = requests.post( + f"{API_BASE}/predict", + json={ + "kind": "bbox", + "analysis_type": "deforestation", + "bbox": [-62.0, -3.1, -61.8, -2.9], + "start_date": "2024-01-01", + "end_date": "2024-12-31" + } +) +result = response.json() +print(f"Forest coverage: {result['result']['inference']['forest_percentage']}%") + +# Create an organization +org_response = requests.post( + f"{API_BASE}/organizations", + json={ + "name": "My NGO", + "type": "ngo", + "contact_email": "contact@myngo.org" + } +) +org = org_response.json() +api_key = org["api_key"] # Save this! + +# Create a subscription +sub_response = requests.post( + f"{API_BASE}/organizations/{org['id']}/subscriptions", + json={ + "name": "Amazon Region", + "bbox": [-70, -10, -50, 5], + "analysis_types": ["deforestation"], + "alert_threshold": 5.0 + } +) +``` + +--- + +## JavaScript/TypeScript Example + +```typescript +const API_BASE = 'http://localhost:8000/api'; + +// Run ice melting analysis +async function analyzeIce() { + const response = await fetch(`${API_BASE}/predict`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + kind: 'bbox', + analysis_type: 'ice_melting', + bbox: [-73, 60, -12, 84], + start_date: '2024-06-01', + end_date: '2024-08-31' + }) + }); + + const { run_id, result } = await response.json(); + console.log(`Ice extent: ${result.inference.ice_percentage}%`); + return result; +} + +// List organization alerts +async function getAlerts(orgId: number, apiKey: string) { + const response = await fetch( + `${API_BASE}/organizations/${orgId}/alerts?unacknowledged_only=true`, + { + headers: { 'X-API-Key': apiKey } + } + ); + return response.json(); +} +``` diff --git a/docs/Francis Umo.docx b/docs/Francis Umo.docx deleted file mode 100644 index d72efdc..0000000 Binary files a/docs/Francis Umo.docx and /dev/null differ diff --git a/docs/OLUFEMI TAIWO.docx b/docs/OLUFEMI TAIWO.docx deleted file mode 100644 index 54a5c2d..0000000 Binary files a/docs/OLUFEMI TAIWO.docx and /dev/null differ diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000..ffbb571 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,4 @@ +# API base URL for frontend requests +# Leave empty when using Vite dev server (proxy handles /api -> backend) +# Set to http://127.0.0.1:8000 when serving built app separately +VITE_API_BASE_URL= diff --git a/frontend/index.html b/frontend/index.html index aeb5f03..e8352d0 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,6 +4,9 @@ ClimateVision + + +
diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 786a3ae..81af47e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,8 +8,13 @@ "name": "climatevision-frontend", "version": "0.1.0", "dependencies": { + "@react-google-maps/api": "^2.20.8", + "framer-motion": "^12.35.0", + "lucide-react": "^0.577.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^7.13.1", + "recharts": "^3.7.0" }, "devDependencies": { "@types/react": "^18.2.55", @@ -708,6 +713,22 @@ "node": ">=12" } }, + "node_modules/@googlemaps/js-api-loader": { + "version": "1.16.8", + "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.8.tgz", + "integrity": "sha512-CROqqwfKotdO6EBjZO/gQGVTbeDps5V7Mt9+8+5Q+jTg5CRMi3Ii/L9PmV3USROrt2uWxtGzJHORmByxyo9pSQ==", + "license": "Apache-2.0" + }, + "node_modules/@googlemaps/markerclusterer": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz", + "integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==", + "license": "Apache-2.0", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "supercluster": "^8.0.1" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -796,6 +817,72 @@ "node": ">= 8" } }, + "node_modules/@react-google-maps/api": { + "version": "2.20.8", + "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.20.8.tgz", + "integrity": "sha512-wtLYFtCGXK3qbIz1H5to3JxbosPnKsvjDKhqGylXUb859EskhzR7OpuNt0LqdLarXUtZCJTKzPn3BNaekNIahg==", + "license": "MIT", + "dependencies": { + "@googlemaps/js-api-loader": "1.16.8", + "@googlemaps/markerclusterer": "2.5.3", + "@react-google-maps/infobox": "2.20.0", + "@react-google-maps/marker-clusterer": "2.20.0", + "@types/google.maps": "3.58.1", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19", + "react-dom": "^16.8 || ^17 || ^18 || ^19" + } + }, + "node_modules/@react-google-maps/infobox": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.20.0.tgz", + "integrity": "sha512-03PJHjohhaVLkX6+NHhlr8CIlvUxWaXhryqDjyaZ8iIqqix/nV8GFdz9O3m5OsjtxtNho09F/15j14yV0nuyLQ==", + "license": "MIT" + }, + "node_modules/@react-google-maps/marker-clusterer": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.20.0.tgz", + "integrity": "sha512-tieX9Va5w1yP88vMgfH1pHTacDQ9TgDTjox3tLlisKDXRQWdjw+QeVVghhf5XqqIxXHgPdcGwBvKY6UP+SIvLw==", + "license": "MIT" + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz", + "integrity": "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.4.tgz", + "integrity": "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -1153,6 +1240,18 @@ "win32" ] }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1198,6 +1297,69 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1205,18 +1367,24 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/google.maps": { + "version": "3.58.1", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.58.1.tgz", + "integrity": "sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==", + "license": "MIT" + }, "node_modules/@types/prop-types": { "version": "15.7.15", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.27", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -1233,6 +1401,12 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@vitejs/plugin-react": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", @@ -1458,6 +1632,15 @@ "node": ">= 6" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -1475,6 +1658,19 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1492,9 +1688,130 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1513,6 +1830,12 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -1534,6 +1857,16 @@ "dev": true, "license": "ISC" }, + "node_modules/es-toolkit": { + "version": "1.45.1", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.45.1.tgz", + "integrity": "sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -1583,6 +1916,18 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -1650,6 +1995,33 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "12.35.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.35.0.tgz", + "integrity": "sha512-w8hghCMQ4oq10j6aZh3U2yeEQv5K69O/seDI/41PK4HtgkLrcBovUNc0ayBC3UyyU7V1mrY2yLzvYdWJX9pGZQ==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.35.0", + "motion-utils": "^12.29.2", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1711,6 +2083,34 @@ "node": ">= 0.4" } }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1815,6 +2215,12 @@ "node": ">=6" } }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "license": "ISC" + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -1857,6 +2263,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.577.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", + "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -1881,6 +2296,21 @@ "node": ">=8.6" } }, + "node_modules/motion-dom": { + "version": "12.35.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.35.0.tgz", + "integrity": "sha512-FFMLEnIejK/zDABn+vqGVAUN4T0+3fw+cVAY8MMT65yR+j5uMuvWdd4npACWhh94OVWQs79CrBBuwOwGRZAQiA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.29.2" + } + }, + "node_modules/motion-utils": { + "version": "12.29.2", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.29.2.tgz", + "integrity": "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2212,6 +2642,36 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz", + "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==", + "license": "MIT", + "peer": true + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -2222,6 +2682,44 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", + "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.1.tgz", + "integrity": "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==", + "license": "MIT", + "dependencies": { + "react-router": "7.13.1" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -2245,6 +2743,57 @@ "node": ">=8.10.0" } }, + "node_modules/recharts": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.7.0.tgz", + "integrity": "sha512-l2VCsy3XXeraxIID9fx23eCb6iCBsxUQDnE8tWm6DFdszVAO7WVY/ChAD9wVit01y6B2PMupYiMmQwhgPHc9Ew==", + "license": "MIT", + "workspaces": [ + "www" + ], + "dependencies": { + "@reduxjs/toolkit": "1.x.x || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^10.1.1", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.1.1", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.11", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", @@ -2365,6 +2914,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2398,6 +2953,15 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -2472,6 +3036,12 @@ "node": ">=0.8" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -2540,6 +3110,12 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -2585,6 +3161,15 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2592,6 +3177,28 @@ "dev": true, "license": "MIT" }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/vite": { "version": "5.4.21", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", diff --git a/frontend/package.json b/frontend/package.json index cc67945..a976d4d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,8 +9,13 @@ "preview": "vite preview" }, "dependencies": { + "@react-google-maps/api": "^2.20.8", + "framer-motion": "^12.35.0", + "lucide-react": "^0.577.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^7.13.1", + "recharts": "^3.7.0" }, "devDependencies": { "@types/react": "^18.2.55", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b4f5a41..93dff27 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,408 +1,4 @@ -import { useEffect, useMemo, useState } from 'react' -import { getRun, health, listRuns, predictJson, predictUpload } from './api' - -type Tab = 'bbox' | 'upload' | 'runs' - -type Toast = { type: 'success' | 'error'; message: string } - -function cx(...parts: Array) { - return parts.filter(Boolean).join(' ') -} - -function Card(props: { title: string; children: React.ReactNode; right?: React.ReactNode }) { - return ( -
-
-

{props.title}

- {props.right} -
-
{props.children}
-
- ) -} - -function Field(props: { - label: string - hint?: string - children: React.ReactNode -}) { - return ( - - ) -} - -function Button(props: { - children: React.ReactNode - onClick?: () => void - type?: 'button' | 'submit' - disabled?: boolean - variant?: 'primary' | 'ghost' -}) { - const variant = props.variant ?? 'primary' - return ( - - ) -} - -function Input(props: React.InputHTMLAttributes) { - return ( - - ) -} - -function Textarea(props: React.TextareaHTMLAttributes) { - return ( -