Spaces:
Paused
Paused
File size: 24,740 Bytes
b6163f9 e7263d1 b6163f9 62711a0 efeddde 62711a0 efeddde 62711a0 efeddde 62711a0 efeddde 62711a0 efeddde 62711a0 efeddde e1cd694 efeddde 35788b8 efeddde 62711a0 efeddde 62711a0 efeddde 62711a0 efeddde f31264b efeddde 62711a0 efeddde f31264b efeddde 62711a0 efeddde 62711a0 efeddde | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | ---
title: FaceID
emoji: π‘οΈ
colorFrom: green
colorTo: blue
sdk: docker
app_port: 8000
pinned: false
---
# π‘οΈ FaceID
> **End-to-End Biometric Provenance, OSINT Social Attribution & Dual-Layer Blockchain Forensic Pipeline**
[](https://www.python.org/)
[](https://github.com/deepinsight/insightface)
[](https://huggingface.co/prithivMLmods/Deep-Fake-Detector-v2-Model)
[](https://serpapi.com/)
[](https://sepolia.etherscan.io/)
[](LICENSE)
---
## π Executive Summary
**`FaceID`** is an end-to-end investigative pipeline engineered to address **digital identity verification**, **OSINT visual attribution**, and **tamper-evident evidence preservation**.
In an era of ubiquitous synthetic media and digital impersonation, establishing the genuine provenance and first-seen context of a face image requires more than simple reverse-search rankings. `FaceID` bridges biometric computer vision, live web-scale OSINT, deepfake classification, and immutable distributed ledgers into an automated forensic workflow.
Given an arbitrary portrait or facial scan, the system:
1. **Detects the face** and computes an invariant **512-dimensional facial embedding** using **InsightFace (ArcFace)**.
2. **Performs a live, non-hardcoded reverse-image search** across the web via **Google Lens (SerpAPI)**.
3. **Downloads discovered candidate images** and independently re-verifies them using **cosine similarity** on facial embeddings to eliminate false positives.
4. **Identifies and isolates specific social media post URLs** (e.g., Instagram Reels, X/Twitter statuses, YouTube videos) rather than generic portal links.
5. **Evaluates the candidate against an experimental deepfake detection classifier (ViT)** to detect synthetic manipulation.
6. **Packages forensic metadata into a deterministic SHA-256 evidence fingerprint**.
7. **Permanently logs the evidence into a dual-layer blockchain architecture**:
- **Layer 1 (Local):** An instant, zero-cost, hash-linked cryptographic ledger (`chain/blockchain.json`).
- **Layer 2 (Public Testnet):** Immutable anchoring to the **Ethereum Sepolia Testnet** with public Etherscan verifiability via transaction calldata.
---
## ποΈ System Architecture & Data Flow
```mermaid
flowchart TD
A["[ Input Face Image ]"] --> B["[ 1. InsightFace / ArcFace ]\n512-D Biometric Embedding"]
B --> C["[ 2. Live SerpAPI Google Lens Search ]\nWeb & Social Visual Candidates"]
C --> D["[ 3. Candidate Image Downloader ]\nFetch High-Resolution Media"]
D --> E["[ 4. ArcFace Biometric Extraction ]\nCandidate Embedding Vectors"]
E --> F["[ 5. Cosine Similarity Ranking ]\nRigorous Identity Confirmation"]
F --> G["[ 6. Social Media Post URL Isolator ]\nExtract /reel/, /status/, /watch"]
G --> H["[ 7. ViT Deepfake Classifier ]\nSynthetic Media Risk Score"]
H --> I["[ 8. SHA-256 Evidence Fingerprint ]\nDeterministic JSON Metadata Hash"]
I --> J1["[ Layer 1: Local Blockchain ]\nchain/blockchain.json\nLinked-Block Cryptographic Ledger"]
I --> J2["[ Layer 2: Public Blockchain ]\nEthereum Sepolia Testnet\n0-Value TX + Calldata Payload"]
J1 --> K["[ Automated Verification Script ]\ncheck.py / CLI Verifier\nMatches On-Chain Calldata == Local Fingerprint"]
J2 --> K
```
### ASCII High-Fidelity Flow Diagram
```text
ββββββββββββββββββββββββββ
β Input Face Image β
βββββββββββββ¬βββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β InsightFace / ArcFace Detector β ββ> 512-D Face Embedding Vector
ββββββββββββββββββ¬ββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β Live SerpAPI Google Lens Search β ββ> Real-world Visual Matches (Web & Social)
ββββββββββββββββββ¬ββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β Image Downloader & Embedding β ββ> Extracts embeddings of candidates
ββββββββββββββββββ¬ββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β Cosine Similarity Ranking β ββ> Independent identity confirmation
ββββββββββββββββββ¬ββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β Social Media Post Extractor β ββ> Isolates specific URLs (/reel/, /status/)
ββββββββββββββββββ¬ββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β ViT Deepfake Risk Analysis β ββ> Probabilistic synthetic media signal
ββββββββββββββββββ¬ββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β SHA-256 Evidence Fingerprint β ββ> Deterministic record hashing
ββββββββββββββββββ¬ββββββββββββββββββ
β
ββββββββ΄βββββββββββββββββββββββ
βΌ βΌ
βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β Layer 1: Local Chain β β Layer 2: Public Chain β
β `chain/blockchain.json`β β Ethereum Sepolia Testnet β
β (Linked-block integrity)β β (0-value TX + Calldata payload) β
ββββββββββββββ¬βββββββββββββ βββββββββββββββββββ¬βββββββββββββββββ
β β
βββββββββββββββββββ¬βββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Automated Verification Script β
β Etherscan & local hash match: MATCH ββ
ββββββββββββββββββββββββββββββββββββββββ
```
---
## βοΈ Which Blockchain We Used (And Why)
To satisfy forensic standards with production-grade rigor, `FaceID` implements a **hybrid dual-layer blockchain strategy**:
### 1. Public Blockchain: Ethereum Sepolia Testnet (EVM)
- **Network:** Ethereum Sepolia Testnet
- **Chain ID:** `11155111`
- **Explorer:** [https://sepolia.etherscan.io](https://sepolia.etherscan.io/)
- **Transaction Model:** EIP-1559 (`maxFeePerGas` / `maxPriorityFeePerGas`)
#### How Evidence Is Stored:
The SHA-256 evidence fingerprint is embedded directly into the **input data (`calldata`)** field of an on-chain self-transaction (0-value ETH transfer).
> [!NOTE]
> **Why Calldata Over Smart Contracts?**
> Because the Ethereum Virtual Machine (EVM) immutably logs transaction calldata and block timestamps directly into mined blocks, calldata creates a globally verifiable, decentralized **Proof of Existence (PoE)** that:
> 1. Requires **zero complex contract deployments** or ongoing maintenance.
> 2. Minimizes gas consumption to the bare minimum 21,000 base gas + calldata byte costs.
> 3. Cannot be altered, censored, or paused by contract ownership privileges or admin keys.
### 2. Local Blockchain: Cryptographically Linked Hash Ledger
- **Implementation:** `blockchain/blockchain.py` (persisted to `chain/blockchain.json`)
- **Structure:** Cryptographic linked list where each block contains:
```json
{
"index": 1,
"timestamp": 1726058400.123,
"evidence_record": { "...": "..." },
"previous_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"hash": "cbfd4687a965dfabbb143fa3b481c7862303abdb5dfc336bbc3966a47a8a4b41"
}
```
### Why Both?
| Dimension | Layer 1: Local Ledger (`blockchain.json`) | Layer 2: Public Sepolia Testnet |
|:---|:---|:---|
| **Latency** | Instant (< 5 ms) | 12β15 seconds (block confirmation) |
| **Gas / Cost** | Zero cost | Free testnet ETH (faucet) |
| **Connectivity** | 100% Offline capable | Requires internet & RPC node |
| **Consensus** | Single-node audit trail | Global decentralized PoS consensus |
| **Tamper Resistance** | Hash-linked block verification | Globally immutable, proof-of-work/stake |
| **Target Audience** | Rapid internal forensic triage | External audits, legal admissible proof |
---
## β¨ Key Features & Technical Highlights
- **100% Genuine, Non-Hardcoded Search:** No pre-baked results. The pipeline uploads the source image directly to SerpAPI (Google Lens visual engine) and streams real-time web results.
- **Independent Biometric Re-Verification:** Rather than blindly trusting search engine relevance rankings, the pipeline downloads each candidate image, extracts candidate face embeddings using ArcFace, and computes exact **cosine similarity** against the query face.
- **Specific Social-Media Post Filtering:** Differentiates between dead/generic portal links (e.g., `instagram.com/explore`) and high-value, actionable evidence posts (e.g., `instagram.com/reel/<id>`, `twitter.com/<user>/status/<id>`, `youtube.com/watch?v=<id>`).
- **Synthetic Media & Deepfake Signal:** Evaluates candidate media through a Vision Transformer (ViT) deepfake classification model (`prithivMLmods/Deep-Fake-Detector-v2-Model`) to alert investigators to manipulated or synthetic faces.
- **Automated Cryptographic Verification:** Includes `check.py` and `blockchain.testnet_anchor` CLI tools that query transaction calldata from Sepolia via Web3 RPC, decode the UTF-8 payload, and verify byte-for-byte equality against the local run.
- **Dual Execution Modes:** Functions seamlessly as a standalone **CLI tool** for batch forensic runs or as an interactive **REST API & Web UI**.
---
## π Quickstart & How to Run
### 1. Prerequisites
- **Python 3.10+** (tested on 3.10, 3.11, 3.12, 3.13)
- Internet connection for initial model downloads (`buffalo_l` and ViT weights)
Clone the repository:
```bash
git clone https://github.com/Rishikvelagapudi/FaceID.git
cd FaceID
```
Create and activate a virtual environment:
```powershell
# Windows PowerShell:
python -m venv venv
.\venv\Scripts\Activate.ps1
# Linux / macOS:
python3 -m venv venv
source venv/bin/activate
```
Install dependencies:
```bash
pip install -r requirements.txt
```
> [!NOTE]
> The deepfake classifier uses `torch` and `transformers`. The first execution downloads pre-trained weights (`prithivMLmods/Deep-Fake-Detector-v2-Model`).
---
### 2. Environment Configuration
Copy the example environment file:
```bash
cp .env.example .env
```
Edit `.env` and fill in your credentials:
```ini
# Required for live Google Lens reverse search
SERPAPI_KEY=your_serpapi_key_here
# Optional: For Public Ethereum Sepolia testnet anchoring
PRIVATE_KEY=0x_your_testnet_private_key_here
RPC_URL=https://ethereum-sepolia-rpc.publicnode.com
# Optional logging & thresholds
LOG_LEVEL=INFO
SIMILARITY_THRESHOLD=0.40
```
- **Free SerpAPI Key:** [serpapi.com](https://serpapi.com/)
- **Free Sepolia ETH Faucets:** [sepoliafaucet.com](https://sepoliafaucet.com/) or [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia)
> [!TIP]
> If Ethereum variables are omitted, the pipeline still fully executes, logging evidence to the local blockchain ledger without network errors.
---
### 3. Running the End-to-End Pipeline
Run the pipeline on any face image:
```bash
python app.py --image path/to/your/image.jpg
```
#### Common Flags:
- `--threshold 0.35`: Minimum cosine similarity score required for face match (default: `0.40`).
- `--top-k 5`: Number of reverse-search candidate images to retrieve and inspect (default: `10`).
- `--no-blockchain`: Run computer vision and reverse search without submitting an on-chain transaction.
- `--log-level DEBUG`: Enable verbose forensic output.
#### Sample CLI Output:
```text
[1/9] Extracting face embedding from source imageβ¦
Face detected (det_score=0.821, norm=20.65)
[2/9] Searching web via SerpAPI Google Lensβ¦
1 visual matches returned.
[3/9] Downloading candidate imagesβ¦
1 candidates downloaded.
[4/9] Extracting face embeddings from candidatesβ¦
1/1 candidates had detectable faces.
[5/9] Ranking candidates by cosine similarityβ¦
Overall best | similarity=1.0000 | match=True | url=https://www.instagram.com/reel/DXGaS1lDMC1/
[5b] Identifying specific social-media post candidatesβ¦
Best specific social post | platform=Instagram | similarity=1.0000 | url=https://www.instagram.com/reel/DXGaS1lDMC1/
[5c] Annotating trust signals (video detection & content corroboration)β¦
[5d] Analyzing deepfake risk on primary candidate imageβ¦
[6/9] Building evidence recordβ¦
[7/9] Hashing evidence record (SHA-256)β¦
Evidence hash: cbfd4687a965dfabbb143fa3b481c786β¦
[8/9] Writing evidence to blockchainβ¦
Block #2 written | chain_length=3
[9/9] Verifying blockchain integrityβ¦
Blockchain: VALID | Evidence hash found in block 2. Chain integrity valid.
[10/10] Anchoring evidence hash to Ethereum Sepolia testnetβ¦
Sepolia TX : 866a0e6987418ccb7cd9fb013694487e4dc3e7cd8dac70c68b91116bbdff42ac
Etherscan : https://sepolia.etherscan.io/tx/866a0e6987418ccb7cd9fb013694487e4dc3e7cd8dac70c68b91116bbdff42ac
```
---
## π Independent Verification on Blockchain
To verify that the evidence hash stored on Sepolia matches the generated local output:
### Automated Verifier Script:
```bash
python check.py
```
### Manual CLI Verifier:
```bash
python -m blockchain.testnet_anchor verify 0x866a0e6987418ccb7cd9fb013694487e4dc3e7cd8dac70c68b91116bbdff42ac cbfd4687a965dfabbb143fa3b481c7862303abdb5dfc336bbc3966a47a8a4b41
```
#### Verification Output:
```text
TX Hash : 0x866a0e6987418ccb7cd9fb013694487e4dc3e7cd8dac70c68b91116bbdff42ac
On-chain hash : cbfd4687a965dfabbb143fa3b481c7862303abdb5dfc336bbc3966a47a8a4b41
Expected hash : cbfd4687a965dfabbb143fa3b481c7862303abdb5dfc336bbc3966a47a8a4b41
Etherscan : https://sepolia.etherscan.io/tx/0x866a0e6987418ccb7cd9fb013694487e4dc3e7cd8dac70c68b91116bbdff42ac
Result : MATCH β
```
---
## π Running the REST API & Web Mode
You can run `FaceID` as a high-performance REST microservice and interactive web application:
```bash
python app.py --serve --port 8000
```
Then navigate to `http://localhost:8000` to access the **FaceID Web Interface**.
### REST Endpoints
| Method | Endpoint | Description |
|:---|:---|:---|
| `GET` | `/health` | Healthcheck and service readiness probe |
| `POST` | `/analyse` | Upload image file (`multipart/form-data`), with optional `threshold` & `top_k` |
| `GET` | `/chain` | Fetch local blockchain ledger and cryptographic validation status |
| `GET` | `/verify/<hash>` | Verify if an evidence hash exists in a validated local block |
#### cURL Example:
```bash
curl -X POST -F "file=@data/input/sample.jpg" http://localhost:8000/analyse
```
---
## π Live Verification Proof (Real Demonstration)
An actual forensic execution produced the following tamper-evident artifact recorded in `results/result.json`:
| Metric / Field | Verified Value |
|:---|:---|
| **Source Image Hash (SHA-256)** | `954419c50ed11c9db3bd5453548eb1a2c39a967bfdc78dfc9e4f45a034d0ea3d` |
| **Discovered Social Post** | [Reddit Post `katamari_time`](https://www.reddit.com/r/katamari/comments/1me54er/katamari_time/) |
| **Face Match / Visual Similarity** | `0.4856` (OSINT visual candidate match) |
| **Evidence Record Hash** | `83ffb62af2a30b5fd64e05faa2d8238fac69114337f3ba310f5d22144f44db39` |
| **Ethereum Sepolia TX Hash** | [`0x71369e339dcbd5658339989a3187568c272aae1b747ffe2ba9eb15db778372cd`](https://sepolia.etherscan.io/tx/0x71369e339dcbd5658339989a3187568c272aae1b747ffe2ba9eb15db778372cd) |
> [!IMPORTANT]
> **Independent Public Verification:** Anyone can open the Etherscan link above, click **"Click to show more"**, view the **Input Data**, select **"UTF-8"**, and directly read the exact Evidence Hash anchored permanently into the Ethereum blockchain.
---
## β οΈ Known Limitations & Edge Cases
In compliance with forensic and security rigor, here are documented boundaries and considerations:
1. **Search Provider Indexation Dependency:** Reverse image lookups depend on external search engine indexing (Google Lens via SerpAPI). Newly published posts (< 1-2 hours) or private profiles (e.g., private Instagram, Facebook, locked X profiles) cannot be scraped or indexed.
2. **Single-Frame Deepfake Detection:** The deepfake classifier is based on a single-frame Vision Transformer (ViT). While highly effective at spotting spatial synthetic artifacts, blending borders, and face swaps, it does not inspect temporal facial inconsistencies across extended video files (e.g., subtle audio-lip desynchronization).
3. **Public RPC Latency & Gas Pricing:** Sepolia testnet confirmation depends on public RPC node availability and testnet block production times (~12β15 seconds per block).
4. **Local Ledger Concurrency:** The local JSON ledger provides immediate, lightweight verification for single-investigator workstations. For multi-node enterprise environments, a distributed database or decentralized smart contract event indexing can be integrated.
---
## π Repository Structure
The repository is modularly architected to decouple computer vision, OSINT retrieval, deepfake heuristics, and distributed ledger anchoring:
```text
FaceID/
βββ app.py # Primary entrypoint: CLI runner, coordinator & REST API server
βββ main.py # Standalone CLI execution wrapper
βββ check.py # Independent blockchain verification script (Sepolia RPC -> Local)
βββ requirements.txt # Production Python dependencies
βββ .env.example # Template for environment credentials & RPC endpoints
βββ .gitignore # Git ignore rules (protects .env, keys, cache, and raw data)
βββ LICENSE # MIT Open Source License
β
βββ app/ # Core Application Engine
β βββ __init__.py
β βββ pipeline.py # Primary orchestrator: biometrics -> search -> ranking -> anchoring
β βββ server.py # FastAPI / REST API service definitions and routes
β β
β βββ face/ # Biometric Feature Extraction Layer
β β βββ __init__.py
β β βββ encoder.py # InsightFace ArcFace wrapper (detection, alignment, 512-D embedding)
β β
β βββ image/ # Image Processing & Classical Vision
β β βββ __init__.py
β β βββ downloader.py # Async/safe candidate image fetcher with timeout controls
β β βββ hashing.py # SHA-256 and Perceptual Hashing (pHash, aHash, dHash)
β β βββ similarity.py # Cosine similarity and hamming distance verification
β β
β βββ reverse_search/ # OSINT Visual Search Providers
β β βββ __init__.py
β β βββ base.py # Abstract Base Class for search providers
β β βββ serpapi_provider.py # Google Lens engine integration via SerpAPI
β β βββ bing_provider.py # Fallback Bing Visual Search provider
β β βββ tineye_provider.py # TinEye Reverse Search provider
β β βββ free_scraper_provider.py # Headless / direct visual scraper fallback
β β βββ social_filter.py # Social URL isolation (/reel/, /status/) & trust annotator
β β βββ factory.py # Provider factory with fallback chaining
β β
β βββ deepfake/ # Synthetic Media Analysis Layer
β β βββ __init__.py
β β βββ classifier.py # Vision Transformer (ViT) deepfake & synthetic media model
β β
β βββ blockchain/ # Distributed Ledger & Anchoring Module
β β βββ __init__.py
β β βββ blockchain.py # Layer 1: Local hash-linked cryptographic ledger implementation
β β βββ testnet_anchor.py # Layer 2: Sepolia EVM calldata transaction broadcaster & verifier
β β βββ registry.py # Smart contract interaction & registry manager
β β βββ abi.json # Smart contract ABI (for optional registry contracts)
β β
β βββ static/ # Forensic Web Terminal Assets
β βββ index.html # FaceID biometric terminal web dashboard
β βββ styles.css # Terminal UI stylesheet
β βββ app.js # Client-side UI controller & async verification handling
β
βββ chain/ # Layer 1 Blockchain Storage
β βββ blockchain.json # Cryptographic local block records and hash chain
β
βββ contracts/ # Smart Contracts
β βββ ProvenanceRegistry.sol # Solidity smart contract for on-chain identity anchor registry
β
βββ data/ # Local Working Directories
β βββ input/ # Input test portraits and probe images
β βββ candidates/ # Cached candidate images downloaded during OSINT search
β
βββ results/ # Forensic Evidence Reports
β βββ result.json # Canonical demonstration evidence artifact
β βββ *_report.json # Detailed timestamped forensic JSON audit trails
β
βββ scripts/ # Maintenance & Utility Scripts
β βββ deploy.py # Deploy ProvenanceRegistry contract to Sepolia
β βββ verify_contract.py # Etherscan contract verification script
β βββ create_sample.py # Generate deterministic synthetic test faces
β
βββ tests/ # Automated Test Suite
βββ test_blockchain.py # Unit tests for block integrity & cryptographic chaining
βββ test_hashing.py # Unit tests for cryptographic & perceptual hashing
βββ test_similarity.py # Unit tests for 512-D cosine similarity matching
```
---
## π Security & Privacy Model
- **Zero Biometric Persistence:** Raw facial biometric embeddings (512-D floating-point vectors) are calculated in volatile memory (RAM) for real-time cosine comparison and are **never written to the blockchain or serialized to public JSON files**.
- **Cryptographic Evidence Fingerprinting:** Only non-reversible cryptographic hashes (SHA-256) of verified forensic metadata records are permanently recorded on the blockchain.
- **Private Key Isolation:** All blockchain transaction signing occurs locally using raw private keys or Web3 keystores; keys are never transmitted over network boundaries.
---
## π License
This project is licensed under the **MIT License** β see the [LICENSE](LICENSE) file for details.
|